哪位好心人可以帮我做一个 两个c51单片机串口通信信然后显示小写a的甲乙机程序!

跟我学51单片机(三)——单片机串口通信实例,单片机串口通信实例,单片机串..
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
跟我学51单片机(三)——单片机串口通信实例
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口查看: 22|回复: 1
我写的一个实现单片机与PC机多机通讯的程序 串口通信
发表于 昨天&00:10
& &下面是我写的一个实现多个下位机(单片机)与一个上位机(PC机)的一主多从串口通讯程序,用的STC89C52RC,定时器2做串口通信波特率发生器。
& &&&实现功能是这样的:
& &&&用调试助手向单片机发送一个数据包。
& &&&通讯协议是这样的:
& && &数据包的格式如下所示(共10个字节组成):
0x2A,0xEB,0x8D,地址码,指令码,数据长度码,数据码,数据码,校验码,0xAD&&
前面三个字节为帧头,即开始符。
地址码: 欲传送的目的地址,即选定哪一个单片机。
指令码:向单片机发送的指令
数据长度码: 用于指示后面有效数据的个数
数据码:传送的数据,配合指令码的纯数据。
校验码: 累加和校验,对地址码,指令码,数据长度码,数据码进行累加,用来检验数据的完整性和正确性。
0xAD : 帧尾,即结束符。
& & 本程序实现功能是这样的:
& & 用调试助手向单片机发送一个数据包,单片机收到后对数据解析,再回传指定的数据。
& & 例如发送:2a eb 8d 01 03 01 01 06 ad
指令码为01,单片机接收到后解析,回传0xce 0x7b 0x11 0xed。其中前两个字节为开始符,最后一个字节为结束符。同理,若收到的指令码为02,回传0xce 0x7b 0x12 0xed。以此模拟控制单片机操作。
若接收错误,即累加校验码不等于单片机实际计算的累加和,回传0xce 0x7b 0x02 0xed,提示接收错误,要求PC重发数据(模拟,需要上位机软件配合才行)。
单片机开机初始化后即向PC发送一个数据0xce 0x7b 0x00 0xed,用于指示单片机与PC通信已连接。
下面是程序:
#define ID 0x01 //单片机地址
uint8 rec_& &//串口通信接收数据
uint8 state_flag=0;&&//通信协议解析状态标志,初始化为0
uint8 retval=0;&&//通信协议解析函数返回值,初始化为0
uint8&&//指令码
uint8 Data[2];&&//数据码
uint8 data_&&//数据长度码
程序大体思想是:
& & 首先定义了几个全局变量,接收到数据后,串口中断子程序中用变量rec_data存储一个字节的数据,随后对数据进行解析:首先判断数据包的完整性,正确性,然后提取指令码,数据码等数据,存放起来用于主程序处理。
& & 协议解析过程中,使用一个变量state_flag的全局变量作为协议解析状态标志,用于确定当前字节处于一帧数据中的那个部位,同时在接收过程中自动对接收数据进行校验和处理,在数据包接收完的同时也进行了校验的比较。因此当帧尾结束符接收到的时候,则表示一帧数据已经接收完毕,并且也通过了校验,关键数据也保存到了缓冲区(cmd和Data[])中。主程序即可通过查询retval的标志位来进行协议的解析处理。如果retval=1;& &//错误标志,数据包传送不正确。如果retval=2;& &//接收成功标志,数据包传送成功。
& & 接收过程中,只要哪一步收到的数据不是预期值,则直接将状态标志复位,用于下一帧数据的判断,避免状态自锁。
& & 以下是程序:
void PortInit();& && && && && & //各端口初始化
void TimerInit();& && &&&//定时器初始化
void UsartInit();& && &&&//串口初始化
void usart_cmd_scan();& && &&&//串口命令扫描
void Data_analysis();& &//通信协议解析函数
void Send(uint8 sendcmd);&&//数据发送函数
/*--------------------------------& && &&&串口中断服务子程序 ------------------------------------*/
void ser() interrupt 4
& &rec_data=SBUF;& &//读取接收到的数据
& &Data_analysis();//数据解析&&
* 函数名:Data_analysis
* 描&&述:通信协议解析函数
* 输&&入:无
* 输&&出:无
* 备&&注:解析串口接收到的数据
/*--------------------------------& && &&&多机通信协议格式 ------------------------------------*/
/*&&数据包的格式如下所示(共10个字节组成): */
/*&&0x2A,0xEB,0x8D,地址码,指令码,数据长度码,数据码,数据码,校验码,0xAD&&*/
void Data_analysis()
& &static uchar recdata_sum=0;&&//存放累加和
& &static uchar lencnt=0;&&//数据长度计数器
& &switch (state_flag)
& && &&&case 0:
& && && & {
& && && && & if(rec_data == 0x2A)& &&&// 是否帧头第一个数据
& && && && && &state_flag = 1;
& && && && & else
& && && && && &state_flag = 0;& & // 标志复位
& && && && && && &
& && && & }
& && &&&case 1:
& && && & {
& && && && & if(rec_data == 0xEB)& &&&// 是否帧头第二个数据
& && && && && &state_flag = 2;
& && && && & else
& && && && && &state_flag = 0;& & // 标志复位
& && && && &
& && && & }
& && &&&case 2:
& && && & {
& && && && & if(rec_data == 0x8D)& &&&// 是否帧头第三个数据
& && && && && &state_flag = 3;
& && && && & else
& && && && && &state_flag = 0;& & // 标志复位
& && && && &
& && && & }
& && &&&case 3:
& && && & {
& && && && & if(rec_data == ID)& & // 判断目的地址是否正确
& && && && && &{
& && && && && && &state_flag = 4;
& && && && && && &recdata_sum=rec_& &//开始累加
& && && && && &}& &
& && && && & else
& && && && && &state_flag = 0;& &// 标志复位
& && && && &
& && && & }
& && &&&case 4:
& && && & {
& && && && & state_flag = 5;
& && && && & cmd=rec_&&//指令码存储
& && && && & recdata_sum+=rec_&&//累加
& && && && &
& && && & }& && &&&
& && &&&case 5:
& && && & {
& && && && & lencnt = 0;&&//数据长度计数器清零
& && && && & data_count=rec_&&//数据长度码存储
& && && && & recdata_sum+=rec_&&//累加
& && && && & if (data_count!=0)&&//后面有数据码
& && && && && &state_flag=6;
& && && && & else
& && && && && &state_flag=8;
& && && && &
& && && & }
& && &&&case 6:
& && &&&case 7:
& && && & {
& && && && &&&Data[lencnt++]=rec_&&//数据码保存
& && && && &&&recdata_sum+=rec_& &//累加
& && && && &&&if(lencnt==data_count)
& && && && &&&{
& && && && && && && && && && && && && && &state_flag=8;
& && && && && && && && && && && && && & lencnt = 0;& && &&&
& && && && && && && && &&&}&&
& && && && &&&else
& && && && && & state_flag=7;
& && && && &&&
& && && & }
& && &&&case 8:
& && && & {
& && && && & if(recdata_sum==rec_data)& &//数据校验,判断累加和是否相等
& && && && && &state_flag=9;
& && && && & else
& && && && && &{
& && && && && && &retval=1;& &//置错误标志,数据包传送不正确。
& && && && && && &state_flag=0;& &
& && && && && &}
& && && && && && && && & recdata_sum=0;//累加和清零
& && && && &
& && && & }
& && &&&case 9:
& && && & {
& && && && & if (rec_data==0xAD)
& && && && && &{
& && && && && && && && && && && && && && & retval=2;& &//置接收成功标志,数据包传送成功。
& && && && && && && && && && && && && & state_flag=0;
& && && && && && && && && &}
& && && && & else
& && && && && &state_flag=0;
& && && && &
& && && & }
//主程序 , 不断扫描串口接收到的命令
void main()
& && &&&PortInit();& && && && && & //各端口初始化
& && &&&TimerInit();& && &&&//定时器初始化
& && &&&UsartInit();& && &&&//串口初始化& && && && && && && && && && && &&&
& && &&&Send(0xce);
& && &&&Send(0x7b);
& && &&&Send(0x00);
& && &&&Send(0xed);
& && &&&while(1)
& && && && && & usart_cmd_scan();& && &&&//串口命令扫描
& && &&&}& && &&&
* 函数名:usart_cmd_scan
* 描&&述:串口命令扫描
* 输&&入:无
* 输&&出:无
* 备&&注:扫描PC通过串口发送的命令
void usart_cmd_scan()
& && &&&& &//下位机向PC发送的命令码
& && && &&&switch (retval)
& && &&&case 1:& && &//数据发送错误,请求PC重发
& && && & {
& && && && & sendcmd=2;&&//向PC发送的重发数据命令,PC识别后向下位机重发数据包。
& && && && & Send(0xce);
& && && && && && && && & Send(0x7b);
& && && && && && && && & Send(sendcmd);
& && && && && && && && & Send(0xed);&&//向PC发送命令
& && && && && && && && & retval=0;& &//标志清零,防止重复扫描,重复执行。&&
& && && && && && && && &
& && && & }
& && &&&case 2:& && &//数据发送成功,执行命令
& && && & {
& && && && & switch (cmd)& & //命令解码
& && && && && && && && & {
& && && && && && && && && && && &case 0x01:
& && && && && && && && && && &&&{
& && && && && && && && && && && && && & Send(0xce);
& && && && && && && && && && && && && & Send(0x7b);
& && && && && && && && && && && && && & Send(0x11);
& && && && && && && && && && && && && & Send(0xed);
& && && && && && && && && && && && && & cmd=0x00;
& && && && && && && && && && && && && &
& && && && && && && && && && &&&}
& && && && && && && && && && &&&case 0x02:
& && && && && && && && && && &&&{
& && && && && && && && && && && && && & Send(0xce);
& && && && && && && && && && && && && & Send(0x7b);
& && && && && && && && && && && && && & Send(0x12);
& && && && && && && && && && && && && & Send(0xed);
& && && && && && && && && && && && && & cmd=0x00;
& && && && && && && && && && && && && &
& && && && && && && && && && &&&}
& && && && && && && && && && &&&case 0x03:
& && && && && && && && && && &&&{
& && && && && && && && && && && && && & Send(0xce);
& && && && && && && && && && && && && & Send(0x7b);
& && && && && && && && && && && && && & Send(0x13);
& && && && && && && && && && && && && & Send(0xed);
& && && && && && && && && && && && && & cmd=0x00;
& && && && && && && && && && && && && &
& && && && && && && && && && &&&}& && && && && &&&
& && && && && && && && & }
& && && && &}
& && && && && && &retval=0;& &//标志清零,防止重复扫描,重复执行。
* 函数名:Send
* 描&&述:串口数据发送函数
* 输&&入:sendcmd - 待发送的数据
* 输&&出:无
* 备&&注:
void Send(uint8 sendcmd)
& &ES=0;&&//关闭串口
& &SBUF=&&//发送数据,向PC发送。
& &while(!TI);
& &TI=0;&&//发送完成,TI清零
& &ES=1;&&//开串口
以上是我写的这个程序,希望大家指点一下。
程序运行整体可以,但是有个问题,也希望大神们能帮忙看一下什么问题
每次在单片机关机后,再重新上电后,发送都没反应,只有手动按下开发板的复位键后才能正常通信,当再次断电上电后,又不行了,又得按复位键才正常。按说开发板上电就复位了呀,为什么还要手动复位才行?什么的问题?你们试一下这个程序有这个问题吗?
& & 还望大神们帮忙指点啊!
发表于 11&分钟前
 复位的时间不同步& & 时序问题吧& && &我刚学单片机& &这是我自己的理解
Powered by51单片机串口通信程序的问题_百度知道
51单片机串口通信程序的问题
flag=0,在那个for循环那里;6;I get &quot,也就是为什么一开始就接受数据,那为什么还有while(,难道每输一位数据TI就被置1一次!TI);reg51; REN=1; ES=1,然后到while里面等待中断的发生?主函数是用来发送数据的;
TI=0; TH1=0xf9;i++)
SBUF=table [i],然后执行if语句;uchar code table []=&quot, i? 中断发生后flag被置1; SM0=0, 先初始化.h&gt,SBUF一次是只接收一位数据吧!TI);
while (;# define uint unsigned int # define uchar unsigned char}程序开始后进入main函数;}void main (){ int0 ()?就算可以产生中断,此时SBUF难道有数据;
SBUF=a; while (1) {
if (flag==1)
ES=0?在PC机上输入的数据是不是通过SBUF=a; TL1=0xf9;
while (,但是中断为什么要发生呢; TR1=1;
} }}void ser ()interrupt 4{ RI=0;;发送的;void int0 (){ TMOD=0x20,a=SBUF!TI)?数据发送完后TI被置0;i& SM1=1,中断服务程序是用来接收数据的,那么显示屏上显示的是a=SBUF的值吗# include & a=SBUF,也就是串口中断只能由RI引起; flag=1,不应该是只有在执行了if以后SBUF才开始有值吗,那么RI是怎么在数据发送完后置1的; EA=1
提问者采纳
这个数据!TI)。TI不会自动复位,无论现在是不是在循环状态,中断是当你中断允许开关打开就开始工作,if (flag==1)应该是flag被置1的时候,可以详细看看书就知道了,自动置位,中止中断你描述有点乱。你PC直接发送a就可以了。有段时间没接触了。其次,中断符合中断条件就会发生,是等待数据发送完成,我大概说一下,也就是说,前面的for循环应该是发送i get ,可能某些细节不是很准确,不过你提的这些问题其实都是蛮基础了,然后while (,要手动置0,总共6位。RI接收完,否则无法发送,SBUF是单片机内部指令。首先,这个跟循环什么的根本没有影响
我知道只要符合条件中断就会发生,但是我感觉这里并没有符合发生的条件,比如一开始flag是为0的,要想发生数据flag起码要为1吧,这就什么中断发生过了,串口中断发生的条件是发送或接受了停止位,但是程序一开始是不可能发送数据的,肯定是接受了数据,关键是为什么程序一开始就可以接受数据
初始是接收到数据flag置位,if就可以继续执行,也就是接收数据后再发送数据。至于为什么可以一开始就接收数据,是因为你开了串口通信中断啊,底层执行。你设置了,程序开始它就一直接收数据了。
为什么SBUF既可以用for循环赋值还可以直接SBUF=a?难道SBUF不应该是一位一位赋值的么?还有为什么那个a=SBUF也是只一个语句就读走了
提问者评价
其他类似问题
为您推荐:
51单片机的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁对2个51单片机进行串口通信的具体步骤是什么,高手来看看,能写程序的请帮我写一下,不胜感激!_百度知道
对2个51单片机进行串口通信的具体步骤是什么,高手来看看,能写程序的请帮我写一下,不胜感激!
提问者采纳
这个是正常的SBUF的接收和发送处理就行了;2;上面两个是初始化……希望这个你自己好好写写,不然可以说你什么都不会了……31。、两个串口的接口Rx接另外一个Tx、设置波特率,Tx接另外一个的Rx就可以了,两边相同、设置串口相关寄存器
其他类似问题
为您推荐:
其他2条回答
、发送接收就可以了,两边相同;2;3、设置波特率、设置串口相关寄存器
看看:C语言的也有,自己找找看。
51单片机的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁09-0907-0409-0209-01
09-2109-2610-1609-03
◇本站云标签
◇热点推荐}

我要回帖

更多关于 c51单片机串口通信 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信