历史上的今天
返回首页

历史上的今天

今天是:2024年08月31日(星期六)

2021年08月31日 | 51单片机-串口&液晶屏Ⅲ

2021-08-31 来源:eefocus

1.题目要求


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


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


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


2.main.c测试代码


#include  

#include //详见第六章第8讲

#include       //详见第十一章第3讲

#include      //详见第十章第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]='';            //添加结束符

                    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]='';//添加结束符

                    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!”。


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

15.8.png?imageView2/2/w/550

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


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

15.9.png?imageView2/2/w/550

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

推荐阅读

史海拾趣

Avel Lindberg公司的发展小趣事

由于我无法直接获取Avel Lindberg公司的详细发展资料,因此我无法直接为您撰写5个关于该公司发展起来的具体故事。不过,我可以为您提供一个通用的故事框架,您可以根据这个框架结合公司的公开信息来撰写相关故事。

Avel Lindberg公司发展故事框架

  1. 创业初期: 描述Avel Lindberg公司成立的背景,包括创始人或核心团队的愿景、行业趋势以及初始产品或服务。可以提及公司如何克服初创期的困难,如资金短缺、市场竞争激烈等问题,逐渐在市场上站稳脚跟。

  2. 技术突破: 讲述公司在某个关键时期实现的技术突破,这项突破可能是对既有技术的改进,也可能是全新技术的研发。这个突破如何帮助公司打开了新的市场领域,提升了竞争力,成为行业内的领军者。

  3. 合作与扩展: 描述公司如何通过与其他企业、研究机构或高校建立合作关系,来扩大业务范围或提升技术水平。这些合作可能涉及共同研发、市场拓展、品牌建设等方面,对公司的长期发展产生了积极影响。

  4. 国际化战略: 讲述公司如何逐步实施国际化战略,进入海外市场。这包括公司如何分析国际市场的需求和竞争态势,制定合适的市场进入策略,以及在国际市场上取得的成就和面临的挑战。

  5. 社会责任与可持续发展: 介绍公司在发展过程中如何关注社会责任和可持续发展。这可以包括公司在环保、员工福利、社区支持等方面的举措,以及这些举措如何提升了公司的社会形象和品牌价值。

在撰写具体故事时,您可以根据Avel Lindberg公司的实际情况调整上述框架中的内容,并结合公司的官方公告、新闻报道和行业分析报告等资料来丰富细节。同时,请确保所描述的事实准确无误,避免主观评价和猜测。

Harbour Industries公司的发展小趣事

背景:20世纪末,随着电子技术的飞速发展,Handok敏锐地捕捉到了半导体行业的崛起机遇。公司决定投入大量研发资源,专注于开发新型半导体材料和技术。

发展:经过数年的潜心研究,Handok成功研发出一种具有更高导电性和稳定性的新型半导体材料,这一创新成果迅速获得了业界的广泛关注。公司迅速将这项技术应用于生产,推出了一系列高性能的半导体产品,迅速占领了市场的一席之地。

影响:Handok的技术革新不仅推动了公司自身的快速发展,还对整个半导体行业产生了深远的影响,促进了整个产业链的升级和转型。

Dearborn Electronics Inc公司的发展小趣事

随着技术的不断进步,Dearborn Electronics Inc.不断投入研发,推出了一系列具有创新性的产品,如钽电容、陶瓷电容器等。这些产品以其卓越的性能和可靠性赢得了市场的广泛认可。同时,公司也积极拓展市场,将产品销售到全球各地,特别是医疗、石油、交通、工业等严苛应用领域。

Device Engineering Incorporated公司的发展小趣事

在电子行业快速发展的背景下,DEI公司意识到只有不断创新才能保持竞争力。因此,公司加大了对研发的投入,积极引进新技术和人才。通过不断的努力,DEI公司成功推出了一系列具有自主知识产权的创新产品,涵盖了多个领域。这些产品不仅提升了公司的竞争力,也为公司赢得了更多的市场份额。

Amplitronix LLC公司的发展小趣事

Amplitronix LLC的创立,源于两位年轻工程师对电子技术的热爱与执着。他们发现市场上存在一种需求,即高性能、高精度的电子测量仪器。于是,他们决定携手创业,将这个想法付诸实践。初创时期,资金短缺、技术难题、市场竞争激烈,每一道关卡都考验着他们的决心和毅力。但他们凭借着对技术的热情和对市场的敏锐洞察,不断研发创新,最终成功推出了首款产品,赢得了市场的初步认可。

雅特力(Artery)公司的发展小趣事

雅特力在追求经济效益的同时,也高度重视企业社会责任和可持续发展。公司积极参与社会公益事业,通过捐款、捐物等方式支持教育、环保等领域的发展。此外,雅特力还注重环境保护和资源利用,采用环保材料和节能技术,努力降低生产过程中的能耗和排放。这些举措不仅有助于提升公司的社会形象,也为实现可持续发展做出了积极贡献。

问答坊 | AI 解惑

教大家我应该用什么方法设计这个波形发生和控制电路

大家好!我想设计一个电路,可以产生两路同步的波形,还在波形产生到某个点的时候触发一个采集卡采集数据,请问我是用cpld,单片机,arm,fpga,dss,plc中的哪种?因为我要学会了才弄,希望大家给点意见。…

查看全部问答>

终于点亮了我的LCD显示器,1024*768@60Hz,verilog语言,EP2C8,全部源码

昨天几乎一晚没睡,参考了很多代码,现在只是点亮了,没进行美化,我是新手,大家别拍砖,呵呵。 module vga( clock, switch, disp_RGB, hsync, vsync ); input clock; //系统输入时钟 input [1:0]switch; output  [ ...…

查看全部问答>

ARM认证有用么?

请问各位前辈,有ARM认证找工作,企业认不认啊,嵌入式方面都有什么权威认证阿。…

查看全部问答>

嵌入式系统软件反盗版问题

我想知道怎么能做到一套硬件系统唯一对应一套软件,关键硬件没有唯一性,要是cpu或存储器能有个序列号就好办,一般的flash是不都没有串号或者叫序列号?三星的K9F1208U0M好像没有啊!…

查看全部问答>

基于单片机89s51的预应力张拉控制仪的设计

急需,谢谢帮帮忙,传一个到邮箱rap511423713@qq.com!!!!!!!!!!!!!1…

查看全部问答>

上位机(VB6.0)与下位机STM32 USB接口通讯 多谢

请问下,我是用VB6.0做上位机,STM32做下位机。通过上位机VB发送一个指令,下位机(STM32)收到后,执行对应的命令,这是怎么实现的,例如STM32的PB0~PB7分别点亮8个LED发光二极管!从VB中发送出来 地址 &H00,&H01,&H02,&H03,&H04,&H05,&H06, ...…

查看全部问答>

新手时钟程序求助

为啥在lcd1602中,读回来的数不是按递加显示呢? 时钟芯片ds12c8887,使用的是51单片机!请诸位相助解答。…

查看全部问答>

是不是只要是芯片就属于数字电路?对模拟的概念,有点蒙了,求大神指教一二

     以前吧,感觉自己很清楚模拟和数字的概念,最近越来越感觉模糊了^             以前感觉——只要是芯片就属于数字电路,电阻电容搭建起来的电路属于模拟电路。 比如单片机就 ...…

查看全部问答>

2431上传网关的数据中,有最近参考点的短地址,怎么获得的???

CC 2431上传网关的数据中,有最近参考点的短地址,怎么获得的??? …

查看全部问答>

temp6=(int)(Rain*10);这个语句有问题吗?

temp6=(int)(Rain*10);这个语句有问题吗?我的Rain是float类型的 …

查看全部问答>