单片机 数据通信 串口
如何去实现一种单片机通过串口方式1进行全双工数据通信的设计呢?其设计思路是怎样的?
回帖(1)
2022-1-26 15:19:22
思考题:
设计两个单片机通过串口方式1进行全双工数据通信,要求将波特率设置为2400,晶振频率为11.0592MHz,请分别编写发送程序和接收程序,接收端需使用液晶屏幕显示接收内容,发送端可循环发送一个字符串(自己定义一个字符串,例如“Welcome to Wuhan”)。
(1)电路图如下:
(2)设计思路:
1、电路:
两个单片机都是用P0口连接LCD1602数据线的0~7位,P20连接寄存器选择位RS,P21连接读写选择位RW,P2^2连接使能位E。然后甲机的RXD连乙机的TXD,甲机的TXD连乙机的RXD。需要注意的是:P0口,P2作为I/O口输出的时候时输出低电平为0输出高电平为高组态(并非5V,相当于悬空状态)。也就是说不能真正的输出高电平,给所接的负载提供电流,因此必须接上拉电阻。
2、程序:
波特率2400,晶振频率为11.0592MHZ,T1工作在方式1,由公式X=256-(fosc/12)(2^SMOD/(322400)),可以算出初值TH1=TL1=244=0xf4。有关LCD1602的相关函数此处就略了!!
2.1甲机发送数据程序说明:
串口首先要初始化,选择方式1,REN允许接收位置1,即SCON=0x50;T1工作在方式2,即TMOD=0x20;波特率不加倍,即PCON=0x00;设置初值TH1=TL1=0xf4;启动T1,即TR1=1。
然后串口发送数据,CPU将数据写入SBUF,即SBUF=dat;再搞一个陷阱while(!TI)来判断是否发完,下一步TI置0;
调用LCD1602的单字符显示函数dis_char(address++,dat) (address刚开始为0x00)发送下一个数据时地址++,(发送完一个数据 就显示一个数据);显示完第一行 就显示第二行;显示完第二行 清屏后又显示第一行;发送完一帧数据 地址就归零 清屏 从头再来。
注意这里清屏之前要延时一下 ,等前面发送的数据显示完了,再清屏!具体请看代码!!!
2.2乙机接收数据程序说明:
首先也是串口的初始化 ,跟楼上甲机是一样的!
然后是串口接收数据,这里是通过串口中断来接收数据的(interrupt 4)。但是有个不足就是得事先知道发送数据的第一个字符;判断当SBUF==发送数据的第一个字符时,这就说明刚接收完一帧数据或者马上开始接收数据,那这时就将地址address置0并将屏幕清屏;然后读SBUF中的数据,调用LCD1602的单字符显示函数dis_char(address++,receive_char) ;再将RI软件置0。最后同发送的显示格式一样,显示完第一行 就显示第二行;显示完第二行 清屏后又显示第一行;接收完一帧数据 地址就归零 清屏 从头再来。
(3)发送程序代码:
/** 功能描述: 甲机发数据!”**/
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define lcd_out P0
/***********端口定义********************************/
***it rs=P2^0;
***it rw=P2^1;
***it e=P2^2;
/***********函数申明***********************************/
void UART_Init(void);
void UART_SendData(uchar dat);
void UART_SendString(uchar *p);
void delay(uint j);
void check_busy(void);
void write_command(uchar com);
void write_data(uchar dat);
void LCD_initial(void);
void dis_char(uchar ad, uchar input);
/***********变量定义********************************/
uchar address=0x00; //显示地址
uchar sting[]="Welcome to Sichuan for hot pot!";
void main(void)
{
LCD_initial(); //LCD1602 初始化
UART_Init(); //串口初始化
while(1)
{
UART_SendString(sting); //发送字符串
address=0x00; //发送完数据 地址就归零 从头再来
delay(1000);
write_command(0x01); //发送完一帧数据 清屏
}
}
//串口初始化
void UART_Init(void)
{
SCON=0x50;
TMOD=0x20;
PCON=0x00;
TH1 =0xf4;
TL1 =0xf4; //预置初值,设波特率为2400
TR1 =1;
}
//串口发送一个字节的数据
void UART_SendData(uchar dat)
{
SBUF=dat; //发送数据
while(!TI); //判断是否发送完
TI=0; //软件清0
delay(100);
dis_char(address++,dat); //发送完一个数据 显示一个数据
if(address==0x10) address=0x40;//显示完第一行 就显示第二行
if(address==0x50){
write_command(0x01);
address=0x00;//显示完第二行 清屏后又显示第一行
}
}
//串口发送多字节数据
void UART_SendString(uchar *p)
{
while(*p!='