找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7752|回复: 14
打印 上一主题 下一主题
收起左侧

单片机驱动液晶显示屏的控制系统设计(资料)

  [复制链接]
跳转到指定楼层
楼主
介绍单片机驱动控制液晶显示器(带触摸屏)的控制系统设计实例,支持modbus通讯协议,采用的是51单片机,驱动控制19寸液晶显示器(可以是15寸,17寸,19寸,30寸,52寸,55寸显示器或电视机)。支持单片机TTL电平串口,RS232串口,RS485串口,以太网连接. 液晶显示控制器系统软件使用人机界面组态软件HMImaker开发,主要有操作画面、参数设置画面、参数修改、系统登录画面、状态监控画面等功能,界面可以自由设计开发,组态软件开发显示与操作界面,“0”编程、"所见即所得"、"0"代码、如"制作PPT"一样简单,快速!。
本设计以51单片机作为LCD液晶显示系统控制器为主线,基于单片机8051,采用单片机的C语言来进行软件设计,指令的执行速度快,节省存储空间。为了便于扩展和更改,软件的设计根据单片机的串口通信协议(易显单片机协议),支持modbus通讯协议。采用模块化结构,使程序设计的逻辑关系更加简洁明了。使硬件在软件的控制下协调运作。其次阐述了部分程序的流程图和实现过程。本文撰写的主导思想是软、硬件相结合,以硬件为基础,来进行各功能模块的编写。以下对所开发的用单片机实现LCD液晶显示器控制原理的设计思想和软、硬件调试作了详细的论述。

以下是单片机8051的通讯协议和程序介绍:
#include<Atmel/AT89x52.H>
//定义数据类型(可以是数据结构)
//*************************************************************
void InitUART(void)         //串口初始化使用22.1184M晶体
{
       SCON= 0x50;                 //选择模式18位数据格式,使能UART
      PCON|= 0x80;                 //波特率加倍
      TMOD=TMOD| 0x20;                //定时器1:模式2 ,自动装载初值      
         //波特率计算公式:TH1=TL1=256-(2*22.1184*1000000)/(32*12*baud)
         //若选115200波特率则TH1=TL1=256-(2*22.1184*1000000)/(32*12*115200)=0xff
         //若选19200波特率则TH1=TL1=256-(2*22.1184*1000000)/(32*12*19200)=0xfa
      TH1= 0xfa;                     
      TL1= 0xfa;
         TR1 = 1;                          //定时器1计数使能
         REN = 1;                //允许串口接受使能
}
/*
******************************************************************
* 名称:    write_byte()
* 功能:    向串口发送一个字节的数据
* 入口参数:i为待发送的字节数据
******************************************************************
*/
voidUART_SendByte(unsigned char i)
{
         SBUF=i;          //发送本次数据
         while(TI==0){}//等待发送完毕
    TI=0;
}
#define   m_ReadVarAdr       48          //类型:unsignedint   初始值:40   解释:待读 变量地址
#define   m_WriteAdr         52          //类型:unsignedint   初始值:28   解释:待写变量地址
/////////////////////////////////本文件如有不明白的地方,咨询热线:13829764765. QQ252631158 /////////
//////////////////////////////////////////////////////////////////////////////////
//unsigned int adr表示需要设置的HMI变量的地址,
//unsigned shortnBytes表示需要设置的HMI变量占一个字节的空间,如果是int变量就占4个字节,如果是short变量就占2个字节,如果是char变量就占1个字节
//unsigned char*m_VarP表示你要设置的HMI变量数据源的的指针,指针所指向的内容就是在HMI变量的将要被设置成的内容
//小技巧:有的时候希望通过调用一次SetVariable一次性设置3int变量的HMI变量,只要这3int变量的地址是连续的,那么只要让nBytes=3*4=12个字节就OK
voidSetVariable(unsigned int adr,unsigned short nBytes,unsigned char *m_VarP)
{
    unsigned char temp;
    unsigned short m_CheckCRC;//命令校验
         UART_SendByte(0x81);       //开始,固定,一个字节
         UART_SendByte(0x0);                  //命令类型,设置变量
         UART_SendByte(0x2);                  //接收方的设备号
         m_CheckCRC=0x81+0x0+0x2;//前面三个字节的校验和
         temp=adr&0xff;
         UART_SendByte(temp);      //地址1
         m_CheckCRC=m_CheckCRC+temp;//每发送一个字节,计算一次校验和
         temp=(adr>>8)&0xff;
         UART_SendByte(temp);      //地址2
         m_CheckCRC=m_CheckCRC+temp;
         temp=0;
         UART_SendByte(temp);      //地址3      固定为0
         m_CheckCRC=m_CheckCRC+temp;
         temp=0;
         UART_SendByte(temp);      //地址4      固定为0
         m_CheckCRC=m_CheckCRC+temp;     
         temp=(nBytes)&0xff;
         UART_SendByte(temp);      //个数低8
         m_CheckCRC=m_CheckCRC+temp;                        
         temp=(nBytes>>8)&0xff;
         UART_SendByte(temp);      //个数高8
         m_CheckCRC=m_CheckCRC+temp;     
         while(nBytes!=0)
         {
            temp=*m_VarP;
                   UART_SendByte(temp);      
                   m_CheckCRC=m_CheckCRC+temp;     
            nBytes--;
            m_VarP++;
         }
         UART_SendByte(m_CheckCRC);
         UART_SendByte(m_CheckCRC>>8);
}
//unsigned int adr表示需要查询的HMI变量的地址,
//unsigned shortnBytes表示需要查询的HMI变量占多少个字节的空间,如果是int变量就占4个字节,如果是short变量就占2个字节,如果是char变量就占1个字节
//小技巧:有的时候希望通过调用一次ReadVariable一次性读取3int变量的HMI变量,只要这3int变量的地址是连续的,那么只要让nBytes=3*4=12个字节就OK
void ReadVariable(unsignedint adr,unsigned short nBytes)
{
    unsigned char temp;
    unsigned short m_CheckCRC;//命令校验
         UART_SendByte(0x81);       //开始,固定,一个字节
         UART_SendByte(0x1);                  //命令类型,查询变量
         UART_SendByte(0x2);                  //接收方的设备号
         m_CheckCRC=0x81+0x1+0x2;//前面三个字节的校验和
         temp=adr&0xff;
         UART_SendByte(temp);      //地址1
         m_CheckCRC=m_CheckCRC+temp;     //每发送一个字节,计算一次校验和
         temp=(adr>>8)&0xff;
         UART_SendByte(temp);      //地址2
         m_CheckCRC=m_CheckCRC+temp;
         temp=0;
         UART_SendByte(temp);      //地址3       固定为0
         m_CheckCRC=m_CheckCRC+temp;
         temp=0;
         UART_SendByte(temp);      //地址4       固定为0
         m_CheckCRC=m_CheckCRC+temp;     
         temp=(nBytes)&0xff;
         UART_SendByte(temp);      //个数低8
         m_CheckCRC=m_CheckCRC+temp;                        
         temp=(nBytes>>8)&0xff;
         UART_SendByte(temp);      //个数高8
         m_CheckCRC=m_CheckCRC+temp;     
         UART_SendByte(m_CheckCRC);
         UART_SendByte(m_CheckCRC>>8);
}
unsigned charmIndex=0;           //定义一个数据索引
unsigned charmCmdAdrBuf[4];    //定义一个缓冲区用于缓冲HMI变量地址
unsigned charmCmdnBytesBuf[2]; //定义一个缓冲区用于缓冲HMI变量字节数量
unsigned charmHmiVarBuf[4];    //定义一个缓冲区用于缓冲HMI变量m_ReadVarAdr内容,因为该变量是4个字节的int变量
unsigned charmHmiVarCheck[2];
unsigned charmReceiveFlag=0;   //串口中断成功接收到一个HMI变量设置命令标志
unsigned charmState=0;                //命令接收状态
unsigned shortmCheckHe;
unsigned intdelay=0;//延时变量
void main(void)
{
     InitUART();
          EA=1; //打开中断总开关,
          ES=1; //打开串口中断
          //ET0=1;//打开定时器中断,每隔50MS中断一次
          while(1) //进入不断循环
          {
            delay++;
                   if(delay>=65535)//延时一段时间(300MS)
                   {
                       delay=0;
                            ReadVariable(m_ReadVarAdr,4);//读取HMI变量命令发出去。本例子中m_ReadVarAdr的地址是48,是一个unsigned int 变量,占4个字节
                   }
                   if(mReceiveFlag==1)//如果接收到数据
                   {
                            mReceiveFlag=0;
                            SetVariable(m_WriteAdr,4,mHmiVarBuf);
                   }
          }
}
unsigned charbufcom1;
void uart(void)interrupt 4
{
         if(RI==0)    return;
                    RI=0;
                    bufcom1=SBUF;//读串口一的上的数据
                    if(mState==0)//阶段0,等待接收0x81,命令开始
                    {     
                       mCheckHe=0x81;
                            if(bufcom1==0x81)//如果收到0x81,就进入阶段1
                            {
                               mState=1;
                            }
                            else mState=0;//接收错误,跳回阶段0
                    }
                    else if(mState==1)//阶段1,等待接收0x0,是否是工控机发过来的“设置变量命令”
                    {
                       mCheckHe=mCheckHe+bufcom1;
                            if(bufcom1==0x0)// 是工控机发过来的“设置变量命令”,就进入阶段2
                            {
                               mState=2;
                            }
                            else mState=0;//接收错误,跳回阶段0
                    }
                    else if(mState==2)      //阶段2,等待接收0x2,是否是工控机发过来的设备号
                    {
                       mCheckHe=mCheckHe+bufcom1;
                            if(bufcom1==0x2)
                            {
                               mState=3;
                               mIndex=0;// 先清0索引,为阶段3做准备
                            }
                            else mState=0; //接收错误,跳回阶段0
                    }
                    else if(mState==3)      //阶段3,等待接收地址,4个字节
                    {
                           mCheckHe=mCheckHe+bufcom1;
                            mCmdAdrBuf[mIndex]=bufcom1;
                            mIndex++;
                            if(mIndex==4)  //已经接完4个字节的地址
                            {
                               mState=4;
                               mIndex=0;// 先清0索引,为阶段4做准备
                            }
                    }
                    else if(mState==4)      //阶段4,等待接收字节数,2个字节
                    {
                       mCheckHe=mCheckHe+bufcom1;
                            mCmdnBytesBuf[mIndex]=bufcom1;
                            mIndex++;
                            if(mIndex==2)  //已经接完2个字节
                            {
                              if((mCmdnBytesBuf[0]==4)&&(mCmdnBytesBuf[1]==0))//如果收到的是4个字节数据
                               {
                                        mState=5;
                                        mIndex=0;// 为阶段5做准备
                               }
                               else mState=0; //接收错误,跳回阶段0
                            }
                    }
                    else if(mState==5)      //阶段5,等待接收4个数据
                    {
                       mCheckHe=mCheckHe+bufcom1;
                            mHmiVarBuf[mIndex]=bufcom1;
                            mIndex++;
                            if(mIndex==4)  //已经接完4个字节
                            {
                                     mState=6;
                                     mIndex=0;//为阶段6做准备
                            }
                    }
                    else if(mState==6)      //阶段6,接收2个数据校验和
                    {
                            mHmiVarCheck[mIndex]=bufcom1;
                            mIndex++;
                            if(mIndex==2)  //已经接完2个字节
                            {
                                     mState=0;  //接收完毕,从头开始
                                     if(mHmiVarCheck[0]==(mCheckHe%256))      //比较校验和低字节
                                        if(mHmiVarCheck[1]==(mCheckHe/256))  //比较校验和高字节
                                          if(mCmdAdrBuf[0]==m_ReadVarAdr%256)  //比较HMI变量地址第0个字节
                                                    if(mCmdAdrBuf[1]==(m_ReadVarAdr/256))  //比较HMI变量地址第1个字节
                                                           if(mCmdAdrBuf[2]==0x0)       //比较HMI变量地址第2个字节
                                                              if(mCmdAdrBuf[3]==0x0) //比较HMI变量地址第3个字节
                                                                  {
                                                                       mReceiveFlag=1;//如果地址和校验和没问题,表示已经成功读到了工控机的m_ReadVarAdr变量
                                                              }
                            }
                    }
                    else mState=0;

}





单片机驱动液晶显示屏的控制系统设计(资料).zip (966.77 KB, 下载次数: 90)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:59400 发表于 2014-6-20 13:53 来自手机 | 只看该作者
厉害。
回复

使用道具 举报

板凳
ID:66741 发表于 2014-9-28 11:30 | 只看该作者

谢谢楼主!!
回复

使用道具 举报

地板
ID:68230 发表于 2014-11-1 17:08 来自手机 | 只看该作者
流程图及电路连接图?
回复

使用道具 举报

5#
ID:67697 发表于 2014-12-2 11:25 | 只看该作者
谢谢分享
回复

使用道具 举报

6#
ID:70708 发表于 2015-1-10 23:21 | 只看该作者
学习了。。。。。
回复

使用道具 举报

7#
ID:78086 发表于 2015-4-26 21:52 | 只看该作者
很给力
回复

使用道具 举报

8#
ID:78086 发表于 2015-4-26 21:52 | 只看该作者
不错的
回复

使用道具 举报

9#
ID:80089 发表于 2015-6-5 09:11 | 只看该作者
回复

使用道具 举报

10#
ID:98045 发表于 2015-12-2 17:53 | 只看该作者
厉害,来学习一下
回复

使用道具 举报

11#
ID:163931 发表于 2017-3-26 23:33 | 只看该作者
不错,谢谢楼主!
回复

使用道具 举报

12#
ID:230418 发表于 2017-9-1 14:51 | 只看该作者
真是很及时
回复

使用道具 举报

13#
ID:230418 发表于 2017-9-1 14:52 | 只看该作者
回复好像没好处
回复

使用道具 举报

14#
ID:230418 发表于 2017-9-1 14:52 | 只看该作者
厉害了   来学习一下
回复

使用道具 举报

15#
ID:216383 发表于 2017-11-11 18:17 | 只看该作者
下载!!!!!!!!!!!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表