在讲解本章的内容之前请大家先反复阅读《手把手教你学51单片机》文档的第11章内容,很多概念文档都已详细讲解有。


1.波特率

串口通信就是单片机与电脑端,单片机与单片机,单片机与模块器件之间互发信息进行通信,比如单片机发送一个“1”的字符给电脑端,电脑端的窗口就会接收到“1”。我们常用的波特率为9600,所谓9600指的是一秒钟单片机可以发送9600个数据位,也就是1秒钟的时间里单片机可以发送(9600/8)=1200字节。

如果我们想发送一个字符“A”给电脑端的窗口,那么字符“A”对应的ASCII值就是65,二进制表示为01000001。


2.通信引脚

单片机的P3.1是发送引脚,也就是说要发送字符“A”,这个引脚的变化如下图所示

串口通信1

单片机要发送一个字节给电脑端,首先发送引脚需要先拉高,然后拉低持续(1/9600)秒,电脑端检测到这个低电平信号就会准备接收数据字节。然后我们要发送的二进制位是01000001,但是串口通信发送的字节是低位在前,高位在后,所以上图的发送顺序就是01000001反过来为10000010。一个字节发送完成之后还要发送一个停止位1,电脑端接收到这个停止位就认为一个字节发送完成了。

我们用定时器来实现引脚的持续时间,怎么定时(1/9600)秒怎么设置,计算一下就可以了

(1/9600)=X*(12/11059200)

解得X=96。

因为定时时间间隔比较短,所以我们使用定时器0的工作模式2就可以了。填充TH0的初始值就是256-96=160=0xA0。

因为P3.1在“#include<reg52.h>”已有定义为TXD,我们直接用即可。通过按K4来启动发送字节数据。


3.代码

#include <reg52.h> 
#include <function.h>//详见第六章第8讲
#include <timer.h>   //详见第八章第11讲
 
void TIM0_Mode2_Init()
{
    TMOD&=0xF0;   //清0低四位
    TMOD|=0x02;   //设置定时器0为工作模式2
    TH0 = 0xA0;   //计算出波特率9600
    TL0 = 0xA0;
    ET0 = 1;      //闭合定时器0中断的开关
    TR0 = 1;      //启动定时器0 
}
 
void main()
{  
    u8 key;
    LED_Init();        //初始化LED硬件模块
    KEY_Init();        //初始化按键模块
    EA = 1;            //闭合总中断开关
    TIM0_Mode2_Init(); //定时(1/9600)秒
    TR0 = 0;           //先关闭定时器
    while(1)
    {  
        key=KEY_Scan(0,1000);
        if(key==4)TR0 = 1;//开启定时器启动一次字节传输,按一次发送一次。    
    } 
}
 
void TIM0_IRQHandler()  interrupt 1   
{
    static u8 cnt=0,i,TXDBUF=65; //字符“A”的ASCII值为65
    cnt++;                       //cnt一直在1~10之间变化
  
    if(cnt==1)TXD=0;             //cnt变为1,发送起始位,这次的中断函数就执行完了,持续够(1/9600)秒之后,再次进入中断函数,然后就是进入发送数据字节的8位的任务
  
    if (cnt>=2 && cnt<=9)        //发送8位数据位,从低位开始引脚的变化为 1 0 0 0 0 0 1 0
    {
        TXD = TXDBUF & 0x01;     //“TXDBUF & 0x01”的表达式就是,要么等于1要么等于0,这样P3.1的引脚要么保持高电平,要么保持低电平
        TXDBUF >>= 1;   
    }
  
    if (cnt == 10)
    {  
        TXD = 1;     //发送停止位
        TR0 = 0;     //关闭定时器,结束一次字节传输
        cnt=0;
        i++;
        TXDBUF=65+i; //下次按按键发送的是 B C D E···     
    }
}

大家可能对中断函数里的内容感到艰涩难度,这里简单说明一下,我们按下K4启动了定时器,然后第一次进入中断函数时,做的任务就是拉低P3.1,然后这次的中断函数的任务就结束了,等过了(1/9600)秒之后,再次进入中断函数,上一次拉低P3.1的时间已经持续够(1/9600)秒了,这第二次的中断函数任务就是拉高P3.1,因为发送字符A这个字节的最低位为1,持续够(1/9600)秒进入第三次执行中断函数,拉低P3.1,第四,第五,第六,第七都是拉低P3.1发送0,以此类推,到第10次中断函数执行就是拉高P3.1发送停止位,关闭定时器结束一次字节的传输,要想再次发送需要按K4启动定时器,“TXDBUF=65+i;
”表示下次发送的是66这个数据,再下次就是发送67······


4.软件设置

在软件界面选择串口助手,选用字符格式显示,查看波特率是否为9600,最后点击“打开串口”。

串口通信2


不断地间隔按K4,就会看到电脑端显示出单片机发送过来的字符数据

串口通信3

点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)