串口是非常常用的一个调试工具,我们都必须熟练使用串口的各个功能。


1.题目要求和解决方案

我们要做的是,电脑端发送字符串过来给单片机,然后单片机这边接收完之后要回复给电脑端,回复内容为“接收完成!”。单片机这边把接收到的数据存放在定义好的全局变量数组里面,我们可以通过按K4发送回去给电脑端查看刚刚接收到的内容并把它显示出来。

我们要知道,一个汉字是需要两个字节内存的,比如电脑端发送的字符串为“好好学习,天天向上!”其中的两个标点符号也是中文输入法打上的话,一个标点符号也是占用两个字节,这个字符串就是一共占用10*2=20个字节内存。

那么怎样判断是否把字符串的数据都接收完成了呢?我们参考了宋老师的编程思想,使用定时计数器,也就是让定时器0使用工作模式1计时,接收到第一个数据的时候我们先把TH0和TL0清0,然后打开定时器开始计时,当接收到第二个数据的时候又把TH0和TL0清0让他们从0开始再次计时,直到当TH0大于等于200的时候证明时间过去了50ms左右( 200*256*(12/11059200)= 0.055秒 ),如果在这50ms里面都不再接收地到数据,那么断定已经把字符串的数据都接收完成。

我们程序里定义的数组有关键字pdata,大家在《手把手教你学51单片机》文档10.4节了解一下知识点即可。


2.main.c测试代码

#include <reg52.h> 
#include <function.h> //详见第六章第8讲
#include <uart.h>     //详见第十章第4讲
 
u8 uart_i=0;
u8 pdata RXDBUF[64];
void COUNT_TIMES()
{
    TMOD&=0xF0;    //清0低四位
    TMOD|=0x01;    //设置定时器0为工作模式1
}
 
void main()
{    
    u8 key,x;
    KEY_Init();    //初始化按键模块
    EA = 1;        //闭合总中断开关
    COUNT_TIMES(); //初始化计数器
    ConfigUART(9600);
   
    while(1)
    {  
        key=KEY_Scan(0,500);
        if(key==4)
        {
            printf_str("收到的内容为:\r\n");
            printf_str(RXDBUF);                 //把接收到的字符串发送给电脑端
            for(x=0;x<64;x++)RXDBUF[x]=0x00;    //发送完接收到的字符串之后,内存区全部清除数据,统一改为0x00以便下次接收新的字符串
        }
        
        if(TH0>=200)                            //判断是否把数据接收完毕
        {
            TR0=0;                              //关闭定时器,停止计时
            printf_str("\r\n接收完成!\r\n"); 
           
            RXDBUF[uart_i]='\0';                //增加结束符,满足了“printf_str(RXDBUF);”该发送多少数据就是多少
            uart_i=0;                           //uart_i归0是为了下次接收新的字符串是从RXDBUF[0]开始存取数据
            TH0=0;                              //清零定时器的寄存器,下次再从0开始计时  
            TL0=0;     
        }
    } 
}
 
void InterruptUART() interrupt 4
{  
    if (RI)   //接收到字节
    {
        RI = 0;
   
        TH0=0;//每接收到一个字节数据,就清0寄存器的值,定时时间又是从0开始计时,直到TH0大于等于200的时候,
        TL0=0;//时间超过50ms,也就是没有再接收到数据,因为接收到数据都会进入“if (RI)”把TH0和TL0清0,TH0大于等于200,
              //超出了等待时间,证明后面没有数据发送过来了   
        TR0=1;//接收到第一个数据就打开定时器开始计时,后面接收到第二,第三个数据照样打开定时器计时,直到在主函数里面被关闭为止
   
        RXDBUF[uart_i]=SBUF;//接收一个字节数据
        uart_i++;           //RXDBUF从0号元素不停往下存取数据   
    }
}


3.实验现象

我们先把串口调试助手的设置选项选好

串口1


打开串口之后,在输入框打上“好好学习,天天向上!”,点击发送,可以看到如下界面

串口2


我们在开发板上按下K4,把刚才接收到的字符串发送回来给电脑端显示出来

串口3


如果不断按K4,将没有显示新的内容,因为程序里一但把上次的数据发送给电脑端显示就清除掉这些数据了,我们接着不断按K4会有如下所示

串口4


只有再次发送内容,再按K4才会显示新的内容

串口5

点赞(0)

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

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

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

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

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

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

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

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

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