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();
}
|