一、PC端串口调试助手软件与Proteus中51单片机相互通信的单片机C语言程序
#include <reg52.h> #define uchar unsigned char #define uint unsigned int uchar flag,a,i,j; uchar code table0[]="I get "; uchar code table1[]=" ";//回车换行 void String_Timer2_init()//串口定时器初始化函数 { TMOD=0x20;//0010 0000定时器工作方式为方式2,8位自动重装。 TH1=0xfd;//初始化计数器高8位:1111 1101 TL1=0xfd;//初始化计数器低8位 TR1=1;//启动定时器1 SM0=0;//设定串口工作方式为方式1(10位异步通信) SM1=1;//设定串口工作方式 REN=1;//打开串口中断接收允许 EA=1;//打开全局中断 ES=1;//打开串口中断允许位 } void main() { String_Timer2_init();//串口定时器初始化函数 while(1)//固定循环 { if(flag==1)//判断检测发送数据标志位变量flag是否为1,若为1则运行以下单片机发送数据缓存寄存器给PC端串口调试助手发送数据。 { ES=0;//关闭串口中断允许位,阻止进入串口中断服务程序。为什么要设置ES=0?由于接下来单片机发送数据缓存寄存器给PC端串口调试助手发送数据结束后,TI(即串口发送中断标志位)=1,若ES不设置为0,在TI(即串口发送中断标志位)=1时,会进入串口中断服务程序执行flag=1,又得回来再次判断if(flag==1),从而无法运行下面的程序。 for(i=0;i<6;i++)//循环发送数据个数 { SBUF=table0[i];//将table0数组中的数据存入单片机发送数据缓存寄存器 while(!TI);//判断串口发送中断标志位是否为1,若为1则单片机发送数据缓存寄存器给PC端串口调试助手发送数据结束。为什么在此编写while(!TI)?由于需要把单片机发送数据缓存寄存器保存的数据发送给PC端串口调试助手。 TI=0;//TI(即串口发送中断标志位)=0,表示单片机发送数据缓存寄存器可重新给PC端串口调试助手发送数据。 } SBUF=a;//表示单片机接收数据缓存寄存器把从串口中断服务程序获取的某数据(用数值变量a表示)赋给单片机发送数据缓存寄存器。为什么?由于串口定时器初始化函数中REN(串口中断接收允许)=1与ES(串口中断允许位)=1被初始化后,就可以进入串口中断服务程序获取PC端串口调试助手给单片机发送某数据,然后单片机接收数据缓存寄存器接收PC端串口调试助手发来的某数据。 while(!TI);//判断串口发送中断标志位是否为1,若为1则单片机发送数据缓存寄存器给PC端串口调试助手发送数据结束。为什么在此编写while(!TI)?由于需要把单片机发送数据缓存寄存器保存的数据发送给PC端串口调试助手。 TI=0; //TI(即串口发送中断标志位)=0,表示单片机发送数据缓存寄存器可重新给PC端串口调试助手发送数据。 for(j=0;j<3;j++)//循环发送数据个数 { SBUF=table1[j];//将table1数组中的数据存入单片机发送数据缓存寄存器 while(!TI);//判断串口发送中断标志位是否为1,若为1则单片机发送数据缓存寄存器给PC端串口调试助手发送数据结束。为什么在此编写while(!TI)?由于需要把单片机发送数据缓存寄存器保存的数据发送给PC端串口调试助手。 TI=0;//TI(即串口发送中断标志位)=0,表示单片机发送数据缓存寄存器可重新给PC端串口调试助手发送数据。 } ES=1;//打开串口中断允许位,允许进入串口中断服务程序。 flag=0;//判断检测发送数据标志位变量flag是否为0,若为0则跳出运行单片机发送数据缓存寄存器给PC端串口调试助手发送数据。 } } } void string() interrupt 4//串口中断服务程序(函数) { RI=0;//表示单片机接收数据缓存寄存器可重新接收PC端串口调试助手发送数据。 a=SBUF;//表示PC端串口调试助手给单片机接收数据缓存寄存器发送某数据,然后单片机接收数据缓存寄存器接收PC端串口调试助手发来的某数据,并赋给数值变量a。 flag=1;//置检测发送数据标志位变量flag为1,运行单片机发送数据缓存寄存器给PC端串口调试助手发送数据。 }