前言
今天将为大家讲解51单片机的串口原理及代码编写。
一、串口概念
51单片机串口是一种通信接口,它可以将51单片机与外部设备连接起来,实现数据的双向传输。51单片机串口的原理是,51单片机的串口接口由两个管脚组成,一个是RXD,另一个是TXD,RXD用于接收数据,TXD用于发送数据。当51单片机接收到外部设备发送的数据时,它会将数据放入串口缓冲区,然后通过RXD管脚将数据发送到51单片机的内部。当51单片机要发送数据时,它会将数据放入串口缓冲区,然后通过TXD管脚将数据发送到外部设备。
通过串口我们就能实现单片机和PC机的通信了。
二、中断中的RI、TI和SUBF
1.RI
RI是接收标志位,当51单片机接收到外部设备发送的数据时,RI会被置位。
当进行下一次接收时需要手动将RI清零。
2.TI
TI是发送标志位,当51单片机要发送数据时,TI会被置位。
当进行下一次发送时需要手动将TI清零。
3.SUBF
SBUF是串口缓冲区,它用于存放51单片机接收到的数据和要发送的数据。
SBUF一次只能发送和接收一个字节的数据。
三、串口波特率的计算
51单片机串口波特率的计算方法是:波特率=时钟频率/(16*(256-波特率寄存器值))。其中,时钟频率是51单片机的时钟频率,波特率寄存器值是51单片机的波特率寄存器的值。
一般我们是不会自己去计算串口的波特率的,我们使用STC-isp这个软件来帮助我们生成相应的代码。
STC-isp软件:
在STC-isp中可以帮助我们去生成对应的代码。
我们只需要注意波特率和系统频率等重要参数选择即可。
生成代码后将代码复制到自己的工程中就行了。
四、代码的编写
串口初始化代码
/******************************************************************************* * 函 数 名 : uart_init * 函数功能 : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间 * 输 入 : baud:波特率对应的TH、TL装载值 * 输 出 : 无 *******************************************************************************/ void uart_init(u8 baud) { TMOD|=0X20; //设置计数器工作方式2 SCON=0X50; //设置为工作方式1 PCON=0X80; //波特率加倍 TH1=baud; //计数器初始值设置 TL1=baud; ES=1; //打开接收中断 EA=1; //打开总中断 TR1=1; //打开计数器 }
串口中断函数
每当串口接收或者发送一个字符串时都会进入串口中断。
RI和TI在上面我们已经说到过了,这里我就直接使用了。
这里定义一个busy发送标志位当在发送数据时busy=1代表串口进入了忙状态,当串口成功发送完一个字符时busy=0,进入空闲状态,这样可以保证我们每一个字符都被成功的发送出去。
定义一个buf用于接收PC机给单片机发送的数据。每当发生一次接收中断都会将接收到的字符串放入buf中。
bit busy = 0;//发送标志位 unsigned char buf[30];//接收缓冲区 void serial_handle() interrupt 4 { if(TI) { TI = 0; busy = 0;//进入空闲状态 } else if(RI) { buf[i] = SBUF; i = (i + 1) % 30; } }
发送一个字符和发送字符串函数
发送一个字符非常的简单,只需要将要发送的字符放入SBUF中即可。
发送一个字符串就是将字符串中的一个个的字符发送出去就可以了,这里用到了指针的操作不熟悉的小伙伴可以去复习一下C语言。
void SendData(unsigned char dat) { while(busy); busy = 1;//进入忙状态 SBUF = dat; } void SendString(char *s) { while(*s) { SendData(*s++); } }
发送测试
void main(void) { /*主函数*/ uart_init(0XFA); while(1) { SendString("Hello World\r\n"); delayms(1000); } }
效果:
每隔一秒就打印一次Hello World。
接收测试:
if(strcmp(buf, "LED1 ON") == 0) { P2 = 0xfe; memset(buf, 0, sizeof(buf)); }
在串口助手上发送LED1 ON让LED1打开,使用串口的数据后使用memset函数清空buf缓冲区,因为缓冲区的大小都是有限的,所以需要我们手动清空缓冲区。
总结
串口在debug中有非常重要的重要,希望大家都能够将他掌握。