⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd显示c程序全解(hd61202).txt

📁 单片机实现的LCD显示。是基于HD61202模块的。我传完了
💻 TXT
📖 第 1 页 / 共 2 页
字号:
LCD显示C程序全解 
               
            在本程序中,实现了显示英文字符,汉字以及打点画线的功能,并有翻滚效果。程序中给出了常用的英文字符的字模,只要在程序中给出所要实现的字符,程序就会自动把字符转换成对应的字模并写入液晶显示模块。但是由于HD61202显示存储器的特点,显示汉字时不能将单片机内的汉字库提出直接使用,需要将其转90度,再写入。这里使用了汉字字模提取软件PICKHZB.EXE,将汉字从单片机内的汉字库提取,并旋转90度后生成专用的用户字库。
            #include <reg51.h>
            #include <math.h>
            #include <INTRINS.H>
            #define uchar unsigned char
            /***************************液晶显示器接口引脚定义*****************************/
            sbit Elcm=P2^7;   //使通信号
            sbit  CSALCM=P2^2;  //CSA控制信号
            sbit CSBLCM=P2^3;  //CSB控制信号
            sbit Dilcm=P2^0;   //D/I信号
            sbit Rwlcm=P2^1;   //R/W信号
            sbit DataIcm=0x80;  //数据口
            /*************************常用操作命令和参数定义********************************/
            #define DISPON  0X3F  //显示开
            #define DISPOFF  0x3e  //显示关
            #define DISPIRST 0xc0;  //显示起始行定义
            #define SETX  0x40;  //X定位设定指令(页)
            #define SETY  0xb8;//((40代表起始列 b8代表起始页))
            #define Lcdbusy  0x80;  //LCM是否忙
            /**************************显示分区边界位置**************************************/
            #define MODL  0x00;  //left(00,01,10,11)
            #define MODM  0x40;  //左区和中区分界
            #define MODR  0x80;  //中区和右区分界
            #define LCMLIMIT 0xc0;  //显示区的右边区
            /******************************全局变量定义*************************************/
            uchar col, row,cbyte;  //列、行(页)、输出数据
            bit xy;      //画线的方向标志,1为水平
            /*******************************************************************************/
            void Lcminit(void);
            void Delay(uchar);
            void lcdbusyL(void);
            void lcdbusyM(void);
            void lcdbusyR(void);
            void Putedut(uchar);     //半角字符输出
            void Putcdot(uchar);     //全角字符输出
            void Wrdata(uchar);     //数据输出给LCM
            void Lcmcls(void);     //LCM全屏幕清0
            void wtcom(void);     //公用BUSY等待
            void Locatexy(void);     //光标定位
            void WrcmdL(uchar);     //左区命令输出
            void WrcmdM(uchar);     //中
            void WrcmdR(uchar);     //右区命令输出
            void Putstr(uchar *puts, uchar i); //中英文字符串输出
            void Rollscreen(uchar x);   //屏幕向上滚动
            void Rddata(void);     //从液晶片上读数据
            void Linehv(uchar length);   //横竖方向画线
            void point(void);     //打点
            void Linexy(uchar endx, uchar endy); 
            /*********************************数组列表************************************/
            uchar code Ezk[];  //ASCII常规字符点阵码表
            uchar code Hzk[];  //自定义汉字点阵码表
            uchar code STR1[];  //自定义字符串
            uchar code STR2[];
            uchar code STR3[];
            uchar code STR4[];
            //*********************************主程序**************************************/
            void main(void)
            {
             uchar x;
             col=0;
             row=0;
             Delay(40);  //延时大约40ms
             Lcminit();  //液晶模块初始化,包括全屏清屏
             Putstr(STR1,12);
             col=0;
             row=2;
             Putstr(STR2,14);
             col=0;
             row=4;
             Putstr(STR3,11);
             col=0;
             row=6;
             Putstr(STR4,12);
             x=0;
             col=0;
             row=0;
             xy=1;   //方向标志
             Linehv(192); //画一条横线(0,0)--(191,0)
             col=0;
             row=15;
             xy=1;
             Linehv(192);
             col=0;
             row=32;
             xy=1;
             Linehv(192);
             col=0;
             row=1;
             xy=0;
             Linehv(31);
             col=191;
             row=1;
             xy=0;
             Linehv(31);
             col=0;
             row=63;
             Linexy(44,31);
             col=44;
             row=31;
             Linexy(192,62);
             while (1)
             {
              Rollscreen(); //定位新的显示起始行
              x++;
              Delay(100);
             }
            }
            /**********************画线,任意方向,不支持垂直或水平线**********************/
            void Linexy(uchar endx, uchar endy)
            {
             register uchar t;
             int xerr=0, yerr=0, delta_x, delta_y, distance;
             uchar incx, incy;
             delta_x=endx-col;
             delta_y=endy-row;
             //计算增量方向
             if (delta_x>0) incx=1;
             if (delta_x==0)
              incx=0;
             else
              incx=-1;
             if (delta_y>0) incy=1;
             if (delta_y==0)
              incy=0;
             else
              incy=-1;
             //区别哪个距离比较大
             //cabs()功  能: 计算复数的绝对值 用  法: double cabs(struct complex z)
             delta_x=cabs(delta_x);    
             delta_y=cabs(delta_y);
             if (delta_x>delta_y)
              distance=delta_x;
             else
              distance=delta_y;
             //开始画线
             for (t=0; t<=distace+1; t++)
             {
              point();
              xerr+=delta_x;
              yerr+=delta_y;
              if (xerr>distace)
              {
               xerr -= distance;
               col += incx;
              }
              if (yerr > distance)
              {
               yerr -= distance;
               row += incy;
              }
             }
            }
            /*****************************画直线或垂线********************************/
            void Linehv(uchar length)
            {
             uchar xs, ys;
             if (xy)
             {
              ys = col;
              for (xs=0; xs < length; xs++)
              {
               col = ys + xs;
               point();
              }
             }
             else
             {
              xs = row;
              for (ys=0; ys < length; ys++)
              {
               row = ys + xs;
               point();
              }
             }
            }
            /**********************************画点**************************************/
            void point(void)
            {
             uchar x1, y1, x, y;
             x1 = col;
             y1 = row;
             row = y1>>3;  //取Y方向分页地址 ??
             Rddata();
             y = y1 & 0x07;  //字节内位置计算
             x = 0x01;
             Wrdata(cbyte | x); //画上屏幕
             col = x1;
             row = y1;
            }
            /*********************************屏幕滚动定位*******************************/
            void Rollscreen(uchar x)
            {
             cbyte = DISPFIRST | x;  //定义显示起始行为 x??
             WrcmdL(cbyte);
             WrcmdM(cbyte);
             WrcmdR(cbyte);
            }
            /**********************************一个字串的输出****************************/
            void Putstr(uchar *puts, uchar i)
            {
             uchar j, X;
             for (j=0; j<i; j++)
             {
              X = puts[j];
              if (X & 0x80)
               Putcdot(X & 0x7f);  //只保留低7位
              else 
               Putcdot(X - 0x20); //ASCII码表从0x20开始
             }
            }
            /**********************************半角字符点阵码数据输出**********************/
            void Putedot(uchar Order)
            {
             uchar i, bakerx, bakery;
             int x;
             bakerx = col;
             bakery = row;
             x = Order * 0x10;
             //上半个字符输出,8列
             for (i = 0; i < 8; i++)
             {
              cbyte = Ezk[x];
              Wrdata(cbyte);
              x++;
              col++;
              if (col == LCMLIMIT) 
              {
               col = 0;
               row++;
               row++;
              }    //下一列,如果列越界换行
              if (row > 7)  row = 0;
             }
             col = bakerx;
             row = bakery + 1;
             //下半个字符输出,8列
             for (i = 0; i < 8; i++)
             {
              cbyte = Ezk[x];
              Wrdata(cbyte);
              x++;
              col++;
              if (col == LCMLIMIT) 
              {
               col = 0;
               row++;
               row++;
              }    //下一列,如果列越界换行
              if (row > 7)  row = 0;
             }
             row = bakery;
            }       //整个字符输出结束
            /***************************全角字符点阵数据输出***********************************/
            void Putcdot(uchar Order)
            {
             uchar i, bakerx, bakery;
             int x;
             bakerx = col;
             bakery = row;
             x = Order * 0x20;  //字义每个字符32b
             //上半个字符输出,16列
             for (i = 0; i < 16; i++)
             {
              Wrdata(cbyte);
              x++;
              col++;
              if (col == LCMLIMIT) 
              {
               col = 0;
               row++;
               row++;
              }    //下一列,如果列越界换行
              if (row > 6)  row = 0;
             }
             col = bakerx;
             row = bakery + 1;
             //下半个字符输出,8列
             for (i = 0; i < 16; i++)
             {
              cbyte = Ezk[x];
              Wrdata(cbyte);
              x++;
              col++;
              if (col == LCMLIMIT) 
              {
               col = 0;
               row++;
               row++;
              }    //下一列,如果列越界换行
              if (row > 7)  row = 0;
             }
             row = bakery;
            }
            /******************************从液晶片上读数据保留在全局变量中*********************************/
            void Rddata(void)
            {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -