Dotcpp  >  编程教程  >  混合例程  >  再次熟悉串口

再次熟悉串口

点击打开在线编译器,边学边练

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


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


本文固定URL:https://www.dotcpp.com/course/404

单片机教程
第一章 单片机入门
第二章 LED及入门
第三章 蜂鸣器
第四章 数码管
第五章 独立按键
第六章 多文件编程
第七章 外部中断
第八章 定时器
第九章 舵机与超声波模块
第十章 串口通信
第十一章 1602液晶屏
第十二章 IIC通信
第十三章 红外遥控与温度传感器
第十四章 AD与DA
第十五章 混合例程
第十六章 完结
Dotcpp在线编译      (登录可减少运行等待时间)