zl_diy 发表于 2023-5-18 13:50:47

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

1. 下载了官网提供的 断码LCD程序,发现里面对显示寄存器操作有点复杂。


/****************** 对第1~5数字装载显示函数 ***************************/
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};

u8      code T_LCD_mask= {0x00,0x0C,0x30,0xC0,0x03,0x0C};
u8      code T_LCD_mask7 = {0x00,0x04,0x10,0x40,0x01,0x04};
u8      code T_SEG_ABC   = {0x00,0x08,0x20,0x80,0x02,0x08};
u8      code T_SEG_DEFG= {0x00,0x04,0x10,0x40,0x01,0x04};

/********************** 装载显示5个8字 *****************************/
void      LCD_load(u8 n, u8 dat)                //n为第几个数字,为1~5,dat为要显示的数字
{
      u8      i,k;

      if((n == 0) || (n >= 6))      return;      //合法值 1~5

      dat =t_display; //3F
      k   = ~T_LCD_mask; //FF

      if(n <= 3)      //1~3
      {
                LCD_buff &= ~T_LCD_mask7; //FF
                LCD_buff &= k; //NC
                LCD_buff &= k; //NC
                LCD_buff &= k; //NC
                i = T_SEG_ABC;//00
                k = T_SEG_DEFG;//00
                if(dat & 0x01)                LCD_buff |= i;      //T_SEG_ABC;                //A
                if(dat & 0x02)                LCD_buff |= i;      //T_SEG_ABC;                //B
                if(dat & 0x04)                LCD_buff |= i;      //T_SEG_ABC;                //C
                if(dat & 0x08)                LCD_buff |= k;      //T_SEG_DEFG;      //D
                if(dat & 0x10)                LCD_buff |= k;      //T_SEG_DEFG;      //E
                if(dat & 0x20)                LCD_buff |= k;      //T_SEG_DEFG;      //F
                if(dat & 0x40)                LCD_buff |= k;      //T_SEG_DEFG;      //G
      }
      else      // n=4 or 5
      {
                LCD_buff &= ~T_LCD_mask7;
                LCD_buff &= k;
                LCD_buff &= k;
                LCD_buff &= k;
                i = T_SEG_ABC;
                k = T_SEG_DEFG;
                if(dat & 0x01)                LCD_buff |= i;      //T_SEG_ABC;                //A
                if(dat & 0x02)                LCD_buff |= i;      //T_SEG_ABC;                //B
                if(dat & 0x04)                LCD_buff |= i;      //T_SEG_ABC;                //C
                if(dat & 0x08)                LCD_buff |= k;      //T_SEG_DEFG;      //D
                if(dat & 0x10)                LCD_buff |= k;      //T_SEG_DEFG;      //E
                if(dat & 0x20)                LCD_buff |= k;      //T_SEG_DEFG;      //F
                if(dat & 0x40)                LCD_buff |= k;      //T_SEG_DEFG;      //G
      }
}


/********************** 将显示内容导入显存 *****************************/
void      LoadToLcd(void)
{
      C0SEGV1 = LCD_buff;    // C0SEG 15~8数据寄存器
      C0SEGV2 = LCD_buff;    // C0SEG 23~16数据寄存器
      C1SEGV1 = LCD_buff;    // C1SEG 15~8数据寄存器
      C1SEGV2 = LCD_buff;    // C1SEG 23~16数据寄存器
      C2SEGV1 = LCD_buff;    // C2SEG 15~8数据寄存器
      C2SEGV2 = LCD_buff;    // C2SEG 23~16数据寄存器
      C3SEGV1 = LCD_buff;    // C3SEG 15~8数据寄存器
      C3SEGV2 = LCD_buff;    // C3SEG 23~16数据寄存器
}
前面对buf的数据处理逻辑比较复杂,最后将数据传入到 CxSEGVx寄存器中。 这段过程一直没有理解;
2. 之前用过TM1621这类的驱动,不知道咱们的这个驱动方式是否和这类芯片类似?如果不相同,应该怎么理解 这些寄存器的作用? 尤其是CxSEGVx寄存器。

电子DIY小家 发表于 2023-5-18 14:11:25

区别于数码管,段码的连接一般不是整组接在位或者段上的。
数码管可能八个段码刚好占用一个P1端口,但是LCD你仔细看提供的段码表,你可以推理下如果要点亮一个数字2需要哪几个位输出,算出来了这个数值,在来看这个程序你就懂了

zl_diy 发表于 2023-5-18 16:24:32

电子DIY小家 发表于 2023-5-18 14:11
区别于数码管,段码的连接一般不是整组接在位或者段上的。
数码管可能八个段码刚好占用一个P1端口,但是LCD ...

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

32位8051-AI 发表于 2023-5-18 17:12:57


xuzeabc 发表于 2023-5-18 19:35:57

本帖最后由 xuzeabc 于 2023-5-18 19:39 编辑

zl_diy 发表于 2023-5-18 16:24
数码管是了解的;TM1621这类专用LCD断码驱动屏,是每次发4个bit数据,发两次正好可以对应一个显示数字; ...
刚使用TLCD给一朋友开发的段码液晶摩托车仪表。用惯了1621驱动,刚开始感觉有点不适应,诚如楼主所言。慢慢的使用过程中,感觉操作起来比1621便宜不少。使用1621为了驱动不同种类的8,用了很多数组,使用单片机,一个数组完成工作。
把段码的数据定义在了bdata处,用联合体和结构体,可以进行位操作,也可以进行字节操作,方便多多。希望对楼主有参考。

梁工 发表于 2023-5-18 22:02:28

zl_diy 发表于 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 &= 0x0f;        LCD_buff &= 0xf8;
                i = t_display;
                if(i & 0x01)        LCD_buff |= 0x10;        //A
                if(i & 0x02)        LCD_buff |= 0x01;        //B
                if(i & 0x04)        LCD_buff |= 0x04;        //C
                if(i & 0x08)        LCD_buff |= 0x80;        //D
                if(i & 0x10)        LCD_buff |= 0x40;        //E
                if(i & 0x20)        LCD_buff |= 0x20;        //F
                if(i & 0x40)        LCD_buff |= 0x02;        //G
                HT1621_write_byte(2,LCD_buff);
                HT1621_write_byte(4,LCD_buff);
        }
        else if(n == 2)
        {
                LCD_buff &= 0x0f;        LCD_buff &= 0xf8;
                i = t_display;
                if(i & 0x01)        LCD_buff |= 0x10;        //A
                if(i & 0x02)        LCD_buff |= 0x01;        //B
                if(i & 0x04)        LCD_buff |= 0x04;        //C
                if(i & 0x08)        LCD_buff |= 0x80;        //D
                if(i & 0x10)        LCD_buff |= 0x40;        //E
                if(i & 0x20)        LCD_buff |= 0x20;        //F
                if(i & 0x40)        LCD_buff |= 0x02;        //G
                HT1621_write_byte(4,LCD_buff);
                HT1621_write_byte(6,LCD_buff);
        }
}

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

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

zl_diy 发表于 2023-5-19 14:31:40




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

zl_diy 发表于 2023-5-19 14:40:36

xuzeabc 发表于 2023-5-18 19:35
刚使用TLCD给一朋友开发的段码液晶摩托车仪表。用惯了1621驱动,刚开始感觉有点不适应,诚如楼主所言。慢 ...

非常感谢,您的思路,我试试是否可以做到。

zl_diy 发表于 2023-5-19 14:43:41



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

梁工 发表于 2023-5-19 17:33:53

zl_diy 发表于 2023-5-19 14:43
这就有点麻烦了;LCD屏也是按照HT1621这类驱动来做的引脚。

所以说,屏的真值表很关键,基本都是确定了驱动IC,再画图设计段码,排列有规律,如果买个乱排的,用HT1621也一样要按我那样复杂处理。
页: [1] 2 3 4
查看完整版本: 8H4K64TLCD驱动段码LCD的寄存器咨询