8H4K64TLCD驱动段码LCD屏教程(一)点亮段码LCD屏 8H4K64TLCD驱动段码LCD屏教程(二)触摸按键
新版段码屏已到货,本系列文章均以这个板子围绕展开,有需要的可以自己打板测试,或者通过这个链接购买成品跟着测试:https://item.taobao.com/item.htm ... 97.7.40763d46EWIlaN
一、原理分析
首先对于一个程序员来说,拿到一个段码屏要先看他的段码表和点亮效果图(每一个图标里的序号和第二个段码表里的序号对应)
第一张图能看到他整个的显示内容,第二张图就是他的段码和位码, 这里需要重点注意STC的com是四线的,屏也需要是最大是四com的,整体来说其实和数码管的操作原理类似,就是com和seg的一系列操作,但是区别的是数码管只输出高低电平,但是段码的输出不单单是高低电平,这里需要插入下他的原理介绍
当然上述的这些不需要完全掌握,只需要知道他的意思就是说虽然同是com和seg,但是我们不能像数码管那样直接高低电平去点(虽然能点亮,但是很容易坏),当然,由于单片机内部有LCD的驱动器,我们也不需要自己搭电路去控制了,能省下不少的成本
这里只需要考虑这里段码屏的com接单片机的com脚,如上图手册描述的一样,段码屏的seg接单片机的seg(可以随意接,不需要考虑顺序什么的,只是要方便写程序就行),由于这个原理图特别大不好截图,原理图请从qq群文件自行下载。
这里段码屏还一个非常重要的参数,就是电压。这个屏的电压是3.3V,所以注意单片机的供电电压不能小于这个屏幕的驱动电压。
二、手册分析
首先先对这个内部的LCD的驱动模块进行初始化;开始查阅手册
1.从首页的介绍可以知道,目前stc能带段码屏的只有这个型号,其次他最大驱动4*40的段码屏,基本上绝大多数场合是完全够用了的。
由此我们可以编写如下代码
- LCDCFG2 = 0x0f; // SEG0~3切换到P7.7~7.4
复制代码
2.功能脚切换,这里我们用的引脚是P7.7~7.4,所以这个寄存器的低4位全都选1
3.时钟配置,可以看到这里有四种模式选择,第一种内部高速IRC在省电模式会停震导致无法刷新,所以实际做产品的话不建议用这个,但是我们测试的时候可以用!!第二种模式不让用,跳过!第三种模式在省电模式下依然可以使用,且用外部晶振可以省去1.5ua的内部低速时钟的功耗,推荐使用这个(这个模式下一章细讲)!
4.电压配置,这里单片机VCC是5v,屏的电压是3.3v,所以VLCDSEL可以直接设置为0,即5*0.65 = 3.25V。
由此可以得出,这个寄存器的代码可以这样写
- LCDCFG = 0x00 + 0; // 0x00:选择CPU时钟为LCD时钟, 0x80: 选择外部32K晶振做时钟. VLCD电压选择0~7对应0.65+VLCD*0.05.
复制代码
5.这里还有一个比较重要的概念,刷新率,基本上在60hz的时候人眼就已经基本无法看出屏闪了,所以这里刷新率可以给他配置为60hz,这里我们选择手册说的24Mhz的情况下考虑的话,60hz所需要的参数都已经给出了,我们就按这个操作即可,我们就可以编写如下代码
- DBLNTH = 2; // 设置LCD显示时的死区时间长度, 取值0~7.
- COMLNTHH = 0x01; // COM时间长度设置 高字节COMLEN[19:16], 一共20bit.
- COMLNTHM = 0x86; // COM时间长度设置 中字节COMLEN[15:8] LCD刷新率 = LCD时钟频率 / ((DBLEN[2:0]+COMLEN[19:0]+1) *2 * COM数)
- COMLNTHL = 0x9d; // COM时间长度设置 低字节COMLEN[7:0] LCD刷新率 = 32768/((2+65+1)*2*4) = 60Hz
- BLINKFRPS = 60; // 闪烁率配置寄存器, LCD闪烁率 = LCD刷新率 / BLINKRATE[7:0] Hz
复制代码
三、代码编写
1.初始化函数
- void LCD_config(void)
- {
- u8 i;
-
- LCDCFG = 0x00 + 0; // 0x00:选择CPU时钟为LCD时钟, 0x80: 选择外部32K晶振做时钟. VLCD电压选择0~7对应0.65+VLCD*0.05.
- DBLNTH = 2; // 设置LCD显示时的死区时间长度, 取值0~7.
- COMLNTHH = 0x01; // COM时间长度设置 高字节COMLEN[19:16], 一共20bit.
- COMLNTHM = 0x86; // COM时间长度设置 中字节COMLEN[15:8] LCD刷新率 = LCD时钟频率 / ((DBLEN[2:0]+COMLEN[19:0]+1) *2 * COM数)
- COMLNTHL = 0x9d; // COM时间长度设置 低字节COMLEN[7:0] LCD刷新率 = 32768/((2+65+1)*2*4) = 60Hz
- BLINKFRPS = 60; // 闪烁率配置寄存器, LCD闪烁率 = LCD刷新率 / BLINKRATE[7:0] Hz
-
- COM_ON_A = 0x0f; // COM使能寄存器
- SEG_ON_A = 0xff; // SEG线使能寄存器1, SEG7~SEG0
- SEG_ON_B = 0xff; // SEG线使能寄存器2, SEG15~SEG8
- SEG_ON_C = 0xff; // SEG线使能寄存器3, SEG23~SEG16
- SEG_ON_D = 0xff; // SEG线使能寄存器4, SEG31~SEG24
- SEG_ON_E = 0xff; // SEG线使能寄存器5, SEG39~SEG32
-
- P5n_pure_input(0x03); //P5.0 P5.1 设置为高阻输入 COM0 COM1
- P3n_pure_input(0x60); //P3.5 P3.6 设置为高阻输入 COM2 COM3
-
- LCDCFG2 = 0x0f; // SEG0~3切换到P7.7~7.4
- P7n_pure_input(0xf0); //P7.7~P7.4 设置为高阻输入 SEG0~SEG3 (对应P7.7~7.4)
- P4n_pure_input(0x80); //P4.7 设置为高阻输入 SEG4
- P1n_pure_input(0x03); //P1.1~P1.0 设置为高阻输入 SEG5 SEG6 (对应P1.1 P1.0)
- P0n_pure_input(0xe0); //P0.7~P0.5 设置为高阻输入 SEG7 SEG8 SEG9 (对应P0.7 P0.6 P0.5)
- P5n_pure_input(0x0C); //P5.3 P5.2 设置为高阻输入 SEG10 SEG11 (对应P5.3 P5.2)
- P0n_pure_input(0x1f); //P0.4~P0.0 设置为高阻输入 SEG12~SEG16 (对应P0.4 ~ 0.0)
- P4n_pure_input(0x60); //P4.6 P4.5 设置为高阻输入 SEG17 SEG18
- P2n_pure_input(0xff); //P2.7~P2.0 设置为高阻输入 SEG19~SEG26 (对应P2.7~2.0)
- P4n_pure_input(0x1e); //P4.4~P4.1 设置为高阻输入 SEG27~SEG30 (对应P4.4~4.1)
- P3n_pure_input(0x80); //P3.7 设置为高阻输入 SEG31
- P7n_pure_input(0x0f); //P7.3~P7.0 设置为高阻输入 SEG32~SEG35 (对应P7.3~7.0)
- P6n_pure_input(0x0f); //P6.0~P6.3 设置为高阻输入 SEG36~SEG39 (对应P6.3~6.0)
-
- for(i=0; i<20; i++)
- LCD_buff[i] = 0x00; //清除显示内容
-
- LoadToLcd(); //将显示内容导入显存
-
- LCDCR = (0<<1) + 1; // LCD控制寄存器, 0:普通模式, 1:长暗模式, 2:长亮模式, 3:闪烁模式. +0:禁止LCD模块, +1:允许LCD模块.
复制代码
可以看到最上面的几行是不是就是第二快内容分析的寄存器配置,这里就不在赘述了。
紧接着就是com和seg的使能了,这里就是写1使能,写0关闭,因为这里4个com和40个seg都用上了,所以这里全都写1了。
在下面就是将所有使用的com和seg口都设置为高阻输入模式
在下面一个for语句将LCD_buff的数组清0,后面我们点亮和熄灭屏的操作都是靠这个数组来的
在下面的LoadToLcd函数是将我们的LCD_buff里的内容全都写入到lcd的数据寄存器里去,即直接显示
最后开启数码管为常亮显示,这个初始化就结束了。
下面就到了大家最关心的,我怎么去点亮段码屏的指定的某一段了,首先我们来看下这个段码屏是怎么和单片机连接的:
这里帮大家整理好了一个表格,分为了三块显示,每块的第一行是段码屏的引脚号,第二三四五行使单片机的com对应的显示的图标号,最后一行就是连接的单片机的引脚,因为这个图是按照段码屏的序号排布的不太好看,我给他整理了下,按照单片机的seg号排布,排列玩之后如下:
可以看到这里还是三块,第一块16个seg口就是,从seg0-seg15,可以看到这里最上面多可一行16进制数,最下面一行多了个中文。这个怎么理解呢,以第一个为例,看到“从上到下为 0 5 10 15”这个文字所在的那八列,其中横着的COM0对应的那一行就是对应的LCD_buff[0]数组对应的显示内容,横着的COM1对应的那一行就是对应的LCD_buff[5]数组对应的显示内容,横着的COM2对应的那一行就是对应的LCD_buff[10]数组对应的显示内容,横着的COM3对应的那一行就是对应的LCD_buff[15]数组对应的显示内容,且写1点亮
例1:要想点亮“P2”所在的图标就是LCD_buff[0] |= 0x08;
例2:要想点亮“-2”所在的图标就是LCD_buff[10] |= 0x10;
例3:要想点亮“L1”所在的图标就是LCD_buff[16] |= 0x02;
2.再来点亮一个数字"8"
每个数字8的段码和数码管一样,都是A-G,这里对应码表,假设我需要点亮一个1,是不是就是点亮表中的这两个段
换成代码就是这样子
LCD_buff[5] |= 0x02;
LCD_buff[15] |= 0x02;
当然每次点亮都这么写太麻烦了,这里换成函数的写法
复制代码
入口参数的n表示第几个数字8,dat表示当前要写入的数,写入的数据包含这些:
这个函数主要就是先把指定的第几个8所在的位置的数据先清空,
例如第一个数字8他会先清空这7个位,在判断当前要显示的内容,在分别写入这七个位即可点亮,后面的数码管一次类推。函数写个LCD_load(1,0); 就可以让第一个数字8显示0;
段码LCD及触摸按键演示程序-20240525:
|