1.题目要求

这次我们使用串口来实现液晶屏功能函数的执行,也就是说我们电脑端发送字符串“LcdFullClear();”给单片机,单片机就让液晶屏执行整屏清除;电脑端发送“LcdShowStr(1,0,"Good Good Study");”给单片机,液晶屏就在第一行显示“Good Good Study”。需要注意的是,我们的代码对这两个功能函数的判别是有严格规定的,如果发送的字符串中间有多出的空格,

也就是说当“LcdShowStr(1, 0, "Good Good Study");”逗号之间多出空格单片机则无法正常执行功能代码,所以要严格按照要求来发送字符串才能实现功能代码。

下面的代码笔者就不一一讲解实现的原理了,大家先下载进开发板,然后跟着教程去实践,后面再回过头分析原理。


2.main.c测试代码

#include <reg52.h> 
#include <function.h> //详见第六章第8讲
#include <lcd.h>      //详见第十一章第3讲
#include <uart.h>     //详见第十章第4讲
   
u8 i=0;
u8 pdata RXDBUF[64];
void COUNT_TIMES()
{
    TMOD&=0xF0;   //清0低四位
    TMOD|=0x01;   //设置定时器0为工作模式1
}
 
void UART_LcdFullClear()
{
    if(  RXDBUF[0]== 'L'&&RXDBUF[1]== 'c'&&RXDBUF[2]== 'd'&&RXDBUF[3]=='F'
       &&RXDBUF[4]== 'u'&&RXDBUF[5]== 'l'&&RXDBUF[6]== 'l'&&RXDBUF[7]== 'C'
       &&RXDBUF[8]== 'l'&&RXDBUF[9]== 'e'&&RXDBUF[10]=='a'&&RXDBUF[11]=='r' )                             
    {
        LcdFullClear();//整屏清除
    }
}
 
void UART_LcdShowStr()
{
    u8 lcd_x,lcd_y,z;
   
    if(  RXDBUF[0]=='L'&&RXDBUF[1]=='c'&&RXDBUF[2]=='d'&&RXDBUF[3]=='S'&&RXDBUF[4]=='h'
       &&RXDBUF[5]=='o'&&RXDBUF[6]=='w'&&RXDBUF[7]=='S'&&RXDBUF[8]=='t'&&RXDBUF[9]=='r')                               
    {
        //以下是确定要在哪个位置开始显示,也就是知道坐标位置
        if(RXDBUF[12]>='0'&&RXDBUF[12]<='9') //RXDBUF[11]接收到的肯定是字符'0'~'9',如果RXDBUF[12]接收到的也是字符'0'~'9',
        {                                    //那么可以知道x坐标系是大于等于10的
       
            lcd_x=(RXDBUF[11]-'0')*10;       //比如我们发送的是“LcdShowStr(13,0,"YES");”,
            lcd_x+=RXDBUF[12]-'0';           //则有RXDBUF[11]==‘1’,RXDBUF[12]==‘3’
        }
        else lcd_x=RXDBUF[11]-'0';           //如果x坐标小于10,也就是只是个位数,则只需处理RXDBUF[11]
      
        if(RXDBUF[14]>='0'&&RXDBUF[14]<='9') //如果RXDBUF[12]接收到的是字符'0'~'9',    
        {                                    //那么RXDBUF[13]==',',RXDBUF[14]就是决定y坐标
       
            lcd_y=RXDBUF[14]-'0';
        }      
        else lcd_y=RXDBUF[13]-'0';           //如果RXDBUF[14]接收到的不是字符'0'~'9',那么x坐标为个位数,则由RXDBUF[13]决定y坐标
                                             //以下是判断两种结果,一种是如果x坐标是小于10,也就是只有个位数,
                                             //那么RXDBUF[15]肯定是等于'"',如果x坐标是大于等于10,则RXDBUF[16]才是等于'"'
      
        if(RXDBUF[15]=='"')
        {
            for(z=1; ;z++)
            {
                if(RXDBUF[15+z]=='"')             //当遇到第二个'"'时,表明要显示的字符串已经确定,此时需要添加结束符,然后退出for循环
                {
                    RXDBUF[15+z]='\0';            //添加结束符
                    break;
                }
            }
            LcdShowStr(lcd_x,lcd_y,RXDBUF+15+1);  //如果电脑端这样发送过来“LcdShowStr(0,0,"DAN PIAN JI");”,
                                                  //那液晶屏上要显示的就是“DAN PIAN JI”
        }
        else if(RXDBUF[16]=='"')
        {
            for(z=1; ;z++)
            {
                if(RXDBUF[16+z]=='"')
                {
                    RXDBUF[16+z]='\0';//添加结束符
                    break;
                }
            }
            LcdShowStr(lcd_x,lcd_y,RXDBUF+16+1);
        }    
    }
}
 
void main()
{  
    u8 x;   
    EA = 1;                                  //闭合总中断开关
    COUNT_TIMES();                           //初始化计数器
    ConfigUART(9600);
    InitLcd1602();                           //初始化液晶屏 
    LcdShowStr(1, 0, "Good Good Study");     //第一行显示"Good Good Study"
    LcdShowStr(3, 1, "Day Day Up!");         //第二行显示"Day Day Up" 
   
    while(1)
    {      
        if(TH0>=200)                         //判断是否把数据接收完毕
        {
            TR0=0;                           //关闭定时器,停止计时
        
            UART_LcdFullClear();             //查看串口发送来的信息是否满足清屏的条件
            UART_LcdShowStr();               //查看串口发送来的信息是否满足液晶屏显示字符串的条件
        
            TH0=0;                           //清零定时器的寄存器,下次再从0开始计时  
            TL0=0;
            i=0;                             //i归0是为了下次接收新的字符串是从RXDBUF[0]开始存取数据
            for(x=0;x<64;x++)RXDBUF[x]=0x00; //内存区全部清除数据,统一改为0x00以便下次接收新的字符串
        }
    } 
}
   
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[i]=SBUF; //接收一个字节数据
        i++;            //RXDBUF从0号元素不停往下存取数据   
    }
}


3.实践操作

首先下载进开发板看到液晶屏显示有“Good Good Study  Day Day Up!”。

我们在电脑端的串口调试助手上输入清屏函数的字符串

串口7

点击发送即可看到液晶屏显示的内容全部清屏。


接着如果我们要在哪个地方显示什么内容,那么在串口调试助手中输入类似这样的字符串“LcdShowStr(0,0,"DAN PIAN JI!");”,记住逗号之间不要留有空格。

串口8

点击发送就可以看到液晶屏上显示“DAN PIAN JI!”了。

点赞(0)

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

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

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

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

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

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

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

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

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