UAV2101~2105串行通信训练
串口自学参考连接(串口通信详解、51单片机串口通信原理)
https://blog.51cto.com/u_15260779/2879124
https://blog.csdn.net/qq_41780295/article/details/124042130
训练001、使用串口调试助手,由PC机发送数据(HEX格式)到单片机通信,不开中断,运用查询法任意点亮LED。11.0592M晶振,波特率9600。
建议使用开发板测试,如果运用Proteus仿真,则需要搭建虚拟串口(运用VSPD),虚拟COM1和COM2并短接,Proteus仿真使用COM1,串口助手发送COM2
#include <reg52.h> void main() { SCON = 0x50; //配置工作方式1,REN=1允许接收 TMOD = 0x20; //T1工作于方式2,定时方式 TH1 = 0xfd; //定时器装初值 TL1 = 0xfd; TR1 = 1; //开定时器1 while(1) { if(RI == 1) { RI=0; //清除接收标志 P0 = SBUF; } } }
训练002、使用串口调试助手,由PC机发送数据(HEX格式)到单片机通信,开中断,运用中断法任意点亮LED。
#include <reg52.h> void main() { SCON = 0x50; //配置工作方式1,REN=1允许接收 TMOD = 0x20; //T1工作于方式2,定时方式 TH1 = 0xfd; //定时器装初值 TL1 = 0xfd; TR1 = 1; //开定时器1 ES = 1;//开串口中断 EA = 1;//开总中断 while(1) { ; } } void Uart() interrupt 4 { RI=0; //清除接收标志 P2 = SBUF; }
训练003、单片机发送数据到PC机通信,不开中断,运用for语句实现任意字符发送。11.0592M晶振,波特率9600。
#include <reg52.h> unsigned char Tab[]="STC89C52RC\nUart Test !\r"; //unsigned char Tab[]={'1','2','3','4','5','o','k'};//定义了向PC机发送的数组 unsigned char i; void delay(unsigned int z) //当z=1,延迟时间10ms { unsigned char i,j,k; for(i=z;i>0;i--) for(j=4;j>0;j--) for(k=248;k>0;k--); } void main() { SCON = 0x40; //配置工作方式1,REN=0禁止接收 PCON |= 0x80; //SMOD=1,波特率加倍 TMOD = 0x20; //T1工作于方式2,定时方式 TH1 = 0xfa; //定时器装初值 TL1 = 0xfa; TR1 = 1; //开定时器1 while(1) { for(i=0;i<24;i++) { SBUF = Tab[i]; while(!TI);//等待发送完 TI=0; //清除发送结束标志 } // SBUF= '\r' ; //'\r'回车'\n'换行 // while(!TI); //等待发送完 // TI=0; //清除发送结束标志 delay(50); } }
训练004、单片机发送数据到PC机通信,开中断,运用字符串发送子函数,实现任意字符发送。11.0592M晶振波特率9600。
#include <reg52.h> bit busy; void SendData(unsigned char dat) { while(busy);//判断是否忙 busy =1; SBUF = dat; } void SendString(char *s) { while (*s) //Check the end of the string { SendData(*s++); //Send current char and increment string ptr } } void main() { SCON = 0x40; //配置工作方式1,REN=0禁止接收 PCON |= 0x80; //SMOD=1,波特率加倍 TMOD = 0x20; //T1工作于方式2,定时方式 TH1 = 0xfa; //定时器装初值 TL1 = 0xfa; TR1 = 1; //开定时器1 ES = 1; //开串口中断 EA = 1; //开总中断 SendString("STC89C52RC\r\nUart Test !\r\n"); while(1); } void uart() interrupt 4 { if(TI) { TI = 0; busy = 0; } }
训练005、简单的串口回环程序,PC机发送数据到单片机通信,并且单片机返回数据给PC机
简单的串口回环程序,它能够将从串口接收到的数据原样发送回去。在这段代码中,使用了 UART_Init() 函数来初始化串口,UART_SendByte() 函数用于发送一个字符,UART_ReceiveByte() 函数用于接收一个字符。main() 函数是程序的主入口,通过循环不断从串口接收数据并发送回去。
#include <reg52.h> // 定义串口波特率 #define BAUDRATE 9600 // 计算波特率产生器的值 #define BRL_VALUE (256 - (11059200 / 12) / 32 / BAUDRATE) // 初始化串口函数 void UART_Init() { TMOD = 0x20; // 设置定时器1为模式2 TH1 = BRL_VALUE; // 设置波特率 SCON = 0x50; // 串口工作在模式1,允许接收 TR1 = 1; // 启动定时器1 } // 串口发送函数 void UART_SendByte(unsigned char dat) { SBUF = dat; // 将数据写入SBUF寄存器 while (!TI); // 等待发送完成 TI = 0; // 清除发送完成标志 } // 串口接收函数 unsigned char UART_ReceiveByte() { while (!RI); // 等待接收完成 RI = 0; // 清除接收标志 return SBUF; // 返回接收到的数据 } // 主程序 void main() { unsigned char dat; UART_Init(); // 初始化串口 while (1) { dat = UART_ReceiveByte(); // 从串口接收数据 UART_SendByte(dat); // 将接收到的数据发送回去 } }
训练006、PC机发送数据到单片机通信,并且单片机返回数据给PC机,通过串行调试助手接收端返回显示(SCON=0x50允许接收),LED显示出来
#include <reg52.h> bit busy; unsigned char uart_data; void SendData(unsigned char dat) { while(busy); busy =1; SBUF = dat; } void SendString(char *s) { while (*s) //Check the end of the string { SendData(*s++); //Send current char and increment string ptr } } void main() { SCON = 0x50; //配置工作方式1,REN=1允许接收 TMOD = 0x20; //T1工作于方式2,定时方式 TH1 = 0xfd; //定时器装初值 TL1 = 0xfd; TR1 = 1; //开定时器1 ES = 1; //开串口中断 EA = 1; //开总中断 SendString("STC89C52RC\r\nUart Test !\r\n"); while(1); } void uart() interrupt 4 { if(RI) { RI = 0; //清除接收中断标志 uart_data = SBUF;//接收数据 P2 = SBUF; //P2显示接收的UART数据 SBUF = uart_data;//返回到PC上位机观察 } if(TI) { TI = 0; //清除发送中断标志 busy = 0; //忙标志位清零 } }
训练007、PC机发送数据到单片机通信,并且单片机返回数据给PC机,通过串行调试助手接收端返回显示(SCON=0x50允许接收),数码管显示出来对应数字
#include <reg52.h> unsigned char Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92, 0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极8段 //#define FOSC 11059200L //System frequency //#define BAUD 9600 //UART baudrate //TH1 = TL1 = -(FOSC/12/32/BAUD); //Set auto-reload vaule char uart_data; void main (void) { SCON = 0x50; /* uart in mode 1 (8 bit), REN=1 */ TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */ TH1 = 0xFD; /* 9600 Bds at 11.059MHz */ TL1 = 0xFD; /* 9600 Bds at 11.059MHz */ ES = 1; /* Enable serial interrupt*/ EA = 1; /* Enable global interrupt */ TR1 = 1; /* Timer 1 run */ while(1); /* endless */ } void serial_IT(void) interrupt 4 { if (RI == 1) { /* if reception occur */ RI = 0; /* clear reception flag for next reception */ uart_data = SBUF; /* Read receive data */ P2 = Tab[uart_data]; SBUF = uart_data; /* Send back same data on uart*/ } else TI = 0; /* if emission occur */ } /* clear emission flag for next emission*/
训练008、实现单片机与单片机通信,需搭建虚拟串口(运用VSPD),虚拟COM1和COM2并短接,分别配置COM1、COM2
/*串口发送与接受一体的控制代码*/
1、在发送端proteus图纸中, 按下按键K1和K2,可以改变要发送的数据num(数值范围0~9),按下K3通过串口发送num数据到接收端。
接收端能够接受数据,并在数码管上显示接受的数字。
2、接收端也可以进行数据的发送,也可以发送数据到发送端,同时发送端也能显示接收到的数据。
#include <REG52.H> #include <intrins.h> //共阳0-F dp-a unsigned char code tab[16]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; #define uchar unsigned char sbit K1=P1^0;//ADD 递增 sbit K2=P1^1;//DEC 递减 sbit K3=P1^2;//DEC 递减 void UartInit(void) //9600bps@11.0592MHz { PCON &= 0x7F; //波特率不倍速SMOD=0 SCON = 0x50; //8位数据,可变波特率,模式1,允许接收 TMOD = 0x20; //设定定时器1,模式2为8位自动重装方式 TL1 = 0xFD; //设定定时初值253 TH1 = 0xFD; //设定定时器重装值 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 ES=1; //开串口中断 EA=1; //开总中断 } char putchar (uchar ch)//向串口发送数据 { SBUF=ch; while(!TI);//查询发生是否完毕 TI=0;//发送完毕,TI由软件清零 return ch; } /******************************************************** 函数功能: 延时c ms 参 数: c 返回 值: 无 *********************************************************/ void delayms( unsigned int ms) //@11.0592MHz { unsigned char i, j; for(;ms>0;ms--) { _nop_(); i = 2; j = 199; do { while (--j); } while (--i); } } uchar Receive_nums=0;//接收到的字符 void Uart1() interrupt 4 { if (RI) { RI=0; //清除RI位 Receive_nums=SBUF; } } void main(void) { uchar Transmit_nums=0;//发送给乙机的数字 UartInit(); while(1) { P0=~tab[Receive_nums];//在数码管上显示数字 if(K1==0)//递增按键 { delayms(10);//消抖 if(K1==0) { Transmit_nums++; if(Transmit_nums>9) Transmit_nums=9; } while(K1==0);//等待按键K1松开 } if(K2==0)//递减按键 { delayms(10);//消抖 if(K2==0) { Transmit_nums--; if(Transmit_nums<1) Transmit_nums=0; } while(K2==0);//等待按键K2松开 } if(K3==0)//发送按键 { delayms(10);//消抖 if(K3==0) { putchar(Transmit_nums); } while(K3==0);//等待按键K3松开 } } }
训练009、实现单片机与PC机通信,11.0592M晶振,波特率9600。实现;两个功能。
1、单片机按键按下,向PC机发送4组1–5五个数
2、PC机控制单片机LED灯的亮灭。