51单片机串口通信相关例程.docx
《51单片机串口通信相关例程.docx》由会员分享,可在线阅读,更多相关《51单片机串口通信相关例程.docx(35页珍藏版)》请在冰豆网上搜索。
51单片机串口通信相关例程
51单片机串口通信
1./*打开串口调试程序,将波特率设置为9600,无奇偶校验
晶振11.0592MHz,发送和接收使用的格式相同,如都使用
字符型格式,在发送框输入hello,ILoveMCU,在接
收框中同样可以看到相同字符,说明设置和通信正确*/
#include
/*主程序*/
voidmain(void)
{
SCON=0x50;/*SCON:
模式1,8-bitUART,使能接收*/
TMOD|=0x20;/*TMOD:
timer1,mode2,
8-bitreload*/
TH1=0xFD;/*TH1:
reloadvaluefor9600baud@11.0592MHz*/
TR1=1;/*TR1:
timer1run*/
EA=1;/*打开总中断*/
ES=1;/*打开串口中断*/
while
(1)/*主循环不做任何动作*/
}
voidUART_SER(void)interrupt4//串行中断服务程序
unsignedcharTemp;//定义临时变量
if(RI)//判断是接收中断产生
RI=0;//标志位清零
Temp=SBUF;//读入缓冲区的值
P1=Temp;//把值输出到P1口,用于观察
SBUF=Temp;//把接收到的值再发回电脑端
if(TI)//如果是发送标志位,清零
TI=0;
2.51单片机与电脑串口通信的C程序,最好是中断方式的
unsignedcharch;
bitread_flag=0;
voidinit_serialcom(void)//串口通信初始设定
SCON=0x50;//UART为模式1,8位数据,
允许接收
TMOD|=0x20;//定时器1为模式2,8位自动重装
PCON|=0x80;//SMOD=1;
TH1=0xFD;//Baud:
19200fosc="11".0592MHz
IE|=0x90;//EnableSerialInterrupt
TR1=1;//timer1run
TI=1;
//向串口发送一个字符
voidsend_char_com(unsignedcharch)
SBUF=ch;
while(TI==0);
voidserial()interrupt4using3//串口接收中断函数
if(RI)
RI=0;
ch=SBUF;
read_flag=1;//就置位取数标志
main()
init_serialcom();//初始化串口
(1)
if(read_flag)//如果取数标志已置位,就将读到的数从串口发出
read_flag=0;//取数标志清0send_char_com(ch);
3.//单片机串行口发送/接收程序,每接收到字节即发送出去
//和微机相接后键入的字符回显示在屏幕上
//可用此程序测试
#defineXTAL11059200//CUP晶振频率
#definebaudrate9600//通信波特率
unsignedcharc;
TMOD=0x20;//定时器1工作于8位自动重载模式,用于产生波特率
TH1=(unsignedchar)(256-(XTAL/(32L*12L*baudrate)));
TL1=(unsignedchar)(256-(XTAL/(32L*12L*baudrate)));//定时器0赋初值
SCON=0x50;
PCON=0x00;
TR1=1;
IE=0x00;//禁止任何中断
while(RI==0);
c=SBUF;//从缓冲区中把接收的字符放入c中
SBUF=c;//要发送的字符放入缓冲区
4./////////////////////////////////////////////////////////////////////////
//E51Pro.c
//Easy51Pro编程器主程序,负责通讯,管理编程操作
/////////////////////////////////////////////////////////////////////////
BYTEComBuf[18];//串口通讯数据缓存,发送和接收都使用
UINTnAddress;//ROM中地址计数
UINTnTimeOut;//超时计数
ProWorkpw;//编程器一般操作
voidDelay_us(BYTEnUs)//微秒级延时<255us
TH0=0;
TL0=0;
TR0=1;
while(TL0{}TR0=0;}voidDelay_ms(UINTnMs)//豪秒级的延时<65535ms{UINTn=0;TR0=1;while(n{TH0=0;TL0=20;while(TH0<4){}n++;}TR0=0;}BOOLWaitComm()//等待上位机的命令,18字节{BYTEn=0;RI=0;while(!RI){}//等待第一个字节ComBuf[n]=SBUF;RI=0;n++;for(n;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000)//后17个字节都有超时限制return0;}ComBuf[n]=SBUF;RI=0;}return1;}BOOLWaitResp()//等待上位机回应,1字节,有超时限制{nTimeOut=0;RI=0;while(!RI){nTimeOut++;if(nTimeOut>50000){return0;}}RI=0;ComBuf[0]=SBUF;return1;}BOOLWaitData()//写器件时等待上位机数据,18字节,有超时限制{BYTEn;RI=0;for(n=0;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000){return0;}}RI=0;ComBuf[n]=SBUF;}return1;}voidSendData()//发送数据或回应操作完成,18字节{BYTEn=0;for(n;n<=17;n++){TI=0;SBUF=ComBuf[n];while(!TI){}TI=0;}}voidSendResp()//回应上位机1个字节,在写器件函数中使用{TI=0;SBUF=ComBuf[0];while(!TI){}TI=0;}voidSetVpp5V()//设置Vpp为5v{P3_4=0;P3_3=0;}voidSetVpp0V()//设置Vpp为0v{P3_3=0;P3_4=1;}voidSetVpp12V()//设置Vpp为12v{P3_4=0;P3_3=1;}voidRstPro()//编程器复位{pw.fpProOver();//直接编程结束SendData();//通知上位机,表示编程器就绪,可以直接用此函数因为协议号(ComBuf[0])还没被修改,下同}voidReadSign()//读特征字{pw.fpReadSign();SendData();//通知上位机,送出读出器件特征字}voidErase()//擦除器件{pw.fpErase();SendData();//通知上位机,擦除了器件}voidWrite()//写器件{BYTEn;pw.fpInitPro();//编程前的准备工作SendData();//回应上位机表示进入写器件状态,可以发来数据while(1){if(WaitData())//如果等待数据成功{if(ComBuf[0]==0x07)//判断是否继续写{for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块{if(!pw.fpWrite(ComBuf[n]))//<<<<<<<<<调用写该器件一个单元的函数{pw.fpProOver();//出错了就结束编程ComBuf[0]=0xff;SendResp();//回应上位机一个字节,表示写数据出错了WaitData();//等待上位机的回应后就结束return;}nAddress++;//下一个单元}ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续SendResp();}elseif(ComBuf[0]==0x00)//写器件结束break;else//可能是通讯出错了{pw.fpProOver();return;}}else//等待数据失败{pw.fpProOver();return;}}pw.fpProOver();//编程结束后的工作Delay_ms(50);//延时等待上位机写线程结束ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}voidRead()//读器件{BYTEn;pw.fpInitPro();//先设置成编程状态SendData();//回应上位机表示进入读状态while(1){if(WaitResp())//等待上位机回应1个字节{if(ComBuf[0]==0)//ComBuf[0]==0表示读结束{break;}elseif(ComBuf[0]==0xff)//0xff表示重发{nAddress=nAddress-0x0010;}for(n=2;n<=17;n++)//ComBuf[2~17]保存读出的数据块{ComBuf[n]=pw.fpRead();//<<<<<<<<<<调用写该器件一个单元的函数nAddress++;//下一个单元}ComBuf[0]=6;//向上位机发送读出的数据块SendData();}elsebreak;//等待回应失败}pw.fpProOver();//操作结束设置为运行状态ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}voidLock()//写锁定位{pw.fpLock();SendData();}///////////////////////////////////////////////////////////////////////////////////所支持的FID,请在这里继续添加/////////////////////////////////////////////////////////////////////////////externvoidPreparePro00();//FID=00:AT89C51编程器externvoidPreparePro01();//FID=01:AT89C2051编程器externvoidPreparePro02();//FID=02:AT89S51编程器voidmain(){SP=0x60;SetVpp5V();//先初始化Vpp为5vSCON=0x00;TCON=0x00;//PCON=0x00;//波特率*2IE=0x00;//TMOD:GATE|C/!T|M1|M0|GATE|C/!T|M1|M0//00100001TMOD=0x21;//T0用于延时程序TH1=0xff;TL1=0xff;//波特率28800*2,注意PCON//SCON:SM0|SM1|SM2|REN|TB8|RB8|TI|RI//01010000SCON=0x50;TR1=1;Delay_ms(1000);//延时1秒后编程器自举ComBuf[0]=0;SendData();while(1)//串口通讯采用查询方式{if(!WaitComm())//如果超时,通讯出错{Delay_ms(500);ComBuf[0]=0;//让编程器复位,使编程器就绪}switch(ComBuf[1])//根据FID设置(ProWork)pw中的函数指针{case0://at89c51编程器PreparePro00();break;case1://at89c2051编程器PreparePro01();break;case2://at89s51编程器PreparePro02();break;//case3:支持新器件时,请继续向下添加//break;//case4://break;default:ComBuf[0]=0xff;ComBuf[1]=0xff;//表示无效的操作break;}switch(ComBuf[0])//根据操作ID跳到不同的操作函数{case0x00:RstPro();break;//编程器复位case0x01:ReadSign();break;//读特征字case0x02:Erase();break;//擦除器件case0x03:Write();break;//写器件case0x04:Read();break;//读器件case0x05:Lock();break;//写锁定位default:SendData();break;}}}5.voidInitSerial(void){TMOD=0x20;//T1方式2PCON=0x00;//PCON=00H,SMOD=0PD=PCON.2=1进入掉电模式TH1=TL1=BAUD_9600;//BAUD:9600SCON=0x50;//串行通信方式1REN=1允许接收ET1=0;//不允许中断TR1=1;//开启定时器1IE=0;//关闭所有中断允许位memset(&SerialBuf,0x00,SERIAL_BUF_LEN);//初始化SerialBuf[SERIAL_BUF_LEN]}/**********************************************************名称:SendByte()**功能:串口发送一个字节**输入:ucData**返回:无**说明:无********************************************************/voidSendByte(unsignedcharucData){SBUF=ucData;while(!TI){_CLRWDT_;}TI=0;} RS232串口通信程序#includeunsignedcharcodedispcode1[]={" welcome! "};unsignedcharcodedispcode2[]={""};unsignedchari,j,k,l,DData;sbitRS=P3^5;sbitRW=P3^6;sbitE=P3^7;unsignedcharm=0;voiddelay(){for(l=0;l<=100;l++){}}voidenable()//writeorder{RS=0;RW=0;E=0;delay();E=1;}voidenable2()//writedata{RS=1;RW=0;E=0;delay();E=1;}voidinitializtion()//lcdinitializtion{for(i=0;i<=100;i++)P0=0x01;enable();P0=0x38;enable();P0=0x0f;enable();P0=0x06;enable();}voidDisplay(m,DData)//displaydata{ P0=0xC0+m; //writeaddress enable(); P0=DData; //writedata enable2();}voidEsisr()interrupt4//串口接收中断服务程序{ unsignedchartemp;ES=0;if(RI==1){ RI=0; temp=SBUF;//接收数据 SBUF=temp; //将接收到的数据发送至PC机 Display(m,temp);//将接收到的数据送LCD显示 while(!TI);//等待数据发送完成 TI=0; m++; if(m>16) m=0;}ES=1;}voidsystem_initial(void) //systeminitializtion{ TMOD=0x21;//定时器1工作方式2,定时器0工作方式1 PCON=0x00;//数据传输率选择。 SCON=0x50;//串口工作方式选择,并打开接收允许。 TH1=0xfd;//定时器赋初值。 TL1=0xfd;//波特率9600bit/s TR1=1;//启动定时器。 EA=1; //开总中断。 ES=1;}voidmain(){ initializtion(); P0=0x80;enable(); for(j=0;j<=15;j++) { P0=dispcode1[j]; enable2(); } P0=0xC0;enable(); for(k=0;k<=15;k++) { P0=dispcode2[k]; enable2(); } system_initial(); while(1);}RS232串口通信单片机接收发送数据的C51程序这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收和查询发送。关于RS232串口通信原理详解见:关于单片机串口控制寄存器设置见:#include#include#definelength4 //数据长度unsignedcharinbuf[length];unsignedcharchecksum,counter;bitflag=0; //取数标记main(){init_serial(); //串行口初始化while(1){if(flag!=0) //如果取数标志已置位,就将读到的数从串口发出{flag=0; //取数标志清0send_string(inbuf,length); //向串口发送字符串}}}/*串行口初始化*/voidinit_serial(void) {SCON=0x50; //串行工作方式1,8位异步通信方式TMOD|=0x20; //定时器1,方式2,8位自动重装PCON|=0x80; //SMOD=1,表示数据传输率加倍TH1=0xF4; //数据传输率:4800fosc=11.0592MHzIE|=0x90; //允许串行中断TR1=1; //启动定时器1}/*向串口发送一个字符*/voidsend_char(unsignedcharx){SBUF=x;while(TI==0);TI=0;}/*向串口发送
TR0=0;
voidDelay_ms(UINTnMs)//豪秒级的延时<65535ms
UINTn=0;
while(n{TH0=0;TL0=20;while(TH0<4){}n++;}TR0=0;}BOOLWaitComm()//等待上位机的命令,18字节{BYTEn=0;RI=0;while(!RI){}//等待第一个字节ComBuf[n]=SBUF;RI=0;n++;for(n;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000)//后17个字节都有超时限制return0;}ComBuf[n]=SBUF;RI=0;}return1;}BOOLWaitResp()//等待上位机回应,1字节,有超时限制{nTimeOut=0;RI=0;while(!RI){nTimeOut++;if(nTimeOut>50000){return0;}}RI=0;ComBuf[0]=SBUF;return1;}BOOLWaitData()//写器件时等待上位机数据,18字节,有超时限制{BYTEn;RI=0;for(n=0;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000){return0;}}RI=0;ComBuf[n]=SBUF;}return1;}voidSendData()//发送数据或回应操作完成,18字节{BYTEn=0;for(n;n<=17;n++){TI=0;SBUF=ComBuf[n];while(!TI){}TI=0;}}voidSendResp()//回应上位机1个字节,在写器件函数中使用{TI=0;SBUF=ComBuf[0];while(!TI){}TI=0;}voidSetVpp5V()//设置Vpp为5v{P3_4=0;P3_3=0;}voidSetVpp0V()//设置Vpp为0v{P3_3=0;P3_4=1;}voidSetVpp12V()//设置Vpp为12v{P3_4=0;P3_3=1;}voidRstPro()//编程器复位{pw.fpProOver();//直接编程结束SendData();//通知上位机,表示编程器就绪,可以直接用此函数因为协议号(ComBuf[0])还没被修改,下同}voidReadSign()//读特征字{pw.fpReadSign();SendData();//通知上位机,送出读出器件特征字}voidErase()//擦除器件{pw.fpErase();SendData();//通知上位机,擦除了器件}voidWrite()//写器件{BYTEn;pw.fpInitPro();//编程前的准备工作SendData();//回应上位机表示进入写器件状态,可以发来数据while(1){if(WaitData())//如果等待数据成功{if(ComBuf[0]==0x07)//判断是否继续写{for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块{if(!pw.fpWrite(ComBuf[n]))//<<<<<<<<<调用写该器件一个单元的函数{pw.fpProOver();//出错了就结束编程ComBuf[0]=0xff;SendResp();//回应上位机一个字节,表示写数据出错了WaitData();//等待上位机的回应后就结束return;}nAddress++;//下一个单元}ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续SendResp();}elseif(ComBuf[0]==0x00)//写器件结束break;else//可能是通讯出错了{pw.fpProOver();return;}}else//等待数据失败{pw.fpProOver();return;}}pw.fpProOver();//编程结束后的工作Delay_ms(50);//延时等待上位机写线程结束ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}voidRead()//读器件{BYTEn;pw.fpInitPro();//先设置成编程状态SendData();//回应上位机表示进入读状态while(1){if(WaitResp())//等待上位机回应1个字节{if(ComBuf[0]==0)//ComBuf[0]==0表示读结束{break;}elseif(ComBuf[0]==0xff)//0xff表示重发{nAddress=nAddress-0x0010;}for(n=2;n<=17;n++)//ComBuf[2~17]保存读出的数据块{ComBuf[n]=pw.fpRead();//<<<<<<<<<<调用写该器件一个单元的函数nAddress++;//下一个单元}ComBuf[0]=6;//向上位机发送读出的数据块SendData();}elsebreak;//等待回应失败}pw.fpProOver();//操作结束设置为运行状态ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}voidLock()//写锁定位{pw.fpLock();SendData();}///////////////////////////////////////////////////////////////////////////////////所支持的FID,请在这里继续添加/////////////////////////////////////////////////////////////////////////////externvoidPreparePro00();//FID=00:AT89C51编程器externvoidPreparePro01();//FID=01:AT89C2051编程器externvoidPreparePro02();//FID=02:AT89S51编程器voidmain(){SP=0x60;SetVpp5V();//先初始化Vpp为5vSCON=0x00;TCON=0x00;//PCON=0x00;//波特率*2IE=0x00;//TMOD:GATE|C/!T|M1|M0|GATE|C/!T|M1|M0//00100001TMOD=0x21;//T0用于延时程序TH1=0xff;TL1=0xff;//波特率28800*2,注意PCON//SCON:SM0|SM1|SM2|REN|TB8|RB8|TI|RI//01010000SCON=0x50;TR1=1;Delay_ms(1000);//延时1秒后编程器自举ComBuf[0]=0;SendData();while(1)//串口通讯采用查询方式{if(!WaitComm())//如果超时,通讯出错{Delay_ms(500);ComBuf[0]=0;//让编程器复位,使编程器就绪}switch(ComBuf[1])//根据FID设置(ProWork)pw中的函数指针{case0://at89c51编程器PreparePro00();break;case1://at89c2051编程器PreparePro01();break;case2://at89s51编程器PreparePro02();break;//case3:支持新器件时,请继续向下添加//break;//case4://break;default:ComBuf[0]=0xff;ComBuf[1]=0xff;//表示无效的操作break;}switch(ComBuf[0])//根据操作ID跳到不同的操作函数{case0x00:RstPro();break;//编程器复位case0x01:ReadSign();break;//读特征字case0x02:Erase();break;//擦除器件case0x03:Write();break;//写器件case0x04:Read();break;//读器件case0x05:Lock();break;//写锁定位default:SendData();break;}}}5.voidInitSerial(void){TMOD=0x20;//T1方式2PCON=0x00;//PCON=00H,SMOD=0PD=PCON.2=1进入掉电模式TH1=TL1=BAUD_9600;//BAUD:9600SCON=0x50;//串行通信方式1REN=1允许接收ET1=0;//不允许中断TR1=1;//开启定时器1IE=0;//关闭所有中断允许位memset(&SerialBuf,0x00,SERIAL_BUF_LEN);//初始化SerialBuf[SERIAL_BUF_LEN]}/**********************************************************名称:SendByte()**功能:串口发送一个字节**输入:ucData**返回:无**说明:无********************************************************/voidSendByte(unsignedcharucData){SBUF=ucData;while(!TI){_CLRWDT_;}TI=0;} RS232串口通信程序#includeunsignedcharcodedispcode1[]={" welcome! "};unsignedcharcodedispcode2[]={""};unsignedchari,j,k,l,DData;sbitRS=P3^5;sbitRW=P3^6;sbitE=P3^7;unsignedcharm=0;voiddelay(){for(l=0;l<=100;l++){}}voidenable()//writeorder{RS=0;RW=0;E=0;delay();E=1;}voidenable2()//writedata{RS=1;RW=0;E=0;delay();E=1;}voidinitializtion()//lcdinitializtion{for(i=0;i<=100;i++)P0=0x01;enable();P0=0x38;enable();P0=0x0f;enable();P0=0x06;enable();}voidDisplay(m,DData)//displaydata{ P0=0xC0+m; //writeaddress enable(); P0=DData; //writedata enable2();}voidEsisr()interrupt4//串口接收中断服务程序{ unsignedchartemp;ES=0;if(RI==1){ RI=0; temp=SBUF;//接收数据 SBUF=temp; //将接收到的数据发送至PC机 Display(m,temp);//将接收到的数据送LCD显示 while(!TI);//等待数据发送完成 TI=0; m++; if(m>16) m=0;}ES=1;}voidsystem_initial(void) //systeminitializtion{ TMOD=0x21;//定时器1工作方式2,定时器0工作方式1 PCON=0x00;//数据传输率选择。 SCON=0x50;//串口工作方式选择,并打开接收允许。 TH1=0xfd;//定时器赋初值。 TL1=0xfd;//波特率9600bit/s TR1=1;//启动定时器。 EA=1; //开总中断。 ES=1;}voidmain(){ initializtion(); P0=0x80;enable(); for(j=0;j<=15;j++) { P0=dispcode1[j]; enable2(); } P0=0xC0;enable(); for(k=0;k<=15;k++) { P0=dispcode2[k]; enable2(); } system_initial(); while(1);}RS232串口通信单片机接收发送数据的C51程序这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收和查询发送。关于RS232串口通信原理详解见:关于单片机串口控制寄存器设置见:#include#include#definelength4 //数据长度unsignedcharinbuf[length];unsignedcharchecksum,counter;bitflag=0; //取数标记main(){init_serial(); //串行口初始化while(1){if(flag!=0) //如果取数标志已置位,就将读到的数从串口发出{flag=0; //取数标志清0send_string(inbuf,length); //向串口发送字符串}}}/*串行口初始化*/voidinit_serial(void) {SCON=0x50; //串行工作方式1,8位异步通信方式TMOD|=0x20; //定时器1,方式2,8位自动重装PCON|=0x80; //SMOD=1,表示数据传输率加倍TH1=0xF4; //数据传输率:4800fosc=11.0592MHzIE|=0x90; //允许串行中断TR1=1; //启动定时器1}/*向串口发送一个字符*/voidsend_char(unsignedcharx){SBUF=x;while(TI==0);TI=0;}/*向串口发送
TL0=20;
while(TH0<4)
n++;
BOOLWaitComm()//等待上位机的命令,18字节
BYTEn=0;
while(!
RI){}//等待第一个字节
ComBuf[n]=SBUF;
for(n;n<=17;n++)
nTimeOut=0;
RI)
nTimeOut++;
if(nTimeOut>10000)//后17个字节都有超时限制
return0;
return1;
BOOLWaitResp()//等待上位机回应,1字节,有超时限制
if(nTimeOut>50000)
ComBuf[0]=SBUF;
BOOLWaitData()//写器件时等待上位机数据,18字节,有超时限制
BYTEn;
for(n=0;n<=17;n++)
if(nTimeOut>10000)
voidSendData()//发送数据或回应操作完成,18字节
SBUF=ComBuf[n];
TI){}
voidSendResp()//回应上位机1个字节,在写器件函数中使用
SBUF=ComBuf[0];
voidSetVpp5V()//设置Vpp为5v
P3_4=0;
P3_3=0;
voidSetVpp0V()//设置Vpp为0v
P3_4=1;
voidSetVpp12V()//设置Vpp为12v
P3_3=1;
voidRstPro()//编程器复位
pw.fpProOver();//直接编程结束
SendData();//通知上位机,表示编程器就绪,可以直接用此函数因为协议号(ComBuf[0])还没被修改,下同
voidReadSign()//读特征字
pw.fpReadSign();
SendData();//通知上位机,送出读出器件特征字
voidErase()//擦除器件
pw.fpErase();
SendData();//通知上位机,擦除了器件
voidWrite()//写器件
pw.fpInitPro();//编程前的准备工作
SendData();//回应上位机表示进入写器件状态,
可以发来数据
if(WaitData())//如果等待数据成功
if(ComBuf[0]==0x07)//判断是否继续写
for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块
if(!
pw.fpWrite(ComBuf[n]))//<<<<<<<<<调用写该器件一个单元的函数
pw.fpProOver();//出错了就结束编程
ComBuf[0]=0xff;
SendResp();//回应上位机一个字节,
表示写数据出错了
WaitData();//等待上位机的回应后就结束
return;
nAddress++;//下一个单元
ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续
SendResp();
elseif(ComBuf[0]==0x00)//写器件结束
break;
else//可能是通讯出错了
pw.fpProOver();
else//等待数据失败
pw.fpProOver();//编程结束后的工作
Delay_ms(50);//延时等待上位机写线程结束
ComBuf[0]=0;//通知上位机编程器进入就绪状态
SendData();
voidRead()//读器件
pw.fpInitPro();//先设置成编程状态
SendData();//回应上位机表示进入读状态
if(WaitResp())//等待上位机回应1个字节
if(ComBuf[0]==0)//ComBuf[0]==0表示读结束
elseif(ComBuf[0]==0xff)//0xff表示重发
nAddress=nAddress-0x0010;
for(n=2;n<=17;n++)//ComBuf[2~17]保存读出的数据块
ComBuf[n]=pw.fpRead();//<<<<<<<<<<调用写该器件一个单元的函数
ComBuf[0]=6;//向上位机发送读出的数据块
else
break;//等待回应失败
pw.fpProOver();//操作结束设置为运行状态
voidLock()//写锁定位
pw.fpLock();
/////////////////////////////////////////////////////////////////////////////////
//所支持的FID,请在这里继续添加
/////////////////////////////////////////////////////////////////////////////
externvoidPreparePro00();//FID=00:
AT89C51编程器
externvoidPreparePro01();//FID=01:
AT89C2051编程器
externvoidPreparePro02();//FID=02:
AT89S51编程器
voidmain()
SP=0x60;
SetVpp5V();//先初始化Vpp为5v
SCON=0x00;
TCON=0x00;
//PCON=0x00;//波特率*2
IE=0x00;
//TMOD:
GATE|C/!
T|M1|M0|GATE|C/!
T|M1|M0
//00100001
TMOD=0x21;//T0用于延时程序
TH1=0xff;
TL1=0xff;//波特率28800*2,注意PCON
//SCON:
SM0|SM1|SM2|REN|TB8|RB8|TI|RI
//01010000
Delay_ms(1000);//延时1秒后编程器自举
ComBuf[0]=0;
(1)//串口通讯采用查询方式
WaitComm())//如果超时,通讯出错
Delay_ms(500);
ComBuf[0]=0;//让编程器复位,使编程器就绪
switch(ComBuf[1])//根据FID设置(ProWork)pw中的函数指针
case0:
//at89c51编程器
PreparePro00();break;
case1:
//at89c2051编程器
PreparePro01();break;
case2:
//at89s51编程器
PreparePro02();break;
//case3:
支持新器件时,请继续向下添加
//break;
//case4:
default:
ComBuf[1]=0xff;//表示无效的操作
switch(ComBuf[0])//根据操作ID跳到不同的操作函数
case0x00:
RstPro();break;//编程器复位
case0x01:
ReadSign();break;//读特征字
case0x02:
Erase();break;//擦除器件
case0x03:
Write();break;//写器件
case0x04:
Read();break;//读器件
case0x05:
Lock();break;//写锁定位
SendData();break;
5.voidInitSerial(void)
TMOD=0x20;//T1方式2
PCON=0x00;//PCON=00H,SMOD=0PD=PCON.2=1进入掉电模式
TH1=TL1=BAUD_9600;//BAUD:
9600
SCON=0x50;//串行通信方式1REN=1允许接收
ET1=0;//不允许中断
TR1=1;//开启定时器1
IE=0;//关闭所有中断允许位
memset(&SerialBuf,0x00,SERIAL_BUF_LEN);//初始化SerialBuf[SERIAL_BUF_LEN]
/********************************************************
**名称:
SendByte()
**功能:
串口发送一个字节
**输入:
ucData
**返回:
无
**说明:
********************************************************/
voidSendByte(unsignedcharucData)
SBUF=ucData;
TI)
_CLRWDT_;
RS232串口通信程序
unsignedcharcodedispcode1[]={" welcome!
"};
unsignedcharcodedispcode2[]={""};
unsignedchari,j,k,l,DData;
sbitRS=P3^5;
sbitRW=P3^6;
sbitE=P3^7;
unsignedcharm=0;
voiddelay()
{for(l=0;l<=100;l++){}}
voidenable()//writeorder
RS=0;RW=0;E=0;delay();E=1;
voidenable2()//writedata
RS=1;RW=0;E=0;delay();E=1;
voidinitializtion()//lcdinitializtion
for(i=0;i<=100;i++)
P0=0x01;enable();
P0=0x38;enable();
P0=0x0f;enable();
P0=0x06;enable();
voidDisplay(m,DData)//displaydata
P0=0xC0+m; //writeaddress
enable();
P0=DData; //writedata
enable2();
voidEsisr()interrupt4//串口接收中断服务程序
unsignedchartemp;
ES=0;
if(RI==1)
temp=SBUF;//接收数据
SBUF=temp; //将接收到的数据发送至PC机
Display(m,temp);//将接收到的数据送LCD显示
TI);//等待数据发送完成
m++;
if(m>16)
m=0;
ES=1;
voidsystem_initial(void) //systeminitializtion
TMOD=0x21;//定时器1工作方式2,定时器0工作方式1
PCON=0x00;//数据传输率选择。
SCON=0x50;//串口工作方式选择,并打开接收允许。
TH1=0xfd;//定时器赋初值。
TL1=0xfd;//波特率9600bit/s
TR1=1;//启动定时器。
EA=1; //开总中断。
initializtion();
P0=0x80;enable();
for(j=0;j<=15;j++)
P0=dispcode1[j];
P0=0xC0;enable();
for(k=0;k<=15;k++)
P0=dispcode2[k];
system_initial();
(1);
RS232串口通信单片机接收发送数据的C51程序
这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收和查询发送。
关于RS232串口通信原理详解见:
关于单片机串口控制寄存器设置见:
#definelength4 //数据长度
unsignedcharinbuf[length];
unsignedcharchecksum,counter;
bitflag=0; //取数标记
init_serial(); //串行口初始化
if(flag!
=0) //如果取数标志已置位,
就将读到的数从串口发出
flag=0; //取数标志清0
send_string(inbuf,length); //向串口发送字符串
/*串行口初始化*/
voidinit_serial(void)
SCON=0x50; //串行工作方式1,8位异步通信方式
TMOD|=0x20; //定时器1,方式2,8位自动重装
PCON|=0x80; //SMOD=1,表示数据传输率加倍
TH1=0xF4; //数据传输率:
4800fosc=11.0592MHz
IE|=0x90; //允许串行中断
TR1=1; //启动定时器1
/*向串口发送一个字符*/
voidsend_char(unsignedcharx)
SBUF=x;
/*向串口发送
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1