PIC 18f45k80单片机通过HT1621驱动LCD显示

2019-04-15 11:49发布

ht1621.c
// SendBit_1621(送数据程序) void SendBit_1621(u8 sdata,u8 cnt) //data 的高cnt 位写入HT1621,高位在前 { unsigned char i; for (i = 0; i < cnt; i++) { CLEAR_HT1621_WR(); if (sdata & 0x80) { SET_HT1621_DATA(); } else { CLEAR_HT1621_DATA(); } SET_HT1621_WR(); sdata <<= 1; } } // SendCmd(送命令) void SendCmd_1621(u8 command) { CLEAR_HT1621_CS(); // 直接将command 的最高位写“0” SendBit_1621(0x80,4); // 写入标志码“100”和9 位command 命令,由于 SendBit_1621(command,8); // 没有使有到更改时钟输出等命令,为了编程方便 SET_HT1621_CS(); } //Write_1621(送数据和命令程序) void Write_1621(u8 addr,u8 sdata) { CLEAR_HT1621_CS(); SendBit_1621(0xa0,3); //写入标志码“101” SendBit_1621(addr,6); //写入addr 的高6位 SendBit_1621(sdata,4); //写入data 的4位 SET_HT1621_CS(); } // all_off(清除1621显示) void HT1621_all_off(void) {     unsigned char i; u8 addr = 0;     for (i = 0; i < 32; i++)     { Write_1621(addr<<2,0x00); addr++;     } } // all_on(全部点亮1621) void HT1621_data(u8 *data,u8 size) {     unsigned char i;     unsigned char addr = 0;     for (i = 0; i < size; i++)     {         Write_1621(addr,data[i]);         addr++;     } } // Init_1621(初始化1621) void HT1621_init(void) {     HT1621_CS_PIN_DIR_OUT();     HT1621_DATA_PIN_DIR_OUT();     HT1621_WR_PIN_DIR_OUT();     SET_HT1621_WR();     SET_HT1621_CS();     SendCmd_1621(BIAS);     SendCmd_1621(RC256);     SendCmd_1621(SYSEN);     SendCmd_1621(LCDON);     SendCmd_1621(TONE2K);     CleraLcdBuffer();                        /// 关闭所有显示 } ht1621.h#define HT1621_CS (0X01 << 1) #define HT1621_DATA         0X01 #define HT1621_WR (0X01 << 3) #define HT1621_CS_PIN_DIR_OUT()         TRISC &= ~(HT1621_CS) // CS管脚设置为输出 #define SET_HT1621_CS() (PORTCbits.RC1 = 1) #define CLEAR_HT1621_CS() (PORTCbits.RC1 = 0) #define HT1621_DATA_PIN_DIR_OUT()         TRISC &= ~(HT1621_DATA) // DATA管脚设置为输出 #define SET_HT1621_DATA() (PORTCbits.RC0 = 1) #define CLEAR_HT1621_DATA()         (PORTCbits.RC0 = 0) #define HT1621_WR_PIN_DIR_OUT()         TRISC &= ~(HT1621_WR) // WR管脚设置为输出 #define SET_HT1621_WR() (PORTCbits.RC3 = 1) #define CLEAR_HT1621_WR()     (PORTCbits.RC3 = 0) #define BIAS 0x52 // 1/3偏压 #define RC256 0x30 // 256k 时钟 #define SYSEN 0x02 // 开启系统振荡器 #define SYSDIS 0x00 // 关闭系统振荡器 #define LCDON 0x06 // 开启LCD偏压产生器 #define LCDOFF 0x04 // 关闭LCD偏压产生器 #define TONE4K 0x80 #define TONE2K 0xC0lcd.c/// 数码管相关数据static struct ValueTAB const Value[20]= { {_F|_E|_D,_A|_B|_C},         // 0 {0,_B|_C}, // 1 {_E|_D|_G,_A|_B}, // 2 {_D|_G,_A|_B|_C}, // 3 {_F|_G,_B|_C}, // 4 {_F|_D|_G,_A|_C}, // 5 {_F|_E|_D|_G,_A|_C},         // 6 {0,_A|_B|_C}, // 7 {_F|_E|_D|_G,_A|_B|_C},         // 8 {_F|_D|_G,_A|_B|_C},         // 9 {_F|_E|_G,_A|_B|_C},         // a {_F|_E|_D|_G,_C}, // b {_F|_E|_D,_A}, // c {_E|_D|_G,_B|_C}, // d {_F|_E|_D|_G,_A}, // e {_F|_E|_G,_A}, // f {_F|_E|_G,_A|_B}, // P {_G,0}, // - {0,0} // null };/// 清除屏幕所有显示void CleraLcdBuffer(void) {   u8 i;   for (i = 0; i< 32; i++)   {   LcdBuffer[i] = 0;   }   HT1621_all_off(); }lcd.h#define COM4 (0X01<<4) #define COM3 (0X02<<4) #define COM2 (0X04<<4) #define COM1 (0X08<<4) #define _A COM1 #define _B COM2 #define _C COM3 #define _D COM4 #define _E COM3 #define _F COM1 #define _G COM2 #define SIG_REF 0 // SIG0起始引脚 /***********************************/ #define SIG(uchar) uchar-SIG_REF // 引脚——LCD缓冲区映射 #define SIG_ADDR(uchar) (SIG(uchar))<<2 // 引脚——HT1621数据地址映射 #define ENABLE_BIT(a) Write_1621(((a/4)-SIG_REF)<<2,(LcdBuffer[(a/4)-SIG_REF] |= ((1 << ((a%4)))<<4))) // 显示单个码段 #define DISABLE_BIT(a) Write_1621(((a/4)-SIG_REF)<<2,(LcdBuffer[(a/4)-SIG_REF] &= ~((1<<((a%4)))<<4)))     // 清除单个码段 #define CPL_BIT(a) Write_1621(((a/4)-SIG_REF)<<2,(LcdBuffer[(a/4)-SIG_REF] ^= ((1<<((a%4)))<<4))) #define _NULL 18 /// 蜂鸣器操作 #define ENABLE_BELL() SendCmd_1621(0x12) #define DISABLE_BELL() SendCmd_1621(0x10) #define CPL_BELL() SendCmd_1621((Bell^=2)) #define LED_P 16 #define LED_E 0x0e #define LED_MINUS 17