51单片机串口使用

简介: 51单片机串口使用

前言

今天将为大家讲解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软件:

image.png

在STC-isp中可以帮助我们去生成对应的代码。

我们只需要注意波特率和系统频率等重要参数选择即可。

image.png

生成代码后将代码复制到自己的工程中就行了。

四、代码的编写

串口初始化代码

/*******************************************************************************
* 函 数 名       : 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。

image.png

接收测试:

  if(strcmp(buf, "LED1 ON") == 0)
  {
    P2 = 0xfe;
    memset(buf, 0, sizeof(buf));
  }

image.png

在串口助手上发送LED1 ON让LED1打开,使用串口的数据后使用memset函数清空buf缓冲区,因为缓冲区的大小都是有限的,所以需要我们手动清空缓冲区。

总结

串口在debug中有非常重要的重要,希望大家都能够将他掌握。

相关文章
|
6月前
|
芯片
STC15F100E单片机模拟串口
STC15F100E单片机模拟串口
STC15F100E单片机模拟串口
|
内存技术
单片机(MCU)如何才能不死机之串口Overrun
单片机(MCU)如何才能不死机之串口Overrun
|
1月前
【通信协议讲解】单片机基础重点通信协议解析与总结之串口通信(三)
【通信协议讲解】单片机基础重点通信协议解析与总结之串口通信(三)
|
5月前
单片机IO口模拟串口实现原理
单片机IO口模拟串口实现原理
70 5
|
6月前
|
网络协议 Linux
嵌入式单片机开源的串口示波器实现方法
嵌入式单片机开源的串口示波器实现方法
56 0
STM32F0单片机快速入门六 用库操作串口(UART)原来如此简单
STM32F0单片机快速入门六 用库操作串口(UART)原来如此简单
STM32F0单片机快速入门七 串口(UART)操作从轮询到中断
STM32F0单片机快速入门七 串口(UART)操作从轮询到中断
STM32F0单片机快速入门七 串口(UART)操作从轮询到中断
|
C语言
简单的C语言宏定义结合全局变量的方法实现单片机串口实现透传模式
简单的C语言宏定义结合全局变量的方法实现单片机串口实现透传模式
97 0
【单片机期中测试】13.串口通信的应用(2)—— 超声波通过串口返回数据
【单片机期中测试】13.串口通信的应用(2)—— 超声波通过串口返回数据
103 0
|
存储
如何编写一个可变参数函数?如何让所有单片机的所有串口实现printf函数?
如何编写一个可变参数函数?如何让所有单片机的所有串口实现printf函数?
187 0