1.题目要求
这次我们使用串口来实现液晶屏功能函数的执行,也就是说我们电脑端发送字符串“LcdFullClear();”给单片机,单片机就让液晶屏执行整屏清除;电脑端发送“LcdShowStr(1,0,"Good Good Study");”给单片机,液晶屏就在第一行显示“Good Good Study”。需要注意的是,我们的代码对这两个功能函数的判别是有严格规定的,如果发送的字符串中间有多出的空格,
也就是说当“LcdShowStr(1, 0, "Good Good Study");”逗号之间多出空格单片机则无法正常执行功能代码,所以要严格按照要求来发送字符串才能实现功能代码。
下面的代码笔者就不一一讲解实现的原理了,大家先下载进开发板,然后跟着教程去实践,后面再回过头分析原理。
2.main.c测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | #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!”。
我们在电脑端的串口调试助手上输入清屏函数的字符串
点击发送即可看到液晶屏显示的内容全部清屏。
接着如果我们要在哪个地方显示什么内容,那么在串口调试助手中输入类似这样的字符串“LcdShowStr(0,0,"DAN PIAN JI!");”,记住逗号之间不要留有空格。
点击发送就可以看到液晶屏上显示“DAN PIAN JI!”了。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程