zoukankan      html  css  js  c++  java
  • 段式LCD液晶显示屏的底层驱动程序

    本次任务用瑞赛单片机R7C004驱动定制的段式液晶,4COM,18seg,1/3偏压。由于单片机本身有段式液晶驱动,根据数据手册可以知道其工作过程及控制方法。

    过程分2步:1,配置硬件驱动寄存器。2,根据具体液晶情况,取模,定义联合结构体。

    步骤1可以查看数据手册,根据步骤配置写程序配置程序如下:4COM,18个seg从seg0到seg18(出去seg11)

    void LCD_Init(void)
    {
    	HB_LCDM1=0;nop();
    	HB_LCDM0=0x4D;
    	HB_PFSEG0=0xf0;HB_PFSEG1=0xF7;HB_PFSEG2=0x07;
    	HB_PFSEG3=0x00;HB_PFSEG4=0x00;HB_PFSEG5=0x00;
    	HB_PFSEG6=0x00;
    	
    	HB_LCDC0=0x16;
    	HB_VLCD=0X16;
    	us_delay(100);
    	HB_LCDM1=0x20;
    	nop();nop();nop();
    	HB_LCDM1|=0xc0;	
    	HB_ISCLCD=0;
    }

    步骤2 液晶的具体情况如下2图

    我们根据图1来设定取模,我把 56 78 910 、、、、两两合为一个字节 8位数据。 即8H 7C 7B 7A 7D 7E 7G 7F 这里的7 即代表数码管的位置,7代表从右往左数第2位数码管。

    这样H 即为0x80 A为0x10 我用宏定义设置每一段的数值

    #define 	      LcdSingMask 		0x00
    #define         LcdSeg_a		0x10
    #define         LcdSeg_b		0x20
    #define         LcdSeg_c		0x40
    #define         LcdSeg_d		0x08
    #define         LcdSeg_e		0x04
    #define         LcdSeg_f		0x01
    #define         LcdSeg_g		0x02

    并通过宏定义对0-f 和u 取模

    #define		 Char_0		LcdSeg_a+LcdSeg_b+LcdSeg_c\
    				 	+LcdSeg_d+LcdSeg_e+LcdSeg_f
    				 	
    #define  	       Char_1		LcdSeg_b+LcdSeg_c
    
    #define		Char_2		LcdSeg_a+LcdSeg_b\
    				 	+LcdSeg_d+LcdSeg_e+LcdSeg_g
    				 	
    #define		Char_3		LcdSeg_a+LcdSeg_b+LcdSeg_c\
    				 	+LcdSeg_d+LcdSeg_g
    				 	
    #define		Char_4		LcdSeg_b+LcdSeg_c\
    				 	+LcdSeg_f+LcdSeg_g
    
    #define		Char_5		LcdSeg_a+LcdSeg_c\
    				 	+LcdSeg_d+LcdSeg_f+LcdSeg_g
    
    #define		Char_6		LcdSeg_a+LcdSeg_g+LcdSeg_c\
    				 	+LcdSeg_d+LcdSeg_e+LcdSeg_f
    
    #define		Char_7		LcdSeg_a+LcdSeg_b+LcdSeg_c
    				 	
    
    #define		Char_8		LcdSeg_a+LcdSeg_b+LcdSeg_c\
    				 	+LcdSeg_d+LcdSeg_e+LcdSeg_f+LcdSeg_g
    
    #define		Char_9		LcdSeg_a+LcdSeg_b+LcdSeg_c\
    				 	+LcdSeg_d+LcdSeg_f+LcdSeg_g
    				 	
    #define		Char_A		LcdSeg_a+LcdSeg_b+LcdSeg_c\
    				 	+LcdSeg_e+LcdSeg_f+LcdSeg_g
    
    #define		Char_b 		LcdSeg_c\
    				 	+LcdSeg_d+LcdSeg_e+LcdSeg_f+LcdSeg_g
    				 	
    #define		Char_C 		LcdSeg_a+LcdSeg_f+LcdSeg_e+LcdSeg_d
    
    #define		Char_d		LcdSeg_b+LcdSeg_c+LcdSeg_d\
    	                            +LcdSeg_e+LcdSeg_g
    
    
    #define		Char_E		LcdSeg_a\
    				 	+LcdSeg_d+LcdSeg_e+LcdSeg_f+LcdSeg_g
    
    #define		Char_F		LcdSeg_a+LcdSeg_f+LcdSeg_e+LcdSeg_g
    
    #define		Char_r          LcdSeg_e+LcdSeg_g
    
    #define		Char_H	 	LcdSeg_b+LcdSeg_c+LcdSeg_e+LcdSeg_f+LcdSeg_g
    
    #define 	Char_L    	LcdSeg_d+LcdSeg_e+LcdSeg_f
    
    #define 	Char_Row	LcdSeg_g
    
    #define 	Char_U		LcdSeg_b+LcdSeg_c+LcdSeg_d+LcdSeg_e+LcdSeg_f

    从图一可以看到 基本上每两个seg能完全配置一个数码管,值得一提的是 ,我通过union来管理他们,简洁明了。

    typedef  union {  
    	 	uchar  LCD_LgcBuf[Gcst_LCDBufSize];
    		struct{	
    				struct
    				{
    					unsigned char Sign_7F:1;
    					unsigned char Sign_7G:1;
    					unsigned char Sign_7E:1;
    					unsigned char Sign_7D:1;
    					unsigned char Sign_7A:1;
    					unsigned char Sign_7B:1;
    					unsigned char Sign_7C:1;
    					unsigned char Sign_8H:1;
    				}Sign_SEG1_2;
    			      struct
    				{
    					unsigned char Sign_8F:1;
    					unsigned char Sign_8G:1;
    					unsigned char Sign_8E:1;
    					unsigned char Sign_8D:1;
    					unsigned char Sign_8A:1;
    					unsigned char Sign_8B:1;
    					unsigned char Sign_8C:1;
    					unsigned char Sign_9H:1;
    				}Sign_SEG3_4;
    			    struct
    				{
    					unsigned char Sign_9F:1;
    					unsigned char Sign_9G:1;
    					unsigned char Sign_9E:1;
    					unsigned char Sign_9D:1;
    					unsigned char Sign_9A:1;
    					unsigned char Sign_9B:1;
    					unsigned char Sign_9C:1;
    					unsigned char Sign_kWh:1;
    				}Sign_SEG5_6;
    				struct
    				{
    					unsigned char Sign_Jiner:1;
    					unsigned char Sign_10H:1;
    					unsigned char Sign_Yuan:1;
    					unsigned char Sign_V:1;
    					unsigned char Sign_6A:1;
    					unsigned char Sign_6B:1;
    					unsigned char Sign_6C:1;
    					unsigned char Sign_7H:1;
    				}Sign_SEG7_8;
    			     struct
    				{
    					unsigned char Sign_6F:1;
    					unsigned char Sign_6G:1;
    					unsigned char Sign_6E:1;
    					unsigned char Sign_6D:1;
    					unsigned char Sign_Dian:1;
    					unsigned char Sign_11H:1;
    					unsigned char Sign_Shengyu:1;
    					unsigned char Sign_Dangqian:1;
    				}Sign_SEG9_10;
    				struct
    				{
    					unsigned char Sign_5A:1;
    					unsigned char Sign_5B:1;
    					unsigned char Sign_5C:1;
    					unsigned char Sign_6H:1;
    					unsigned char Sign_5F:1;
    					unsigned char Sign_5G:1;
    					unsigned char Sign_5E:1;
    					unsigned char Sign_5D:1;
    				}Sign_SEG11_12;
    				struct
    				{
    					unsigned char Sign_4A:1;
    					unsigned char Sign_4B:1;
    					unsigned char Sign_4C:1;
    					unsigned char Sign_5H:1;
    					unsigned char Sign_4F:1;
    					unsigned char Sign_4G:1;
    					unsigned char Sign_4E:1;
    					unsigned char Sign_4D:1;
    				}Sign_SEG13_14;
    				struct
    				{
    					unsigned char Sign_3A:1;
    					unsigned char Sign_3B:1;
    					unsigned char Sign_3C:1;
    					unsigned char Sign_4H:1;
    					unsigned char Sign_3F:1;
    					unsigned char Sign_3G:1;
    					unsigned char Sign_3E:1;
    					unsigned char Sign_3D:1;
    				}Sign_SEG15_16;
    				struct
    				{
    					unsigned char Sign_2A:1;
    					unsigned char Sign_2B:1;
    					unsigned char Sign_2C:1;
    					unsigned char Sign_A:1;
    					unsigned char Sign_2F:1;
    					unsigned char Sign_2G:1;
    					unsigned char Sign_2E:1;
    					unsigned char Sign_2D:1;
    				}Sign_SEG17_18;									
    			}Signs;		
    	 	}UnDef_LcdBuf;

    这里初始化每个结构体时,要把低为放前边。

    我把一些特殊的值单独赋值,比如“当前”,“金额”。因为这些不是数码,要根据特殊情况来置位。同样用到宏定义。

    #define         Sign_Kwh_Dat          	GStr_LcdBuf.Signs.Sign_SEG5_6.Sign_kWh
    #define         Sign_V_Dat        	GStr_LcdBuf.Signs.Sign_SEG7_8.Sign_V
    #define         Sign_Yuan_Dat         	GStr_LcdBuf.Signs.Sign_SEG7_8.Sign_Yuan	
    #define         Sign_A_Dat          	GStr_LcdBuf.Signs.Sign_SEG17_18.Sign_A
    #define         Sign_Shengyu_Dat  	GStr_LcdBuf.Signs.Sign_SEG9_10.Sign_Shengyu
    #define         Sign_Jiner_Dat    	GStr_LcdBuf.Signs.Sign_SEG7_8.Sign_Jiner
    #define        Sign_Dianliang_Dat    	GStr_LcdBuf.Signs.Sign_SEG9_10.Sign_Dian
    #define        Sign_Dangqian_Dat	GStr_LcdBuf.Signs.Sign_SEG9_10.Sign_Dangqian
    #define         Sign_P4_Dat  		GStr_LcdBuf.Signs.Sign_SEG15_16.Sign_4H
    #define         Sign_P5_Dat  		GStr_LcdBuf.Signs.Sign_SEG13_14.Sign_5H
    #define         Sign_P6_Dat  		GStr_LcdBuf.Signs.Sign_SEG11_12.Sign_6H
    #define         Sign_P7_Dat  		GStr_LcdBuf.Signs.Sign_SEG7_8.Sign_7H
    #define         Sign_P8_Dat  		GStr_LcdBuf.Signs.Sign_SEG1_2.Sign_8H
    #define         Sign_P9_Dat  		GStr_LcdBuf.Signs.Sign_SEG3_4.Sign_9H
    #define         Sign_P10_Dat  		GStr_LcdBuf.Signs.Sign_SEG7_8.Sign_10H
    #define         Sign_P11_Dat  		GStr_LcdBuf.Signs.Sign_SEG9_10.Sign_11H
    
    #define         Dis_Kwh          	Sign_Kwh_Dat=1
    #define         Dis_Fu_V         	Sign_V_Dat=1
    #define         Dis_Yuan         	Sign_Yuan_Dat=1 	
    #define         Dis_An_A          	Sign_A_Dat=1
    #define         Dis_Shengyu  	Sign_Shengyu_Dat=1 
    #define         Dis_Jin_e    		Sign_Jiner_Dat=1 
    #define         Dis_Dianliang    	Sign_Dianliang_Dat=1 
    #define         Dis_Dangqian		Sign_Dangqian_Dat=1
    #define         Dis_Point5  		Sign_P4_Dat=1
    #define         Dis_Point4  		Sign_P5_Dat=1
    #define         Dis_Point3  		Sign_P6_Dat=1
    #define         Dis_Point2  		Sign_P7_Dat=1
    #define         Dis_Point1  		Sign_P8_Dat=1
    #define         Dis_Point0  		Sign_P9_Dat=1
    #define         Dis_Point10  		Sign_P10_Dat=1
    #define         Dis_Point11  		Sign_P11_Dat=1

    取模和液晶对应起来后,就可以写基础的赋值程序了。

    根据瑞萨R7004数据手册介绍,只需王显示寄存器赋值既可以了。

    赋值程序如下:

    void Screen_convert(void) 
    {
    
    	*(LCD_StartAddr)=GStr_LcdBuf.LCD_LgcBuf[0]&0X0F;
    	*(LCD_StartAddr+1)=(GStr_LcdBuf.LCD_LgcBuf[0]>>4);	
    	*(LCD_StartAddr+2)=GStr_LcdBuf.LCD_LgcBuf[1]&0X0F;	
    	*(LCD_StartAddr+3)=(GStr_LcdBuf.LCD_LgcBuf[1]>>4);		
    	*(LCD_StartAddr+4)=GStr_LcdBuf.LCD_LgcBuf[2]&0X0F;
    	*(LCD_StartAddr+5)=(GStr_LcdBuf.LCD_LgcBuf[2]>>4);
    	*(LCD_StartAddr+6)=GStr_LcdBuf.LCD_LgcBuf[3&0X0F];
    	*(LCD_StartAddr+7)=(GStr_LcdBuf.LCD_LgcBuf[3]>>4);
    	*(LCD_StartAddr+8)=GStr_LcdBuf.LCD_LgcBuf[4]&0X0F;	
    	*(LCD_StartAddr+9)=(GStr_LcdBuf.LCD_LgcBuf[4]>>4);	
    	*(LCD_StartAddr+10)=GStr_LcdBuf.LCD_LgcBuf[5]&0X0F;
    	*(LCD_StartAddr+12)=(GStr_LcdBuf.LCD_LgcBuf[5]>>4);	
    	*(LCD_StartAddr+13)=GStr_LcdBuf.LCD_LgcBuf[6]&0X0F;		
    	*(LCD_StartAddr+14)=(GStr_LcdBuf.LCD_LgcBuf[6]>>4);		
    	*(LCD_StartAddr+15)=GStr_LcdBuf.LCD_LgcBuf[7]&0X0F;		
    	*(LCD_StartAddr+16)=(GStr_LcdBuf.LCD_LgcBuf[7]>>4);	
    	*(LCD_StartAddr+17)=GStr_LcdBuf.LCD_LgcBuf[8]&0X0F;		
    	*(LCD_StartAddr+18)=(GStr_LcdBuf.LCD_LgcBuf[8]>>4);	
    }
    
    LCD_StartAddr为寄存器首地址,数据手册有。把一个字节分为高低4位,赋值给连续的两个显示寄存器,就可正常显示一个数码管的数字了。接下来介绍怎么王数组里填充数值。
    <pre name="code" class="objc">void Dis_1char(uchar PuB_position,uchar PuB_data)
    {
    	uchar LuW_Dat;
    	LuW_Dat=GAuB_char_tbl[PuB_data];
    	switch(PuB_position)
    		{
    		case 0: GStr_LcdBuf.LCD_LgcBuf[2]=LuW_Dat;break;
    		case 1: GStr_LcdBuf.LCD_LgcBuf[1]=LuW_Dat;break;
    		case 2: GStr_LcdBuf.LCD_LgcBuf[0]=LuW_Dat;break;
    		case 3: GStr_LcdBuf.LCD_LgcBuf[3]|=(LuW_Dat&0xf0);GStr_LcdBuf.LCD_LgcBuf[4]|=(LuW_Dat&0x0f);break;
    		case 4: zhihuan(LuW_Dat);GStr_LcdBuf.LCD_LgcBuf[5]=LuW_Dat;break;
    		case 5: zhihuan(LuW_Dat);GStr_LcdBuf.LCD_LgcBuf[6]=LuW_Dat;break;
    		case 6: zhihuan(LuW_Dat);GStr_LcdBuf.LCD_LgcBuf[7]=LuW_Dat;break;
    		case 7: zhihuan(LuW_Dat);GStr_LcdBuf.LCD_LgcBuf[8]=LuW_Dat;break;
    		default: break;
    		}
    
    }
    
    

    这里要注意GStr_LcdBuf.LCD_LgcBuf[?]的顺序和要显示的位置的关系,和图一一一对应,比如要显示0位置时,可根据图1的 要用9A-9C,K那两个seg 即GStr_LcdBuf.LCD_LgcBuf[2]。位置3,有点特殊,他分别用到了数组3的高4位,和数组4的低四位。位置4-7,高低四位又反过来,所以要加zhihuan(LuW_Dat);实现高低4为互换。

    #define zhihuan(dat)  ((dat>>4)|(dat<<4))

    了解基本的显示程序后,显示的步骤为:

    1,LCD_Init()

    2,Dis_1char(PuB_position,PuB_data),,还可以有Sign_Kwh_Dat、Dis_Jin_e、Dis_Point0之类。

    3,Screen_convert()






    懒惰不会让你一下子跌到 但会在不知不觉中减少你的收获; 勤奋也不会让你一夜成功 但会在不知不觉中积累你的成果 越努力,越幸运。
  • 相关阅读:
    用迭代法求x=a−−√。求平方根的迭代公式为 xn+1 = 12(xn + axn) 要求前后两次求出的x的差的绝对值小于10−5
    C 数组
    fofa自动化爬虫脚本更新+详解
    c# winfrom接收http协议body数据
    FLW要求
    modbus工具问题
    2020年总结
    WIFI K型热电偶传感器
    泛海三江烟感JTY-GD-H361 V2.7
    工位终端
  • 原文地址:https://www.cnblogs.com/Rainingday/p/5947480.html
Copyright © 2011-2022 走看看