目录
1、根据时序图了解通讯协议格式
2、写驱动函数
HT1622数据手册(嘉立创)
1、根据时序图了解通讯协议格式
根据HT1622数据手册中的时序图可知:
1)从N1处可知,当CS处于低电平时,WR才有效。
2)从N2处可知,当CS处于低电平,且当WR脚处于上升沿时,DATA才有效。
3)从N3处可知,向HT1622传送指令的通讯协议格式为:3位命令标识+9位指令。
4)从N4处可知,向HT1622传送数据的通讯协议格式为:3位命令标识+6位地址+4位数据。
5)从N5处可知,向HT1622连续传送多组数据,后续数据会自动更新写入到下一个地址。
6)从N3/N4/N5处可知,向HT1622写入数据时,指令和地址是从高位写入,数据是从低位写入。
2、写驱动函数
由HT1622 RAM映射表可知,SEGx 和 其首地址Addr 的关系(Addr = SEGx * 2),是连续映射的。所以在写入数据时,可以使用SEGx代替地址,一次写入8位数据(控制SEGx下的8个COM),能更简洁直观地对断码屏进行操作。注意,有的屏幕供应商提供的DataSheet,SEG是从1开始计数,而不是0。(我手中断码屏DataSheet(如下图)的就是从1开始计数)
写驱动函数:
*注:我的工程中移植了RT_Thread,故延时函数使用的是 rt_thread_delay();
#define DISPLAY 1 // 显示
#define HIDE 0 // 隐藏// 定义数据IO口
#define ScreenBLED_ON Screen_BLED_GPIO_Port->BSRR = Screen_BLED_Pin // 开启屏幕背光
#define ScreenBLED_OFF Screen_BLED_GPIO_Port->BRR = Screen_BLED_Pin // 关闭屏幕背光
#define ScreenCS_H Screen_CS_GPIO_Port->BSRR = Screen_CS_Pin // 将CS拉高
#define ScreenCS_L Screen_CS_GPIO_Port->BRR = Screen_CS_Pin // 将CS拉低
#define ScreenWR_H Screen_WR_GPIO_Port->BSRR = Screen_WR_Pin // 将WR拉高
#define ScreenWR_L Screen_WR_GPIO_Port->BRR = Screen_WR_Pin // 将WR拉低
#define ScreenDATA_H Screen_DATA_GPIO_Port->BSRR = Screen_DATA_Pin // 将DATA拉高
#define ScreenDATA_L Screen_DATA_GPIO_Port->BRR = Screen_DATA_Pin // 将DATA拉低// 定义指令代码
#define SYSDIS 0x00 // 0b 0000 0000 关闭系统振荡器和LCD偏压发生器
#define SYSEN 0x01 // 0b 0000 0001 打开系统振荡器
#define LCDOFF 0x02 // 0b 0000 0010 关闭LCD偏压
#define LCDON 0x03 // 0b 0000 0011 打开LCD偏压
#define WDTDIS 0x05 // 0b 0000 0101 禁止看门狗
#define RC32K 0x18 // 0b 0001 1000 内部时钟
#define TONEOFF 0x08 // 0b 0000 1000 关闭声音输出// "8"形状数码屏数字定义
uint8_t NumData[10] = {0xEE, 0x24, 0xD6, 0xB6, 0x3C, 0xBA, 0xFA, 0x26, 0xFE, 0xBE}; // 0~9// 定义显示数字区域的SEGx,从低位到高位
uint8_t SEG_ShowNum[4] = {6, 5, 4, 3};//===========================================================================
// 函数名: WrBit_H
// 功能 : 将数据data从高位开始(高-->低),写入cnt位
// 参数 : data:写入的数据;cnt:写入位数
// 返回值: none
//===========================================================================
void WrBit_H(uint8_t data, uint8_t cnt)
{uint8_t i;for (i = 0; i < cnt; i++){ScreenWR_L;rt_thread_delay(1);if (data & 0x80)ScreenDATA_H;elseScreenDATA_L;rt_thread_delay(1);ScreenWR_H;rt_thread_delay(1);data <<= 1;}
}//===========================================================================
// 函数名: WrBit_L
// 功能 : 将数据data从低位开始(高<--低),写入cnt位
// 参数 : data:写入的数据;cnt:写入位数
// 返回值: none
//===========================================================================
void WrBit_L(uint8_t data, uint8_t cnt)
{uint8_t i;for (i = 0; i < cnt; i++){ScreenWR_L;rt_thread_delay(1);if (data & 0x01)ScreenDATA_H;elseScreenDATA_L;rt_thread_delay(1);ScreenWR_H;rt_thread_delay(1);data >>= 1;}
}//===========================================================================
// 函数名: HT1622WrCmd
// 功能 : 向HT1622写入指令
// 参数 : Cmd:指令代码
// 返回值: none
//===========================================================================
void HT1622WrCmd(uint8_t Cmd)
{ScreenCS_L;rt_thread_delay(1);WrBit_H(0x80, 3); // 写入命令标志WrBit_H(Cmd, 9); // 写入命令数据ScreenCS_H;rt_thread_delay(1);
}//===========================================================================
// 函数名: HT1622WrData
// 功能 : 向HT1622的SEGx写入8位数据(直接控制SEGx下的所有内容)
// 参数 : SEGx:数据映射表中的SEGx列;Data:要写入的控制数据
// 返回值: none
//===========================================================================
void HT1622WrData(uint8_t SEGx, uint16_t Data)
{uint8_t Addr;Addr = (SEGx - 1) * 2;ScreenCS_L;rt_thread_delay(1);WrBit_H(0xA0, 3); // 写入数据标志WrBit_H(Addr << 2, 6); // 写入6位地址WrBit_L(Data, 8); // 写入8位数据ScreenCS_H;rt_thread_delay(1);
}//===========================================================================
// 函数名: FullScreenContent
// 功能 : 控制全屏的内容为 显示/隐藏
// 参数 : state:显示状态(DISPLAY/HIDE)
// 返回值: none
//===========================================================================
void FullScreenContent(uint8_t state)
{ScreenCS_L;rt_thread_delay(1);WrBit_H(0xA0, 3); // 写入数据标志WrBit_H(0x00, 6); // 写入6位地址// 对所有地址写入数据 1/0 —— DISPLAY/HIDEfor (uint16_t i = 0; i < 8 * 32; i++){ScreenWR_L;rt_thread_delay(1);if (state)ScreenDATA_H;elseScreenDATA_L;rt_thread_delay(1);ScreenWR_H;rt_thread_delay(1);}ScreenCS_H;rt_thread_delay(1);
}//===========================================================================
// 函数名: DisplayNum
// 功能 : 在段码屏的数字显示区域SEG_ShowNum显示数字
// 参数 : Num:要显示的多位数
// 返回值: none
//===========================================================================
void DisplayNum(uint16_t Num)
{for (uint8_t i = 0; i < sizeof(SEG_ShowNum); i++){if ((Num == 0) && (i != 0))HT1622WrData(SEG_ShowNum[i], 0x00);elseHT1622WrData(SEG_ShowNum[i], NumData[Num % 10]);Num /= 10;}
}//===========================================================================
// 函数名: Screen_Init
// 功能 : 屏幕初始化
// 参数 : none
// 返回值: none
//===========================================================================
void Screen_Init(void)
{ScreenCS_H;ScreenWR_H;ScreenDATA_H;ScreenBLED_ON;rt_thread_mdelay(1000);HT1622WrCmd(RC32K);HT1622WrCmd(SYSEN);HT1622WrCmd(LCDON);FullScreenContent(HIDE);// 测试例程:倒数计数显示for (int16_t i = 110; i >= 0; i--){rt_thread_delay(10);DisplayNum(i);}
}
测试例程:倒数计数显示效果
段码屏倒数显示效果