本帖最后由 SnailWillow 于 2021-3-31 13:15 编辑

LCD控制器TM1621/HT1621要点1)由公共输出口COM0-COM3和段输出口SEG0-SEG23控制LCD的段码;
2)3个关键数据口:
  a)CS:片选,低电平有效;
  b)WR:读写控制,上升沿从MCU读取数据;
  c)DATA:数据,命令是大端位序,数据是小端位序;
3)命令结构:3bit标识(LCD_FLAG_CMD)+9bit命令
4)写数据到RAM:3bit标识(LCD_FLAG_DATA)+6bit地址+若干bit数据(数据是小端)
定义
#define LCD_BIAS_1P2 (0<<1) //1/2偏压
  • #define LCD_BIAS_1P3 (1<<1) //1/3偏压
  • #define LCD_USE_COM2 (0<<3) //使用2个公共口
  • #define LCD_USE_COM3 (1<<3) //使用3个公共口
  • #define LCD_USE_COM4 (2<<3) //使用4个公共口
  • #define LCD_CMD_BIAS_COM (0x40) //设置公共口和偏压的命令
  • #define LCD_CMD_ON (0x6)        //打开
  • #define LCD_CMD_OFF (0x4)       //关闭
  • #define LCD_CMD_Normal (0x1C6)  //普通模式
  • #define LCD_CMD_SYS_EN (2)      //打开系统振荡器和LCD偏压发生器
  • #define LCD_CMD_SYS_DIS (0)     //关闭系统振荡器和LCD偏压发生器
  • #define LCD_RC256       (0x30)  //系统时钟源片内RC 256K振荡器
  • #define LCD_XTAL     0x28       //0b1000 0010 1000 外部接时钟
  • #define LCD_WDTDIS1  0X0A       //0b1000 0000 1010  禁止看门狗
  • #define LCD_FLAG_CMD (4)   //命令标识100
  • #define LCD_FLAG_DATA (5)  //数据标识101
  • 复制代码
    一些函数
    /**
  • * 发送大端数据
  • */
  • static void lcd_sendBeData(LcdStr* ps,u32 n, int nBit) {
  •    for (int i = nBit; --i >= 0;) {
  •       LCD_WR_L();
  •       LCD_WriteBit((n >> i) & 1);
  •       LCD_DELAY();
  •       LCD_WR_H();
  •       LCD_DELAY();
  •    }
  • }
  • /**
  • * 发送小端数据
  • */
  • static void lcd_sendLeData(LcdStr* ps,u32 n, int nBit) {
  •    for (int i = 0; i < nBit; i++) {
  •       LCD_WR_L();
  •       LCD_WriteBit((n >> i) & 1);
  •       LCD_DELAY();
  •       LCD_WR_H();
  •       LCD_DELAY();
  •    }
  • }
  • /**
  • *写命令
  • */
  • static void lcd_writeCmd(LcdStr* ps, u16 cmd) {
  •    LCD_CS_SEL();
  •    lcd_sendBeData(ps, LCD_FLAG_CMD, 3); //100
  •    lcd_sendBeData(ps, cmd, 9);
  •    LCD_CS_RELAESE();
  •    LCD_DELAY();
  • }
  • 复制代码

    初始化
    static void lcd_init(LcdStr* ps) {   ...//MCU的GPIO初始化   LCD_CS_RELAESE();//片选脚拉高   LCD_WR_H();      //读写控制拉高   LCD_DELAY();   //---------------   lcd_writeCmd(ps, LCD_CMD_BIAS_COM | LCD_USE_COM4 | LCD_BIAS_1P3);//1/3偏压 4公共口   lcd_writeCmd(ps, LCD_RC256);          //内部RC振荡   lcd_writeCmd(ps, LCD_CMD_SYS_DIS);       //关系统振荡器和LCD偏压发生器   lcd_writeCmd(ps, LCD_WDTDIS1);   lcd_writeCmd(ps, LCD_CMD_SYS_EN);       //打开系统振荡器   lcd_writeCmd(ps, LCD_CMD_Normal);   lcd_writeCmd(ps, LCD_CMD_ON);           //开LCD偏压   lcd_clearAll(ps); //清除屏幕数据,就是全部写0}
    显示
    /**
  • * 显示所有
  • */
  • static void lcd_showAll(LcdStr* ps) {
  •    LCD_CS_SEL();
  •    lcd_sendBeData(ps, LCD_FLAG_DATA, 3); //标识101
  •    lcd_sendBeData(ps, ps->startSeg, 6); //地址
  •    for (int s = 0; s < 4; s++) {
  •       lcd_sendLeData(ps, ps->lcds >> (s * 8), 8);
  •    }
  •    LCD_CS_RELAESE();
  •    LCD_DELAY();
  • }
  • 复制代码

    清除
    /**
  • *清除屏幕
  • */
  • static void lcd_clearAll(LcdStr* ps) {
  •    LCD_CS_SEL();
  •    lcd_sendBeData(ps, LCD_FLAG_DATA, 3);
  •    lcd_sendBeData(ps, 0, 6); //地址
  •    for (int s = 0; s < 16; s++) {
  •       lcd_sendLeData(ps, 0, 8);
  •    }
  •    LCD_CS_RELAESE();
  •    LCD_DELAY();
  • }
  • 复制代码