文章目录

  • 前言
  • 一、串口概念
  • 二、中断中的RI、TI和SUBF
  • 1.RI
  • 2.TI
  • 3.SUBF
  • 三、串口波特率的计算
  • 四、代码的编写
  • 总结

  • 前言

    今天将为大家讲解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中有非常重要的重要,希望大家都能够将他掌握。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 51单片机串口使用

    发表评论