单片机串口通信C程序及应用实例
一、程序代码
#include
#define uchar unsigned char
uchar indata[4];
uchar outdata[4];
uchar flag;
static uchar temp1,temp2,temp3,temp;
static uchar R_counter,T_counter;
void system_initial(void);
void initial_comm(void);
void delay(uchar x);
void uart_send(void);
void read_Instatus(void);
serial_contral(void);
void main()
{
system_initial();
initial_comm();
while(1)
{
if(flag==1)
{
ES = 0;
serial_contral();
ES = 1;
flag = 0;
}
else
read_Instatus();
}
}
void uart_send(void)
{
for(T_counter=0;T_counter<4;T_counter++)
{
SBUF = outdata[T_counter];
while(TI == 0);
TI = 0;
}
T_counter = 0;
}
uart_receive(void) interrupt 4
{
if(RI)
{
RI = 0;
indata[R_counter] = SBUF;
R_counter++;
if(R_counter>=4)
{
R_counter = 0;
flag = 1;
}
}
}
void system_initial(void)
{
P1M1 = 0x00;
P1M0 = 0xff;
P1 = 0xff; //初始化为全部关闭
temp3 = 0x3f;//初始化temp3的值与六路输出的初始值保持一致
temp = 0xf0;
R_counter = 0;
T_counter = 0;
}
void initial_comm(void)
{
SCON = 0x50; //设定串行口工作方式:mode 1 ; 8-bit UART,enable ucvr TMOD = 0x21; //TIMER 1;mode 2 ;8-Bit Reload
PCON = 0x80; //波特率不加倍SMOD = 1
TH1 = 0xfa; //baud: 9600;fosc = 11.0596
IE = 0x90; // enable serial interrupt
TR1 = 1; // timer 1
RI = 0;
TI = 0;
ES = 1;
EA = 1;
}
void delay(uchar x)
{
uchar i,j;
for(i=0;i for(j=0;j<110;j++); } serial_contral(void) { if(indata[3] == ((indata[0]^indata[1])^indata[2])) { if(indata[1]== 0x01) { P0 = 0xff; temp2 = P0; //读取四路输入 // temp2 = temp2&0x0f; outdata[0] = 0xee; outdata[1] = 0x02; outdata[2] = temp2; outdata[3] = ((outdata[0]^outdata[1])^outdata[2]); uart_send(); return; } if(indata[1]== 0x03) { temp3 = indata[2]; P1 = temp3; //控制六路输出 return; } if(indata[1]==0x04) { outdata[0] = 0xee; outdata[1] = 0x05; outdata[2] = temp3; outdata[3] = ((outdata[0]^outdata[1])^outdata[2]); uart_send(); return; } } } void read_Instatus(void) { P0 = 0xff; temp1 = P0; //读取四路输入 if(temp1!=temp) { delay(10); P0 = 0xff; temp1 = P0; if(temp1!=temp) { temp = temp1; //P0 = 0xff; //temp = P0; //temp = temp&0x0f; outdata[0] = 0xee; outdata[1] = 0x06; outdata[2] = temp; outdata[3] = ((outdata[0]^outdata[1])^outdata[2]); uart_send(); } } } //总结:原因在于串口中断接收一定要使用全局变量,并且这个变量R_counter和T_counter 要在主程序中初始化。这样,当串口有数据进来时,系统进入中断接收程序,就不会出现数组混乱送出的问题。 二、原理图 三、四路开关量输入/六路开关量输出通讯协议 通信设置:波特率9600b/s 8位数据位无校验位1位停止位 命令格式: 区别码(1字节)+ Command(1字节)+ Content(1字节)+ Xor(1字节) 区别码:上位发送/单片机接收:0xff 单片机发送/上位机接收:0xee Command = 0x01上位机命令单片机读取四路输入开关量的输入状态 如:0xff + 0x01 + 0x00 + Xor Command = 0x02单片机返回四路输入状态给上位机 此时,Content 的1字节中的低四位分别表示四路开关量的输入状态 1表示输入高电平,0表示输入低电平 第一路输入(第0位) 第二位输入(第1位) 第三路输入(第2位) 第四路输入(第3位) 如:假设某一时刻四路输入开关量的输入状态为0x03,上位机读取其状态为:0xee + 0x02 + 0x03 + Xor Command = 0x03上位机命令单片机控制六路输出的输出状态 此时,Content 的1字节中的低六位分别表示六路开关量的输出状态 1表示输出高电平,0表示输出低电平 第一路输出(第0位) 第二路输出(第1位) 第三路输出(第2位) 第四路输出(第3位) 第五路输出(第4位) 第六路输出(第5位) 如:上位机欲设置某一时刻六路输出开关量的输出状态为0x01: 0xff + 0x03 + 0x01 + Xor Command = 0x04上位机命令单片机读取六路输出开关量的输出状态 如:0xff + 0x04 + 0x00 + Xor Command = 0x05 单片机返回六路输出状态给上位机 此时,Content 的1字节中的低六位分别表示六路开关量的输出状态 1表示输出高电平,0表示输出低电平 第一路输出(第0位) 第二路输出(第1位) 第三路输出(第2位) 第四路输出(第3位) 第五路输出(第4位) 第六路输出(第5位) 如:某一时刻六路输出开关量的输出状态为0x01,上位机读取其状态为:0xee + 0x05 + 0x01 + Xor Command = 0x06四路输入状态发生变化时单片机读取其变化的状态并返回给上位机此时,Content 的1字节中的低四位分别表示四路开关量的输入状态 1表示输入高电平,0表示输入低电平 第一路输入(第0位) 第二位输入(第1位) 第三路输入(第2位) 第四路输入(第3位) 如:假设某一时刻四路输入开关量的输入状态为0x03,上位机读取其状态为:0xee + 0x06 + 0x03 + Xor Content:表示四路输入开关量的输入状态(数据)或者六路输出开关量的输出状态(数据),在不使用它的命令格式中,它的值无意义,为通信方便,在不使用它的命令格式中,规定其值为0x00; Xor :从第一个字节开始到Xor的前一个字节(总共3个字节),做异或运算 四、串口助手测试: 读取四路输入开关量 ff 01 00 fe 控制六路输出的输出状态 ff 03 XX Xor 00 fc 全开 01 fd 关闭右边第一个 02 fe 关闭右边第二个 04 f8 关闭右边第三个 08 f4 关闭右边第四个 10 ec 关闭右边第五个 20 dc 关闭右边第六个 3f c3 全关 3e c2 开右边第一个 3c c1 开右边第二个 3b c7 开右边第三个 37 cb 开右边第四个 2f d3 开右边第五个 1f e3 开右边第六个 读取六路输出开关量的输出状态 ff 04 00 fb 简介: 本文论述了一个简单的单片机串口通信作品,通过上位机和单片机通信,控制几路开关量的输入和输出。只限于学习和参考之用,各部分均通过测试成功!是笔者工作和学习之总结,望大家多学习交流! 2010-12-22 晚于上海 难为 //以下程序都是在VC++6.0 上调试运行过的程序,没有错误,没有警告。 //单片机是STC89C52RC,但是在所有的51 52单片机上都是通用的。51只是一个学习的基础平台,你懂得。 //程序在关键的位置添加了注释。 /****************************************************************************** * * 实验名: 串口实验 * 使用的IO : P2 * 实验效果: 将接收到发送回电脑上面。 * 注意: ******************************************************************************* / #include 上位机与51单片机串口通信 目录: 1、单片机串口通信的应用 2、PC控制单片机IO口输出 3、单片机控制实训指导及综合应用实例 4、单片机给计算机发送数据: [实验任务] 单片机串口通信的应用,通过串口,我们的个人电脑和单片机系统进行通信。 个人电脑作为上位机,向下位机单片机系统发送十六进制或者ASCLL码,单片机系统接收后,用LED显示接收到的数据和向上位机发回原样数据。 [硬件电路图] [实验原理] RS-232是美国电子工业协会正式公布的串行总线标准,也是目前最常用的串 行接口标准,用来实现计算机与计算机之间、计算机与外设之间的数据通讯。 RS-232串行接口总线适用于:设备之间的通讯距离不大于15m,传输速率最大为20kBps。RS-232协议以-5V-15V表示逻辑1;以+5V-15V 表示逻辑0。我们是用MAX232芯片将RS232电平转换为TTL电平的。一个完整的RS-232接口有22 根线,采用标准的25芯插头座。我们在这里使用的是简化的9芯插头座。 注意我们在这里使用的晶振是11.0592M的,而不是12M。因为波特率的设置 需要11.0592M的。 “串口调试助手V2.1.exe”软件的使用很简单,只要将串口选择‘CMO1’波 特率设置为‘9600’数据位为8 位。打开串口(如果关闭)。然后在发送区里 输入要发送的数据,单击手动发送就将数据发送出去了。注意,如果选中‘十六 进制发送’那么发送的数据是十六进制的,必须输入两位数据。如果没有选中, 则发送的是ASCLL码,那么单片机控制的数码管将显示ASCLL码值。 //参考源程序 #include "reg52.h" //包函8051 内部资源的定义 unsigned char dat; //用于存储单片机接收发送缓冲寄存器SBUF里面的内容sbit gewei=P2^4; //个位选通定义 《专业综合实习报告》 专业:电子信息工程 年级:2013级 指导教师: 学生: 目录 一:实验项目名称 二:前言 三:项目内容及要求 四:串口通信原理 五:设计思路 5.1虚拟串口的设置 5.2下位机电路和程序设计 5.3串口通信仿真 六:电路原理框图 七:相关硬件及配套软件 7.1 AT89C51器件简介 7.2 COMPIN简介 7.3 MAX232器件简介 7.4友善串口调试助手 7.5 虚拟串口软件Virtual Serial Port Driver 6.9八:程序设计 九:proteus仿真调试 十:总结 十一:参考文献 一:实验项目名称: 基于51单片机的单片机与PC机通信 二:前言 在国内外,以PC机作为上位机,单片机作为下位机的控制系统中,PC机通常以软件界面进行人机交互,以串行通信方式与单片机进行积极交互,而单片机系统根据被控对象配置相应的前向,后向信息通道,工作时作为主控机测对象,作为被控机接受PC机监督,指挥,定期或受命向上位机提供对象及本身的工作状态信息。 目前,随着集成电路集成度的增加,电子计算机向微型化和超微型化方向发展,微型计算机已成为导弹,智能机器人,人类宇宙和太空和太空奥妙复杂系统不可缺少的智能部件。在一些工业控制中,经常需要以多台单片机作为下位机执行对被控对象的直接控制,以一台PC机为上位机完成复杂的数据处理,组成一种以集中管理、分散控制为特点的集散控制系统。 为了提高系统管理的先进性和安全性,计算机工业自动控制和监测系统越来越多地采用集总分算系统。较为常见的形式是由一台做管理用的上位主计算机(主机)和一台直接参与控制检测的下位机(单片机)构成的主从式系统,主机和从机之间以通讯的方式来协调工作。主机的作用一是要向从机发送各种命令及参数:二是要及时收集、整理和分析从机发回的数据,供进一步的决策和报表。从机被动地接受、执行主机发来的命令,并且根据主机的要求向主机回传相应烦人实时数据,报告其运行状态。 用串行总线技术可以使系统的硬件设计大大简化、系统的体积减小、可靠性提高。同时,系统的更改和扩充极为容易。MCS-51系列单片机,由于内部带有一个可用于异步通讯的全双工的穿行通讯接口,阴齿可以很方便的构成一个主从式系统。 串口是计算机上一种非常通用的设备通讯协议,大多数计算机包容两个基于RS232的串口。串口同时也是仪器仪表设备通过用的通讯协议,很多GPIB兼容的设备也带有RS-232口。同时串口通讯协议也可以用于获取远程采集设备数据。所以,深入的理解学习和研究串口通信相关知识是非常必要的。此次毕业设计选题为“PC机与MCS-51单片机的串口通讯”,使用51单片机来实现一个主从式 8.用C语言或汇编语言实现串口通信(PC和单片机间) 上位机和下位机的主从工作方式为工业控制及自动控制系统所采用。由于PC 机分析能力强、处理速度更快及单片机使用灵活方便等特点,所以一般都将PC 机作为上位机,单片机作为下位机,二者通过RS-232或者RS-485接收、发送数据和传送指令。单片机可单独处理数据和控制任务,同时也将数据传送给PC机,由PC机对这些数据进行处理或显示 1 硬件电路的设计 MCS-51单片机有一个全双工的串行通讯口UART,利用其RXD和TXD与外界进行通信,其内部有2个物理上完全独立的接收、发送缓冲器SBUF,可同时发送和接收数据。所以单片机和PC机之间可以方便地进行串口通讯。单片机串口有3条引线:TXD(发送数据),RXD(接收数据)和GND(信号地)。因此在通信距离较短时可采用零MODEM方式,简单三连线结构。IBM-PC机有两个标准的RS-232串行口,其电平采用的是EIA电平,而MCS-51单片机的串行通信是由TXD(发送数据)和RXD(接收数据)来进行全双工通信的,它们的电平是TTL电平;为了PC机与MCS-51 机之间能可靠地进行串行通信,需要用电平转换芯片,可以采用MAXIM公司生产的专用芯片MAX232进行转换。电路如图1所示。硬件连接时,可从MAX232中的2路发送器和接收器中任选一路,只要注意发送与接收的引脚对应关系即可。接口电路如图3.5所示。 总体设计按照整体设计思路方案绘制原理图如下所示: 2 系统软件设计 软件设计分上位机软件设计和下位机软件设计。这两部分虽然在不同的机器上编写和运行,但它们要做的工作是对应的:一个发送,另一个接收。为了保证数据通信的可靠性,要制定通信协议,然后各自根据协议分别编制程序。现约定通信协议如下:PC机和单片机都可以发送和接收。上位机和下位机均采用查询方式发送控字符和数据、中断方式接收控制字符和数据。采用RS-232串口异步通信, 1上位PC机与下位单片机异步串行通信的通信协议 C51单片机和电脑串口通信电路图与源码 51单片机有一个全双工的串行通讯口,所以单片机和电脑之间可以方便地进行串口通讯。进行串行通讯时要满足一定的条件,比如电脑的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,我们采用了专用芯片MAX232进行转换,虽然也可以用几个三极管进行模拟转换,但是还是用专用芯片更简单可靠。我们采用了三线制连接串口,也就是说和电脑的9针串口只连接其中的3根线:第5脚的GND、第2脚的RXD、第3脚的TXD。这是最简单的连接方法,但是对我们来说已经足够使用了,电路如下图所示,MAX232的第10脚和单片机的11脚连接,第9脚和单片机的10脚连接,第15脚和单片机的20脚连接。 串口通讯的硬件电路如上图所示 在制作电路前我们先来看看要用的MAX232,这里我们不去具体讨论它,只要知道它是TTL和RS232电平相互转换的芯片和基本的引脚接线功能就行了。通常我会用两个小功率晶体管加少量的电路去替换MAX232,可以省一点,效果也不错,下图就是MAX232的基本接线图。 按图7-3加上MAX232就可以了。这大热天的拿烙铁焊焊,还真的是热气迫人来呀:P串口座用DB9的母头,这样就可以用买来的PC串口延长线进行和电脑相连接,也可以直接接到电脑com口上。 为了能够在电脑端看到单片机发出的数据,我们必须借助一个WINDOWS软件进行观察,这里我们利用一个免费的电脑串口调试软件。本串口软件在本网站https://www.360docs.net/doc/0f17412239.html,可以找到 软件界面如上图,我们先要设置一下串口通讯的参数,将波特率调整为4800,勾选十六进制显示。串口选择为COM1,当然将网站提供的51单片机实验板的串口也要和电脑的COM1连接,将烧写有以下程序的单片机插入单片机实验板的万能插座中,并接通51单片机实验板的电源。 51单片机串口通信异常的调试一例 单片机与DSP在硬件结构和程序编写方面存在很多共同之处,所以最近几周试着用了一下51单片机开发板,希望进一步熟悉中断的概念、串口通信、I2C协议、存储扩展等常用的知识。 在进行串口通信的实验时,预期功能不能实现。实验的设计方案是:通过上位机给单片机发送一个16bit的字符串,单片机对字符串进行接收并立刻回显给上位机,接收并回显完毕后依次将这些字符(只能是0-9,a-f这几个字符,可以重复)在数码管上进行显示。 程序编写完成后,通过上位机发送字符串9876543210abcdef,单片机串口接收并回显9876543210abcde,然后数码管依次显示f9876543210abcde,数码管显示完成后,单片机串口回显的字符串中的e后面又多了一个f。 对实验现象进行分析不难发现,串口的接收和回显功能正常,但是存在2个问题:1.串口接收并回显和数码管显示的时序有点混乱;2.数码管的显示出现异常,本应该依次显示9876543210abcdef,实际上显示的却是f9876543210abcde。 对源代码进行分析发现,时序混乱的原因是中断响应及中断返回的执行时序出现问题,修改代码后问题1被解决。 问题2的解决思路:源代码中,通过串口接收到的字符串被存储在一个一维数组array[16]中,该数组有16个元素,每个元素都是unsigned char型。在源代码中,先注释掉数码管显示的那一段代码,然后添加串口打印代码,串口打印实现的功能是依次显示array[0]到array[15]这16个元素的值。编译通过后,将程序烧写到单片机。使用串口调试助手,以十六进制的形式观察array[0]到array[15]的取值,结果如下: 目录 第1章需求分析 ............................................................................................................................ - 1 - 1.1课题名称 (1) 1.2任务 (1) 1.3要求 (1) 1.4设计思想 (1) 1.5课程设计环境 (1) 1.6设备运行环境 (2) 1.7我在本实验中完成的任务 (2) 第2章概要设计 ............................................................................................................................ - 2 - 2.1程序流程图 (2) 2.2设计方法及原理 (3) 第3章详细设计 ............................................................................................................................ - 3 - 3.1电路原理 (3) 3.1.1STC89C52芯片 ............................................................................................................. - 3 -3.2串口通信协议 (4) 3.3程序设计 (5) 3.3.1主程序模块 .................................................................................................................... - 5 - 3.3.2串口通讯模块 ................................................................................................................ - 6 - 3.3.3控制部分文件 ................................................................................................................ - 8 - 3.3.4公共部分模块 .............................................................................................................. - 11 -3.4电路搭建 (12) 3.4.1电路原理图 .................................................................................................................. - 12 -第4章上位机关键代码分析 ...................................................................................................... - 12 - 4.1打开串口操作 (12) 4.2后台线程处理串口程序 (15) 4.3程序运行界面 (18) 第5章课程设计总结与体会 ...................................................................................................... - 19 -第6章致谢 .................................................................................................................................. - 19 -参考文献........................................................................................................................................... - 19 - 实验单片机与PC机串口通信(C51编程)实验 要求: 1、掌握串行口的控制与状态寄存器SCON 2、掌握特殊功能寄存器PCON 3、掌握串行口的工作方式及其设置 4、掌握串行口的波特率(bondrate)选择 任务: 1、实现PC机发送一个字符给单片机,单片机接收到后即在个位、十位数码管上进行显示,同时将其回发给PC机。要求:单片机收到PC机发来的信号后用串口中断方式处理,而单片机回发给PC机时用查询方式。 采用软件仿真的方式完成,用串口调试助手和KEIL C,或串口调试助手和PROTEUS分别仿真。 需要用到以下软件:KEIL,VSPDXP5(虚拟串口软件),串口调试助手,Proteus。 (1)虚拟串口软件、串口调试助手和KEIL C的联调 首先在KEIL里编译写好的程序。 打开VSPD,界面如下图所示:(注明:这个软件用来进行串口的虚拟实现。在其网站上可以下载,但使用期为2周)。 左边栏最上面的是电脑自带的物理串口。点右边的addpair,可以添加成对的串口。一对串口已经虚拟互联了,如果添加的是COM3、COM4,用COM3发送数据,COM4就可以接收数据,反过来也可以。 接下来的一步很关键。把KEIL和虚拟出来的串口绑定。现在把COM3和KEIL绑定。在KEIL中进入DEBUG模式。在最下面的COMMAND命令行,输入 modecom39600,0,8,1 %分别设置com3的波特率、奇偶校验 位、数据位、停止位 assigncom3 (以上参数设置注意要和所编程序中设置一致!) 打开串口调试助手 可以看到虚拟出来的串口COM3、COM4,选择COM4,设置为波特率9600,无校验位、8位数据位,1位停止位(和COM3、程序里的设置一样)。打开COM4。 现在就可以开始调试串口发送接收程序了。可以通过KEIL发送数据,在串口调试助手中就可以显示出来。也可以通过串口调试助手发送数据,在KEIL中接收。 实验实现PC机发送一个字符给单片机,单片机接收到后将其回发给PC机。在调试助手上(模拟PC)发送数据,单片机收到后将收到的结果回送到调试助手上。 2、以下在Proteus和串口调试助手实现的结果: 将编译好的HEX程序加载到Proteus中,注意这里需要加上串口模块,用来进行串行通信参数的设置。 点击串口,可以对串口进行设置: 用串口调试助手发送数据,即可看到仿真结果。 实验参考程序源文件在exp2-comm文件夹中。 51 单片机的串口,是个全双工的串口,发送数据的同时,还可以接收数据。 当串行发送完毕后,将在标志位TI 置1,同样,当收到了数据后,也会在RI 置1。无 论RI 或TI 出现了1,只要串口中断处于开放状态,单片机都会进入串口中断处理程序。在中断程序中,要区分出来究竟是发送引起的中断,还是接收引起的中断,然后分别进行处理。 看到过一些书籍和文章,在串口收、发数据的处理方法上,很多人都有不妥之处。 接收数据时,基本上都是使用“中断方式”,这是正确合理的。 即:每当收到一个新数据,就在中断函数中,把RI 清零,并用一个变量,通知主函数, 收到了新数据。 发送数据时,很多的程序都是使用的“查询方式”,就是执行while(TI ==0); 这样的语句来 等待发送完毕。 这时,处理不好的话,就可能带来问题。 看了一些网友编写的程序,发现有如下几条容易出错: 1.有人在发送数据之前,先关闭了串口中断!等待发送完毕后,再打开串口中断。 这样,在发送数据的等待期间内,如果收到了数据,将不能进入中断函数,也就不会保存的这个新收到的数据。 这种处理方法,就会遗漏收到的数据。 2.有人在发送数据之前,并没有关闭串口中断,当TI = 1 时,是可以进入中断程序的。 但是,却在中断函数中,将TI 清零! 这样,在主函数中的while(TI ==0);,将永远等不到发送结束的标志。 3.还有人在中断程序中,并没有区分中断的来源,反而让发送引起的中断,执行了接收 中断的程序。 对此,做而论道发表自己常用的方法: 接收数据时,使用“中断方式”,清除RI 后,用一个变量通知主函数,收到新数据。 发送数据时,也用“中断方式”,清除TI 后,用另一个变量通知主函数,数据发送完毕。 这样一来,收、发两者基本一致,编写程序也很规范、易懂。 更重要的是,主函数中,不用在那儿死等发送完毕,可以有更多的时间查看其它的标志。 实例: 求一个PC 与单片机串口通信的程序,要求如下: 1、如果在电脑上发送以$开始的字符串,则将整个字符串原样返回(字符串长度不是固定的)。 #include 单片机实验报告 实验名称:串行通信实验 姓名:高知明 学号:110404320 班级:通信3 实验时间:2014-6-11 南京理工大学紫金学院电光系 一、实验目的(四号+黑体) 1、理解单片机串行口的工作原理; 2、学习使用单片机的TXD\RXD口; 3、了解MAX232芯片的作用; 二、实验原理 MCS-51单片机内部集成有一个UART,用于全双工方式的串行通信,可以发送、接收数据。他有两个相互独立的接收、发送缓冲器,这两个缓冲器同名(SBUF),共用一个地址号(99H)。发送缓冲器只能写入,不能读出,接受缓冲器只能读出,不能写入。要发送的字节数据直接写入发送缓冲器。SBUF=a;当UART接收到数据后,CPU从接收缓冲器中读取数据,a=SBUF;串行口内部有两个移位寄存器,一个用于串行发送,一个用于串行接收。定时器T1作为波特率发生器,波特率发生器的溢出信号昨接受或发送移位寄存器的位移时钟。TI与RI分别为发送完数据的中断标志,用来想CPU发中断请求。 三、实验内容 1、发送信号 1)C51程序: #include51单片机串口调试实验(C语言)
上位机与51单片机串口通信
51单片机与PC机通信资料
汇编语言实现串口通信(PC和单片机间)教学文案
C51单片机和电脑串口通信电路图
51单片机串口通信异常的调试一例
51单片机与PC串口通讯
实验单片机与PC机串口通信
单片机串口通信的发送与接收(可编辑修改word版)
51单片机usart通信程序(有CRC校验)
单片机串行通信实验