一、简介

HT1621 是 128 点 内存映象和多功能的 LCD 驱动器 HT1621 的软件配置特性使它适用于多种 LCD 应用场合包括 LCD 模块和显示子系统。用于连接主控制器和 HT1621 的管脚只有 4 或 5 条 HT1621,还有一个节电命令用于降低系统功耗。


二、字符显示原理

液晶管点亮和熄灭原理分别为在对应的RAM地址中写1和写0。 首先需要清楚所驱动控制的液晶的COM-SEG对应关系,然后需要了解HT1621的32×4RAM地址映射。

例如要控制的液晶的装脚成品图部分如下:

着重看一个液晶数码管,我们了解原理就行。可以看到图3中是第2个液晶数码管,有7段,分别为A,B,C,D,E,F,G。也就分别为下面COM\SEG地址对应关系图中的2A,2B,2C,2D,2E,2F,2G。

液晶的显示字符的部分COM公共端输出口和SEG段输出口的分布如下表所示,同理我们可以看到例如:2D对应(SEG5,COM0),2E对应(SEG5,COM1),2F对应(SEG5,COM2),2A对应(SEG5,COM3),2C对应(SEG4,COM1),2G对应(SEG4,COM2),2B对应(SEG4,COM3)。

HT1621的RAM 地址映射如下图所示:

可以清楚的看到要控制液晶段对应SEG号作为6位地址,COM号对应作为4位数据写入,此时注意4位数据的高低位。写数据到RAM命令格式为:101+6位RAM地址+4位数据,其中RAM地址为SEG序号。

例如我们在图3的第二个液晶数码管上显示数字,首先我们根据图3得到地址映射关系,先写入地址SEG4中的四位数据(COM3,COM2,COM1,COM0),再写如地址SEG5中的四位数据(COM3,COM2,COM1,COM0),对应关系如下:

所以如果在图3中显示“5”,则在显示的液晶段对应地址上写1,不显示写0,如下图所示。所以SEG4地址应写入的数据为0110 ,SEG5地址应写入数据1101。

三、命令格式

HT1621 可以用软件设置 两种模式的命令可以配置 HT1621 和传送 LCD 所显示的数据。HT1621 的配置模式称为命令模式,命令模式类型码为 100。命令模式包括一个系统配置命令,一个系统频率选择命令,一个 LCD 配置命令,一个声音频率选择命令,一个定时器/WDT设置命令和一个操作命令。数据模式包括 READWRITEREAD-MODIFY-WRITE 操作,下表是数据和命令模式类型码表。

操作 模式 类型码
READ 数据 110
WRITE 数据 101
READ-MODIFY-RITE 数据 101
COMMAND 命令 100

模式命令应在数据或命令传送前运行。如果执行连续的命令,命令模式代码即 100,将被忽略。当系统在不连续命令模式或不连续地址数据模式下,管脚/CS 应设为 “1” 而且先前的操作模式将复位。当管脚/CS 返回 “0” 时,新的操作模式类型码应先运行。

四、时序图及程序流程




五、硬件连接

功能口 引脚
CS PB.12
DATA PB.14
WR PB.13

六、移植文件

注意:延时函数使用了FreeRTOS的vTaskDelay任务延时函数
链接:https://pan.baidu.com/s/1lXWqJIr9Q07al4H3FwNb6Q 提取码:dsuy
board_ht1621.cboard_ht1621.h 两个文件加入到工程

6.1 board_ht1621.c

/********************************************************************** INCLUDES*/
#include "FreeRTOS.h"
#include "task.h"#include "board_ht1621.h"static void gpioConfig(void);/********************************************************************** PUBLIC FUNCTIONS*/
/**@brief 初始化LCD屏,HT1621芯片@param 无@return 无
*/
void HT1621_Init(void)
{gpioConfig();vTaskDelay(10);LCD_CS_1();LCD_DATA_1();LCD_WR_1();vTaskDelay(100);                    // 延时使LCD工作电压稳定HT1621_WriteCommand(HT1621_SYS_EN); // 打开系统振荡器HT1621_WriteCommand(HT1621_BIAS);   // BIAS 13 4个公共口HT1621_WriteCommand(HT1621_RC256);  // 使用RC_256K系统时钟源,片内RC振荡器HT1621_WriteCommand(HT1621_WDT_DIS);HT1621_WriteCommand(HT1621_LCD_ON);
}/**@brief 写入命令,命令标志100@param cmd -[in] 命令数据@return 无
*/
void HT1621_WriteCommand(uint8_t cmd)
{uint8_t i;LCD_CS_0();                         // CS = 0 vTaskDelay(1);// 写入命令标志,DATA:100LCD_WR_0();                         // WR = 0vTaskDelay(1);LCD_DATA_1();                       // DATA = 1vTaskDelay(1);LCD_WR_1();                         // WR = 1vTaskDelay(1);LCD_WR_0();                         // WR = 0vTaskDelay(1);LCD_DATA_0();                       // DATA = 0vTaskDelay(1);LCD_WR_1();                         // WR = 1vTaskDelay(1);LCD_WR_0();                         // WR = 0vTaskDelay(1);LCD_DATA_0();                       // DATA = 0vTaskDelay(1);LCD_WR_1();                         // WR = 1vTaskDelay(1);// Datasheet中命令后的C8为0LCD_WR_0();                         // WR = 0vTaskDelay(1);LCD_DATA_0();                       // DATA = 0vTaskDelay(1);LCD_WR_1();                         // WR = 1vTaskDelay(1);// Datasheet中命令后的C7~C0for(i = 0; i < 8; i++){LCD_WR_0();                     // WR = 0vTaskDelay(1);if((cmd << i) & 0x80){LCD_DATA_1();               // DATA = 1}else{LCD_DATA_0();               // DATA = 0}vTaskDelay(1);LCD_WR_1();                     // WR = 1vTaskDelay(1);}LCD_CS_1();                         // CS = 1vTaskDelay(1);
}/**@brief 写入4位数据,写入数据标志101@param addr -[in] 写入起始地址@param data -[in] 写入数据,因为HT1621的数据位4位,所以实际写入数据为参数的后4位@return 无
*/
void HT1621_WriteData4Bit(uint8_t addr, uint8_t data)
{uint8_t i;LCD_CS_0();                         // CS = 0 vTaskDelay(1);// 写入数据标志,DATA:101LCD_WR_0();                         // WR = 0vTaskDelay(1);LCD_DATA_1();                       // DATA = 1vTaskDelay(1);LCD_WR_1();                         // WR = 1vTaskDelay(1);LCD_WR_0();                         // WR = 0vTaskDelay(1);LCD_DATA_0();                       // DATA = 0vTaskDelay(1);LCD_WR_1();                         // WR = 1vTaskDelay(1);LCD_WR_0();                         // WR = 0vTaskDelay(1);LCD_DATA_1();                       // DATA = 1vTaskDelay(1);LCD_WR_1();                         // WR = 1vTaskDelay(1);// 写入地址,Datasheet中A5~A0for(i = 0; i < 6; i++){LCD_WR_0();                     // WR = 0vTaskDelay(1);if((addr << i) & 0x80){LCD_DATA_1();               // DATA = 1}else{LCD_DATA_0();               // DATA = 0}vTaskDelay(1);LCD_WR_1();                     // WR = 1vTaskDelay(1);}// 写入数据,Datasheet中D0~D3for(i = 0; i < 4; i++){LCD_WR_0();                     // WR = 0vTaskDelay(1);if((data >> (3 - i)) & 0x01){LCD_DATA_1();               // DATA = 1}else{LCD_DATA_0();               // DATA = 0}vTaskDelay(1);LCD_WR_1();                     // WR = 1vTaskDelay(1);}LCD_CS_1();                         // CS = 1vTaskDelay(1);
}/**@brief 写入8位数据,写入数据标志101@param addr -[in] 写入起始地址@param data -[in] 写入数据@return 无
*/
void HT1621_WriteData8Bit(uint8_t addr, uint8_t data)
{uint8_t i;LCD_CS_0();                         // CS = 0 vTaskDelay(1);// 写入数据标志,DATA:101LCD_WR_0();                         // WR = 0vTaskDelay(1);LCD_DATA_1();                       // DATA = 1vTaskDelay(1);LCD_WR_1();                         // WR = 1vTaskDelay(1);LCD_WR_0();                         // WR = 0vTaskDelay(1);LCD_DATA_0();                       // DATA = 0vTaskDelay(1);LCD_WR_1();                         // WR = 1vTaskDelay(1);LCD_WR_0();                         // WR = 0vTaskDelay(1);LCD_DATA_1();                       // DATA = 1vTaskDelay(1);LCD_WR_1();                         // WR = 1vTaskDelay(1);// 写入地址,Datasheet中A5~A0for(i = 0; i < 6; i++){LCD_WR_0();                     // WR = 0vTaskDelay(1);if((addr << i) & 0x80){LCD_DATA_1();               // DATA = 1}else{LCD_DATA_0();               // DATA = 0}vTaskDelay(1);LCD_WR_1();                     // WR = 1vTaskDelay(1);}// 写入数据,Datasheet中两组D0~D3for(i = 0; i < 8; i++){LCD_WR_0();                     // WR = 0vTaskDelay(1);if((data >> (7 - i)) & 0x01){LCD_DATA_1();               // DATA = 1}else{LCD_DATA_0();               // DATA = 0}vTaskDelay(1);LCD_WR_1();                     // WR = 1vTaskDelay(1);}LCD_CS_1();                         // CS = 1vTaskDelay(1);
}/********************************************************************** LOCAL FUNCTIONS*/
/**@brief 引脚初始化@param 无@return 无
*/
static void gpioConfig(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(HT1621_CS_CLK|HT1621_DATA_CLK|HT1621_WR_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = HT1621_CS_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(HT1621_CS_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = HT1621_DATA_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(HT1621_DATA_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = HT1621_WR_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(HT1621_WR_PORT, &GPIO_InitStructure);
}/****************************************************END OF FILE****************************************************/

6.2 board_ht1621.h

#ifndef _BOARD_HT1621_H_
#define _BOARD_HT1621_H_/********************************************************************** INCLUDES*/
#include "stm32f10x.h"/********************************************************************** DEFINITIONS*/
#define HT1621_CS_PORT              GPIOB                   // GPIO端口
#define HT1621_CS_CLK               RCC_APB2Periph_GPIOB    // GPIO端口时钟
#define HT1621_CS_PIN               GPIO_Pin_12             // 定义HT1621的CS管脚#define HT1621_DATA_PORT            GPIOB                   // GPIO端口
#define HT1621_DATA_CLK             RCC_APB2Periph_GPIOB    // GPIO端口时钟
#define HT1621_DATA_PIN             GPIO_Pin_14             // 定义HT1621的DATA管脚#define HT1621_WR_PORT              GPIOB                   // GPIO端口
#define HT1621_WR_CLK               RCC_APB2Periph_GPIOB    // GPIO端口时钟
#define HT1621_WR_PIN               GPIO_Pin_13             // 定义HT1621的WR管脚#define LCD_CS_0()                  GPIO_ResetBits(HT1621_CS_PORT, HT1621_CS_PIN)
#define LCD_CS_1()                  GPIO_SetBits(HT1621_CS_PORT, HT1621_CS_PIN)
#define LCD_DATA_0()                GPIO_ResetBits(HT1621_DATA_PORT, HT1621_DATA_PIN)
#define LCD_DATA_1()                GPIO_SetBits(HT1621_DATA_PORT, HT1621_DATA_PIN)
#define LCD_WR_0()                  GPIO_ResetBits(HT1621_WR_PORT, HT1621_WR_PIN)
#define LCD_WR_1()                  GPIO_SetBits(HT1621_WR_PORT, HT1621_WR_PIN)#define COMMAND_CODE                0x80                    // 命令码
#define WRITE_DATA_CODE             0xA0                    // 写命令#define HT1621_BIAS                 0x52                    // 1/3duty 4com
#define HT1621_SYS_DIS              0x00                    // 关振系统荡器和LCD偏压发生器
#define HT1621_SYS_EN               0x02                    // 打开系统振荡器
#define HT1621_LCD_OFF              0x04                    // 关闭LCD偏压
#define HT1621_LCD_ON               0x06                    // 打开LCE偏压
#define HT1621_XTAL                 0x28                    // 外部接时钟
#define HT1621_RC256                0x30                    // 内部时钟
#define HT1621_WDT_DIS              0X0A                    // 关闭看门狗
#define HT1621_TONE_ON              0x12                    // 打开声音输出
#define HT1621_TONE_OFF             0x10                    // 关闭声音输出/********************************************************************** API FUNCTIONS*/
void HT1621_Init(void);
void HT1621_WriteCommand(uint8_t cmd);
void HT1621_WriteData4Bit(uint8_t addr, uint8_t data);
void HT1621_WriteData8Bit(uint8_t addr, uint8_t data);#endif /* _BOARD_HT1621_H_ */

七、使用例子

/********************************************************************** DEFINITIONS*/
#define TEMP_ADDR               0x00
#define FOURTH_8_MHz_ADDR       0x04
#define FOURTH_8_ADDR           0x08
#define THIRD_8_75us_ADDR       0x0C
#define THIRD_8_ADDR            0x10
#define SECOND_8_POINT_ADDR     0x14
#define SECOND_8_ADDR           0x18
#define FIRST_8_50us_ADDR       0x1C
#define FIRST_8_ADDR            0x20
#define FM_SOUND_1_ADDR         0x24
#define SIGNAL_ADDR             0x28#define DISPLAY_ALARM           0x03
#define DISPLAY_FM              0x04
#define DISPLAY_1_1             0x08
#define DISPLAY_MHZ             0x10HT1621_Init();
HT1621_WriteData4Bit(TEMP_ADDR, 0x00);                              // ℃灭
HT1621_WriteData4Bit(SIGNAL_ADDR, 0x00);                            // 信号灭
HT1621_WriteData4Bit(FM_SOUND_1_ADDR, DISPLAY_ALARM | DISPLAY_FM);  // 报警+FM亮
HT1621_WriteData8Bit(FOURTH_8_MHz_ADDR, DISPLAY_MHZ);               // MHz亮/**@brief LCD屏显示频率@param frequency -[in] 频率@return 无
*/
void LCD_ShowFrequency(uint32 frequency)
{calculateHundreds(frequency);                                       // 百位calculateTens(frequency);                                           // 十位calculateOnes(frequency);                                           // 个位calculateDecimals(frequency);                                       // 小数位
}/**@brief 计算频率百位,如87.5MHz,则百位0@param frequency -[in] 频率@return 无
*/
static void calculateHundreds(uint32 frequency)
{if(frequency / 100000 == 1){s_alarm |= DISPLAY_1_1;HT1621_WriteData4Bit(FM_SOUND_1_ADDR, s_alarm);                 // 1亮}else{s_alarm &= 0x07;HT1621_WriteData4Bit(FM_SOUND_1_ADDR, s_alarm);                 // 1灭}
}/**@brief 计算频率十位,如87.5MHz,则十位8@param frequency -[in] 频率@return 无
*/
static void calculateTens(uint32 frequency)
{if(frequency / 10000 % 10 == 0){HT1621_WriteData8Bit(FIRST_8_50us_ADDR, 0xAF);                  // 0}else if(frequency / 10000 % 10 == 8){HT1621_WriteData8Bit(FIRST_8_50us_ADDR, 0xEF);                  // 8}else if(frequency / 10000 % 10 == 9){HT1621_WriteData8Bit(FIRST_8_50us_ADDR, 0xED);                  // 9}
}/**@brief 计算频率个位,如87.5MHz,则个位7@param frequency -[in] 频率@return 无
*/
static void calculateOnes(uint32 frequency)
{if(frequency / 1000 % 10 == 0){HT1621_WriteData8Bit(SECOND_8_POINT_ADDR, 0xBF);                // 0.}else if(frequency / 1000 % 10 == 1){HT1621_WriteData8Bit(SECOND_8_POINT_ADDR, 0xB0);                // 1.}else if(frequency / 1000 % 10 == 2){HT1621_WriteData8Bit(SECOND_8_POINT_ADDR, 0xDB);                // 2.}   else if(frequency / 1000 % 10 == 3){HT1621_WriteData8Bit(SECOND_8_POINT_ADDR, 0xF9);                // 3.} else if(frequency / 1000 % 10 == 4){HT1621_WriteData8Bit(SECOND_8_POINT_ADDR, 0xF4);                // 4.}else if(frequency / 1000 % 10 == 5){HT1621_WriteData8Bit(SECOND_8_POINT_ADDR, 0x7D);                // 5.}else if(frequency / 1000 % 10 == 6){HT1621_WriteData8Bit(SECOND_8_POINT_ADDR, 0x7F);                // 6.}else if(frequency / 1000 % 10 == 7){HT1621_WriteData8Bit(SECOND_8_POINT_ADDR, 0xB8);                // 7.}else if(frequency / 1000 % 10 == 8){HT1621_WriteData8Bit(SECOND_8_POINT_ADDR, 0xFF);                // 8.}else if(frequency / 1000 % 10 == 9){HT1621_WriteData8Bit(SECOND_8_POINT_ADDR, 0xFD);                // 9.}
}/**@brief 计算频率小数位,如87.5MHz,则小数位5@param frequency -[in] 频率@return 无
*/
static void calculateDecimals(uint32 frequency)
{if(frequency / 100 % 10 == 0){HT1621_WriteData8Bit(THIRD_8_75us_ADDR, 0xAF);                  // 0}else if(frequency / 100 % 10 == 1){HT1621_WriteData8Bit(THIRD_8_75us_ADDR, 0xA0);                  // 1}else if(frequency / 100 % 10 == 2){HT1621_WriteData8Bit(THIRD_8_75us_ADDR, 0xCB);                  // 2}   else if(frequency / 100 % 10 == 3){HT1621_WriteData8Bit(THIRD_8_75us_ADDR, 0xE9);                  // 3} else if(frequency / 100 % 10 == 4){HT1621_WriteData8Bit(THIRD_8_75us_ADDR, 0xE4);                  // 4}else if(frequency / 100 % 10 == 5){HT1621_WriteData8Bit(THIRD_8_75us_ADDR, 0x6D);                  // 5}else if(frequency / 100 % 10 == 6){HT1621_WriteData8Bit(THIRD_8_75us_ADDR, 0x6F);                  // 6}else if(frequency / 100 % 10 == 7){HT1621_WriteData8Bit(THIRD_8_75us_ADDR, 0xA8);                  // 7}else if(frequency / 100 % 10 == 8){HT1621_WriteData8Bit(THIRD_8_75us_ADDR, 0xEF);                  // 8}else if(frequency / 100 % 10 == 9){HT1621_WriteData8Bit(THIRD_8_75us_ADDR, 0xED);                  // 9}
}

• 由 Leung 写于 2020 年 7 月 14 日

• 参考:STM32液晶显示HT1621驱动原理及程序代码
    HT1621B段码 LCD屏驱动 51单片机驱动程序
    HT1621测试程序

STM32F103学习笔记(4)——LCD段码屏HT1621使用相关推荐

  1. HT1623驱动LCD段码屏程序

    HT1623驱动LCD段码屏--STM32F103 一.简介 二.使用步骤 1.管脚初始化配置 2.HT1623数据写入和初始化配置 3.操作段码屏例程 一.简介 有关芯片相关知识和使用原理好多博主已 ...

  2. 段码LCD段码屏的驱动原理

    LCD段码屏的驱动原理是:具有偶极矩的液晶棒状分子在外加电场的作用下其排列状态发生变化,使得通过液晶显示器件的光被调制,从而呈现明与暗或秀光与不透光的显示效果.液晶显示器件中的每个显示像素都单独被电场 ...

  3. STM8驱动LCD段码屏

    在工作中遇到用stm8驱动LCD段码屏,发现很有意思,特在此记录下来.整个说明过程由液晶屏显示原理,驱动断码LCD液晶屏的方式,stm8驱动断码屏三块进行说明. 一.液晶屏显示原理 液晶是一种介于固态 ...

  4. MSP430单片机HT1261驱动LCD段码屏

    去年帮人做的一个段码屏相关的开发,网上有关这方面的资料比较少,这里写一点自己的积累. 一.参考资料 (1)http://www.51hei.com/bbs/dpj-127088-1.html (2)h ...

  5. LCD段码屏液晶屏针脚尺寸多长?

    液晶屏金属针脚尺寸长度3.5-15MM为常规尺寸,15-30MM为定制尺寸. 粗细0.5*0.3MM,PCB焊接口建议开孔0.8MM

  6. LCD段码液晶屏驱动方法介绍

    LCD段码屏的驱动基本原理是:具备偶极矩的lcd段码屏针状分子结构在另加电场的施加下其排序情况产生变化,促使根据液晶显示器件的光被调配,进而展现明与暗或透光与不透的表明实际效果.液晶显示器件中的每一个 ...

  7. 怎么点亮段码屏_段码液晶屏实现原理及应用

    什么是段码液晶屏 段码液晶或段码液晶屏,只是液晶屏的用户对于某一类液晶显示屏的一种叫法,但是在液晶行业之内,一般都称之为图案型的液晶屏,从而来区别于点阵型的液晶屏,故段码液晶屏并不是一个很严格的表述或 ...

  8. [MM32生态]如何使用不带SLCD控制器的MCU IO直接驱动段码屏

    前言 相信大家都对段码液晶屏都不陌生了,在电子大爆炸的日常生活中到处可以见到它的身影,比如在通信工具.家用电器.仪器仪表.交通工具.文教体娱.医疗保健.光阀产品等等应用领域.段码屏一般外形尺寸都在 2 ...

  9. 怎么点亮段码屏_段码LCD液晶屏驱动方法

    TFT 液晶屏: http://www.hzjingxian.com 段码 LCD 液晶屏驱动方法 段码 LCD 液晶屏驱动方法 首先,不要以为用单片机来驱动就以为段码屏是直流驱动的,其实,段码屏是交 ...

最新文章

  1. 引用参考文献_引用参考文献时应注意些什么
  2. html中after伪类原理,css :after伪类+content使用说明和方法
  3. 【Linux】一步一步学Linux——let命令(223)
  4. matlab寻找向量最小值,matlab – 在排序向量中快速搜索大于x的最小值
  5. html5支持多线程,html5 多线程
  6. 机器学习笔记九之支持向量机
  7. Make my home's PC as proxy server to surf internet
  8. java毕业设计老鹳窝旅游网源码+lw文档+mybatis+系统+mysql数据库+调试
  9. 设计模式 - 抽象工厂模式
  10. linux c: 静态库和动态库的生成和使用
  11. 2020-02-29
  12. php实现独立模块,poscms独立模块URL规则
  13. 塑造元宇宙未来的5项技术
  14. PPT精灵:批量插入图片生成幻灯片
  15. Creo教程:如何使用SQLite在Creo中创建日记应用?
  16. 数据分析01 - 规范化方法
  17. Node 引入 ESM 新方案
  18. Colorful Image Colorization原理及源码详解
  19. 计算机如何制作音乐相册,电脑电子相册制作软件 精美的音乐电子相册制作方法...
  20. 高分二号(GF-2)号卫星数据的查询下载地址和方法

热门文章

  1. iec104协议测试软件弓口虫,IEC104测试工具
  2. c语言break习题,C语言循环结构练习题.doc
  3. 目前互联网最详细的5G注册流程
  4. vue实现简单的百度接口搜索框
  5. Cocos2d-x高级开发教程:制作自己的《捕鱼达人》
  6. docker部署和使用
  7. 物联网架构和技术:如何实现物物互联和智能化控制
  8. http各种超时配置
  9. thinkpad选择启动项_联想thinkpad笔记本新老机型bios设置u盘启动详细教程
  10. 汽车驾驶盲区 无论新手老手都要看看