#include "includes.h" // 是否自检屏状态 u8 self_check_state = 0; // 显示缓冲区 TVideoBuf VideoBuf = {0}; TVideoBuf Last_VideoBuf = {0}; // 定义7段字库编码 // |-A-| // F B // |-G-| // E C // |-D-| typedef struct { unsigned A : 1; unsigned B : 1; unsigned C : 1; unsigned D : 1; unsigned E : 1; unsigned F : 1; unsigned G : 1; unsigned : 1; } TChar; // 字库,不带小数点或单位 const TChar CLib[] = { {0, 0, 0, 0, 0, 0, 0}, // ' ' {0, 0, 0, 0, 0, 0, 1}, // '-' {0, 1, 1, 0, 0, 0, 1}, // '+' = '-|' {1, 0, 0, 0, 0, 0, 0}, // '^' {1, 1, 1, 0, 1, 1, 1}, // 'A' {0, 0, 1, 1, 1, 1, 1}, // 'b' {0, 0, 0, 1, 1, 0, 1}, // 'c' {0, 1, 1, 1, 1, 0, 1}, // 'd' {1, 0, 0, 1, 1, 1, 1}, // 'E' {1, 0, 0, 0, 1, 1, 1}, // 'F' {1, 0, 1, 1, 1, 1, 0}, // 'G' {0, 0, 1, 0, 1, 1, 1}, // 'h' {0, 0, 0, 0, 1, 1, 0}, // 'I' {0, 1, 1, 1, 0, 0, 0}, // 'J' {0, 0, 0, 1, 0, 0, 0}, // 'K' = '_' {0, 0, 0, 1, 1, 1, 0}, // 'L' {0, 0, 0, 1, 0, 0, 0}, // 'M' = '_' {0, 0, 1, 0, 1, 0, 1}, // 'n' {0, 0, 1, 1, 1, 0, 1}, // 'o' {1, 1, 0, 0, 1, 1, 1}, // 'P' {1, 1, 1, 0, 0, 1, 1}, // 'q' {0, 0, 0, 0, 1, 0, 1}, // 'r' {1, 0, 1, 1, 0, 1, 1}, // 'S' {0, 0, 1, 0, 0, 0, 1}, // 't' {0, 1, 1, 1, 1, 1, 0}, // 'U' {0, 1, 0, 0, 1, 1, 1}, // 'V' {0, 0, 0, 1, 0, 0, 0}, // 'W' = '_' {0, 0, 0, 1, 0, 0, 0}, // 'X' = '_' {0, 1, 1, 1, 0, 1, 1}, // 'y' {0, 0, 0, 1, 0, 0, 0}, // 'Z' = '_' {1, 1, 1, 1, 1, 1, 0}, // '0' {0, 1, 1, 0, 0, 0, 0}, // '1' {1, 1, 0, 1, 1, 0, 1}, // '2' {1, 1, 1, 1, 0, 0, 1}, // '3' {0, 1, 1, 0, 0, 1, 1}, // '4' {1, 0, 1, 1, 0, 1, 1}, // '5' {1, 0, 1, 1, 1, 1, 1}, // '6' {1, 1, 1, 0, 0, 0, 0}, // '7' {1, 1, 1, 1, 1, 1, 1}, // '8' {1, 1, 1, 1, 0, 1, 1}, // '9' }; // 字符在字库中的编码 typedef enum { CODE_SPACE, CODE_MINUS, CODE_PLUS, CODE_EXP, CODE_A, CODE_B, CODE_C, CODE_D, CODE_E, CODE_F, CODE_G, CODE_H, CODE_I, CODE_J, CODE_K, CODE_L, CODE_M, CODE_N, CODE_O, CODE_P, CODE_Q, CODE_R, CODE_S, CODE_T, CODE_U, CODE_V, CODE_W, CODE_X, CODE_Y, CODE_Z, CODE_0, CODE_1, CODE_2, CODE_3, CODE_4, CODE_5, CODE_6, CODE_7, CODE_8, CODE_9 } TCode; TCode HT1621_Char2Code(char c) { if(c >= '0' && c <= '9') return CODE_0 + (c - '0'); if(c >= 'a' && c <= 'z') return CODE_A + (c - 'a'); if(c >= 'A' && c <= 'Z') return CODE_A + (c - 'A'); if(c == '-') return CODE_MINUS; if(c == '+') return CODE_PLUS; if(c == '^') return CODE_EXP; return CODE_SPACE; } // pin_no: 1~32 // com_no: 1~4 void HT1621_WriteBuf(u16 pin_com, u8 bit_val) { uint8_t byte_index, bit_index; uint8_t pin_no = pin_com / 10; uint8_t com_no = pin_com % 10; if(pin_no < 1 || pin_no > 25) return; if(com_no < 1 || com_no > 6) return; byte_index = pin_no - 1; bit_index = com_no - 1; // COM6高位,COM1低位 if(bit_val) VideoBuf.buf[byte_index] |= (1 << bit_index); else VideoBuf.buf[byte_index] &= ~(1 << bit_index); } // 写一个七段码字符 // pin_comA = (A段的pin_no) * 10 + (A段的com_no) void HT1621_WriteChar(char c, u16 pin_comA, u16 pin_comB, u16 pin_comC, u16 pin_comD, u16 pin_comE, u16 pin_comF, u16 pin_comG) { TCode code = HT1621_Char2Code(c); HT1621_WriteBuf(pin_comA, CLib[code].A); HT1621_WriteBuf(pin_comB, CLib[code].B); HT1621_WriteBuf(pin_comC, CLib[code].C); HT1621_WriteBuf(pin_comD, CLib[code].D); HT1621_WriteBuf(pin_comE, CLib[code].E); HT1621_WriteBuf(pin_comF, CLib[code].F); HT1621_WriteBuf(pin_comG, CLib[code].G); } // 写一个七段码数据 // pin_comA = (A段的pin_no) * 10 + (A段的com_no) void HT1621_Write7Seg(u8 val, u16 pin_comA, u16 pin_comB, u16 pin_comC, u16 pin_comD, u16 pin_comE, u16 pin_comF, u16 pin_comG) { HT1621_WriteBuf(pin_comA, val & 1); val >>= 1; HT1621_WriteBuf(pin_comB, val & 1); val >>= 1; HT1621_WriteBuf(pin_comC, val & 1); val >>= 1; HT1621_WriteBuf(pin_comD, val & 1); val >>= 1; HT1621_WriteBuf(pin_comE, val & 1); val >>= 1; HT1621_WriteBuf(pin_comF, val & 1); val >>= 1; HT1621_WriteBuf(pin_comG, val & 1); } /////////////////////////////////////////////////////////////////////////////////// // 以下定义适用于HT16L23驱动芯片 //命令 #define WRITE_LCD 0x80 #define DRIVE_MODE_CMD 0x82 #define SYS_MODE_CMD 0x84 #define FRQ_CMD 0x86 #define BLINK_FRQ_CMD 0x88 #define VOL_SET_CMD 0x8a //参数定义 #define BIAS_LCD 0x34 // 驱动模式 SEG40*8com显示段位模式 1/8duty 1/3bias #define SYS_MODE_LCD 0x03 //显示和内部晶振都打开 #define FRQ_LCD 0x02 //3--128HZ 2--64 #define BLINK_FRQ_LCD 0x00 //blinking off #define VOL_LCD 0x02 //1--内部V 电压3.3v /////////////////////////////////////////////////////////////////////////////////// void HT1621_Delay() { __NOP(); } // 通讯定义 #define HT1621_CS_EN() \ { \ LL_GPIO_ResetOutputPin(GPIOD, LL_GPIO_PIN_12); \ HT1621_Delay(); \ } #define HT1621_CS_DIS() \ { \ LL_GPIO_SetOutputPin(GPIOD, LL_GPIO_PIN_12); \ HT1621_Delay(); \ } #define HT1621_CLK_LOW() \ { \ LL_GPIO_ResetOutputPin(GPIOD, LL_GPIO_PIN_13); \ HT1621_Delay(); \ } #define HT1621_CLK_HIGH() \ { \ LL_GPIO_SetOutputPin(GPIOD, LL_GPIO_PIN_13); \ HT1621_Delay(); \ } #define HT1621_DATA_1() \ { \ LL_GPIO_SetOutputPin(GPIOD, LL_GPIO_PIN_14); \ HT1621_Delay(); \ } #define HT1621_DATA_0() \ { \ LL_GPIO_ResetOutputPin(GPIOD, LL_GPIO_PIN_14); \ HT1621_Delay(); \ } // 写 1 bit void HT1621_Bit(u8 b1) { HT1621_CLK_LOW(); if(b1) { HT1621_DATA_1(); } else { HT1621_DATA_0(); } HT1621_CLK_HIGH(); } // 写多个bits void HT1621_Bits(u8 byte, u8 num) { while(num--) { HT1621_Bit(byte & 0x80); byte <<= 1; } } // 写命令 void HT1621_Cmd(u8 cmd, u8 val) { // 片选 HT1621_CS_EN(); HT1621_Bits(cmd, 8); HT1621_Bits(val, 8); // 取消片选 HT1621_CS_DIS(); } // 设置参数 void HT1621_SetParams() { HT1621_Cmd(DRIVE_MODE_CMD, BIAS_LCD); HT1621_Cmd(VOL_SET_CMD, VOL_LCD); //使用内部振荡器 HT1621_Cmd(FRQ_CMD, FRQ_LCD); HT1621_Cmd(BLINK_FRQ_CMD, BLINK_FRQ_LCD); HT1621_Cmd(SYS_MODE_CMD, SYS_MODE_LCD); } // 刷新整个显示屏内容 void HT1621_Refresh() { u8 i; // 比较显示内容和标志位,如无改变则不操作 if(memcmp(&VideoBuf, &Last_VideoBuf, sizeof(VideoBuf)) == 0) return; // 保存显示内容和标志位 Last_VideoBuf = VideoBuf; // 处理闪烁,根据标志位临时改变显示内容 if(!self_check_state && !VideoBuf.blink_visible) { // 隐藏数字(显示界面) if(VideoBuf.fld1_blink) // 显示1 { Disp_Fld1Text(" "); Disp_Fld1PointOff(); } if(VideoBuf.fld2_blink) // 显示2 { Disp_Fld2Text(" "); Disp_Fld2PointOff(); } if(VideoBuf.fld3_blink) // 显示3 { Disp_Fld3Text(" "); Disp_Fld3PointOff(); } if(VideoBuf.fld4_blink) // 显示4 { Disp_Fld4Text(" "); Disp_Fld4PointOff(); } if(VideoBuf.battery_blink) // 电池 Disp_WriteBattery(0); // 光标闪烁(配置界面) for(i = 0; i < VideoBuf.cursor_width; i++) Disp_DispChar(VideoBuf.cursor_pos + i, ' '); } // 片选 HT1621_CS_EN(); HT1621_Bits(WRITE_LCD, 8); // cmd HT1621_Bits(0, 8); // addr for(i = 0; i < sizeof(VideoBuf.buf); i++) HT1621_Bits(VideoBuf.buf[i], 8); // 取消片选 HT1621_CS_DIS(); // 恢复显示内容和标志位 VideoBuf = Last_VideoBuf; } // 整个屏幕全熄灭 void HT1621_AllOff() { self_check_state = 1; memset(VideoBuf.buf, 0x00, sizeof(VideoBuf.buf)); // 不影响最后的状态 HT1621_Refresh(); self_check_state = 0; } // 整个屏幕全点亮 void HT1621_AllOn() { self_check_state = 1; memset(VideoBuf.buf, 0xFF, sizeof(VideoBuf.buf)); // 不影响最后的状态 HT1621_Refresh(); self_check_state = 0; } void LCD_Init() { LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); /**/ LL_GPIO_SetOutputPin(GPIOD, LL_GPIO_PIN_11|LL_GPIO_PIN_12|LL_GPIO_PIN_13|LL_GPIO_PIN_14); /**/ GPIO_InitStruct.Pin = LL_GPIO_PIN_11|LL_GPIO_PIN_12|LL_GPIO_PIN_13|LL_GPIO_PIN_14; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; LL_GPIO_Init(GPIOD, &GPIO_InitStruct); } void LCD_MyOpen() { HT1621_SetParams(); }