找回密码
 立即注册
查看: 2767|回复: 30

8H4K64TLCD驱动段码LCD的寄存器咨询

[复制链接]

1

主题

5

回帖

31

积分

新手上路

积分
31
发表于 2023-5-18 13:50:47 | 显示全部楼层 |阅读模式
1. 下载了官网提供的 断码LCD程序,发现里面对显示寄存器操作有点复杂。

  1. /****************** 对第1~5数字装载显示函数 ***************************/
  2. u8 code t_display[]={                                                //标准字库
  3. //         0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
  4.         0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
  5. //black         -     H    J         K          L           N        o   P         U     t    G    Q    r   M    y
  6.         0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e};
  7. u8        code T_LCD_mask[7]  = {0x00,0x0C,0x30,0xC0,0x03,0x0C};
  8. u8        code T_LCD_mask7[7] = {0x00,0x04,0x10,0x40,0x01,0x04};
  9. u8        code T_SEG_ABC[7]   = {0x00,0x08,0x20,0x80,0x02,0x08};
  10. u8        code T_SEG_DEFG[7]  = {0x00,0x04,0x10,0x40,0x01,0x04};
  11. /********************** 装载显示5个8字 *****************************/
  12. void        LCD_load(u8 n, u8 dat)                //n为第几个数字,为1~5,dat为要显示的数字
  13. {
  14.         u8        i,k;
  15.         if((n == 0) || (n >= 6))        return;        //合法值 1~5
  16.         dat =  t_display[dat]; //3F
  17.         k   = ~T_LCD_mask[n]; //FF
  18.         if(n <= 3)        //1~3
  19.         {
  20.                 LCD_buff[0] &= ~T_LCD_mask7[n]; //FF
  21.                 LCD_buff[2] &= k; //NC
  22.                 LCD_buff[4] &= k; //NC
  23.                 LCD_buff[6] &= k; //NC  
  24.                 i = T_SEG_ABC[n];  //00
  25.                 k = T_SEG_DEFG[n];  //00
  26.                 if(dat & 0x01)                LCD_buff[6] |= i;        //T_SEG_ABC[n];                //A
  27.                 if(dat & 0x02)                LCD_buff[4] |= i;        //T_SEG_ABC[n];                //B
  28.                 if(dat & 0x04)                LCD_buff[2] |= i;        //T_SEG_ABC[n];                //C
  29.                 if(dat & 0x08)                LCD_buff[0] |= k;        //T_SEG_DEFG[n];        //D
  30.                 if(dat & 0x10)                LCD_buff[2] |= k;        //T_SEG_DEFG[n];        //E
  31.                 if(dat & 0x20)                LCD_buff[6] |= k;        //T_SEG_DEFG[n];        //F
  32.                 if(dat & 0x40)                LCD_buff[4] |= k;        //T_SEG_DEFG[n];        //G
  33.         }
  34.         else        // n=4 or 5
  35.         {
  36.                 LCD_buff[1] &= ~T_LCD_mask7[n];
  37.                 LCD_buff[3] &= k;
  38.                 LCD_buff[5] &= k;
  39.                 LCD_buff[7] &= k;
  40.                 i = T_SEG_ABC[n];
  41.                 k = T_SEG_DEFG[n];
  42.                 if(dat & 0x01)                LCD_buff[7] |= i;        //T_SEG_ABC[n];                //A
  43.                 if(dat & 0x02)                LCD_buff[5] |= i;        //T_SEG_ABC[n];                //B
  44.                 if(dat & 0x04)                LCD_buff[3] |= i;        //T_SEG_ABC[n];                //C
  45.                 if(dat & 0x08)                LCD_buff[1] |= k;        //T_SEG_DEFG[n];        //D
  46.                 if(dat & 0x10)                LCD_buff[3] |= k;        //T_SEG_DEFG[n];        //E
  47.                 if(dat & 0x20)                LCD_buff[7] |= k;        //T_SEG_DEFG[n];        //F
  48.                 if(dat & 0x40)                LCD_buff[5] |= k;        //T_SEG_DEFG[n];        //G
  49.         }
  50. }
  51. /********************** 将显示内容导入显存 *****************************/
  52. void        LoadToLcd(void)
  53. {
  54.         C0SEGV1 = LCD_buff[0];    // C0SEG 15~8数据寄存器
  55.         C0SEGV2 = LCD_buff[1];    // C0SEG 23~16数据寄存器
  56.         C1SEGV1 = LCD_buff[2];    // C1SEG 15~8数据寄存器
  57.         C1SEGV2 = LCD_buff[3];    // C1SEG 23~16数据寄存器
  58.         C2SEGV1 = LCD_buff[4];    // C2SEG 15~8数据寄存器
  59.         C2SEGV2 = LCD_buff[5];    // C2SEG 23~16数据寄存器
  60.         C3SEGV1 = LCD_buff[6];    // C3SEG 15~8数据寄存器
  61.         C3SEGV2 = LCD_buff[7];    // C3SEG 23~16数据寄存器
  62. }
复制代码
前面对buf的数据处理逻辑比较复杂,最后将数据传入到 CxSEGVx寄存器中。 这段过程一直没有理解;
2. 之前用过TM1621这类的驱动,不知道咱们的这个驱动方式是否和这类芯片类似?如果不相同,应该怎么理解 这些寄存器的作用? 尤其是CxSEGVx寄存器。
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2024-12-25 10:15:05

47

主题

1350

回帖

8058

积分

荣誉版主

冲哥视频教程和各种开源资料QQ交流群884047237,可群

积分
8058
QQ
发表于 2023-5-18 14:11:25 | 显示全部楼层
区别于数码管,段码的连接一般不是整组接在位或者段上的。
数码管可能八个段码刚好占用一个P1端口,但是LCD你仔细看提供的段码表,你可以推理下如果要点亮一个数字2需要哪几个位输出,算出来了这个数值,在来看这个程序你就懂了
回复 支持 反对

使用道具 举报 送花

1

主题

5

回帖

31

积分

新手上路

积分
31
发表于 2023-5-18 16:24:32 | 显示全部楼层
电子DI*** 发表于 2023-5-18 14:11
区别于数码管,段码的连接一般不是整组接在位或者段上的。
数码管可能八个段码刚好占用一个P1端口,但是LCD ...

数码管是了解的;TM1621这类专用LCD断码驱动屏,是每次发4个bit数据,发两次正好可以对应一个显示数字;但是STC的驱动方式好像不一样。感觉驱动起来就比TM1621要麻烦点

点评

一样的,其实我们的比HT1621要方便得多,传送速度快得多。 例子为什么看起来复杂?其实是因为例子用的屏是网上买来的,并且是在通用测试板上测试的,所以每一段对应显存有点乱,实际工程会自己设计LCD,排列有规律,  详情 回复 发表于 2023-5-18 22:02
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:14
  • 最近打卡:2025-04-28 14:10:14

19

主题

385

回帖

2508

积分

版主

积分
2508
QQ
发表于 2023-5-18 17:12:57 | 显示全部楼层
1.png
QQ:1463035472,微信:19952583954
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:440
  • 最近打卡:2025-04-30 08:02:54
已绑定手机

4

主题

269

回帖

1246

积分

金牌会员

积分
1246
发表于 2023-5-18 19:35:57 | 显示全部楼层
本帖最后由 xuzeabc 于 2023-5-18 19:39 编辑
zl_*** 发表于 2023-5-18 16:24
数码管是了解的;TM1621这类专用LCD断码驱动屏,是每次发4个bit数据,发两次正好可以对应一个显示数字; ...

刚使用TLCD给一朋友开发的段码液晶摩托车仪表。用惯了1621驱动,刚开始感觉有点不适应,诚如楼主所言。慢慢的使用过程中,感觉操作起来比1621便宜不少。使用1621为了驱动不同种类的8,用了很多数组,使用单片机,一个数组完成工作。
把段码的数据定义在了bdata处,用联合体和结构体,可以进行位操作,也可以进行字节操作,方便多多。希望对楼主有参考。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2023-5-18 22:02:28 | 显示全部楼层
zl_*** 发表于 2023-5-18 16:24
数码管是了解的;TM1621这类专用LCD断码驱动屏,是每次发4个bit数据,发两次正好可以对应一个显示数字; ...

一样的,其实我们的比HT1621要方便得多,传送速度快得多。
例子为什么看起来复杂?其实是因为例子用的屏是网上买来的,并且是在通用测试板上测试的,所以每一段对应显存有点乱,实际工程会自己设计LCD,排列有规律,连到MCU的LCD驱动脚也按屏设计,就会有规律。

下面是我某个测试用的HT1621,2个数码管,也一样的复杂:
/****************** 对第1 2数字装载显示函数 ***************************/
u8 code t_display[]={                                                //标准字库
//         0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
        0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black         -     H    J         K          L           N        o   P         U     t    G    Q    r   M    y
        0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
        0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};        //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
void        LCD_load(u8 n, u8 dat)                //n为第几个数字,为1~2,dat为要显示的数字
{
        u8        i;
       
        if(n == 1)
        {
                LCD_buff[1] &= 0x0f;        LCD_buff[2] &= 0xf8;
                i = t_display[dat];
                if(i & 0x01)        LCD_buff[1] |= 0x10;        //A
                if(i & 0x02)        LCD_buff[2] |= 0x01;        //B
                if(i & 0x04)        LCD_buff[2] |= 0x04;        //C
                if(i & 0x08)        LCD_buff[1] |= 0x80;        //D
                if(i & 0x10)        LCD_buff[1] |= 0x40;        //E
                if(i & 0x20)        LCD_buff[1] |= 0x20;        //F
                if(i & 0x40)        LCD_buff[2] |= 0x02;        //G
                HT1621_write_byte(2,LCD_buff[1]);
                HT1621_write_byte(4,LCD_buff[2]);
        }
        else if(n == 2)
        {
                LCD_buff[2] &= 0x0f;        LCD_buff[3] &= 0xf8;
                i = t_display[dat];
                if(i & 0x01)        LCD_buff[2] |= 0x10;        //A
                if(i & 0x02)        LCD_buff[3] |= 0x01;        //B
                if(i & 0x04)        LCD_buff[3] |= 0x04;        //C
                if(i & 0x08)        LCD_buff[2] |= 0x80;        //D
                if(i & 0x10)        LCD_buff[2] |= 0x40;        //E
                if(i & 0x20)        LCD_buff[2] |= 0x20;        //F
                if(i & 0x40)        LCD_buff[3] |= 0x02;        //G
                HT1621_write_byte(4,LCD_buff[2]);
                HT1621_write_byte(6,LCD_buff[3]);
        }
}

为什么会这样?因为LCD的段码排列和HT1621的引线是工程师乱连的结果。

如果是下面的内存映射表,则不管是HT1621还是STC8H4K64TLCD,只要规划好COM线和SEG线,则会很简单的,所以最关键的是映射表是否有规律,没有规律,用哪个IC都恼火。
               RAM地址  B7                B6                B5                B4                B3                B2                B1                B0
LCD_buff[3]:        19,18        3D                3E                3G                3F                3H                3C                3B                3A
LCD_buff[0]:        21,20        --                --                --                --                61                -                LB                Kg                61为右上角到E显示1
LCD_buff[5]:        23,22        5D                5E                5G                5F                --                5C                5B                5A                5为右下角小8
LCD_buff[4]:        25,24        4D                4E                4G                4F                三                4C                4B                4A
LCD_buff[2]:        29,28        2D                2E                2G                2F                2H                2C                2B                2A
LCD_buff[1]:        31,30        1D                1E                1G                1F                --                1C                1B                1A
回复 支持 反对

使用道具 举报 送花

1

主题

5

回帖

31

积分

新手上路

积分
31
发表于 2023-5-19 14:31:40 | 显示全部楼层



如上图中的寄存器,我一开始是没有理解这个表格中CxSEGVx寄存器的作用,后来反复琢磨,猜想到他的对饮关系 是不是:例如  C0SEGV0 寄存器对用的 COM0 线上的SEG0~SEG7 的这7个段,哪一个位为1,对应的LCD哪一段就亮起来。  不知道是不是这样理解的?
1684477491834.png
回复 支持 反对

使用道具 举报 送花

1

主题

5

回帖

31

积分

新手上路

积分
31
发表于 2023-5-19 14:40:36 | 显示全部楼层
xuze*** 发表于 2023-5-18 19:35
刚使用TLCD给一朋友开发的段码液晶摩托车仪表。用惯了1621驱动,刚开始感觉有点不适应,诚如楼主所言。慢 ...

非常感谢,您的思路,我试试是否可以做到。
回复 支持 反对

使用道具 举报 送花

1

主题

5

回帖

31

积分

新手上路

积分
31
发表于 2023-5-19 14:43:41 | 显示全部楼层
1684478551090.png

这就有点麻烦了;LCD屏也是按照HT1621这类驱动来做的引脚。

点评

所以说,屏的真值表很关键,基本都是确定了驱动IC,再画图设计段码,排列有规律,如果买个乱排的,用HT1621也一样要按我那样复杂处理。  详情 回复 发表于 2023-5-19 17:33
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2023-5-19 17:33:53 | 显示全部楼层
zl_*** 发表于 2023-5-19 14:43
这就有点麻烦了;LCD屏也是按照HT1621这类驱动来做的引脚。

所以说,屏的真值表很关键,基本都是确定了驱动IC,再画图设计段码,排列有规律,如果买个乱排的,用HT1621也一样要按我那样复杂处理。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 08:55 , Processed in 0.372620 second(s), 112 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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