【STM32】_02_使用HT1621B驱动段码液晶屏

一、简介

1.1 什么是段码液晶屏

详细的介绍可以看这位博主的帖子:那头时空
着急的朋友就不用看了,简单来说段码液晶屏的驱动需要交流电,有些MCU会自带LCD液晶驱动,而通常我们则会采用像HT1621B这样的LCD驱动器来控制段码屏。

1.2 HT1621B

在这里插入图片描述
简单来说,HT1621B最多可以控制具有128个显示点位的段码屏,与MCU之间的通信仅需三线即可CS片选线,低电平有效、WR写时钟线,上升沿写入、DATA线,串行数据输入/输出
详细的内容请看数据手册:HT1621B数据手册

二、HT1621B的驱动电路

最简单的连接方式就是将段码屏SEG0-SEG13(我这个屏SEG脚有14个,这种屏都是定制的,具体你要用几个脚要看你定制的屏有几个) 和HT1621B的SEG0-SEG13按照顺序对应的连到一起 (如果你的硬件是乱序相连的,那你就只能在软件上进行一下转换了,也就是你写入数据的地址可能不是从0开始的,也可能不连续),将段码屏COM0-COM3和HT1621B的COM0-COM3按照顺序对应的连到一起 。将HT1621B的CS、WR、DATA与MCU的3个IO口(任选)相连,这样硬件的连接就完成了。
在这里插入图片描述

三、驱动程序

3.1 写一位数据到HT1621B

时序图如下
在这里插入图片描述
从图中可看出,在片选为低电平且写时钟线的上升沿时才能写入数据。

/**
 * @brief   写数据到HT1621
 * @param   Data:要写入的数据bits
 * @param   num:传送数据位数
 * @retval  无
 */
void write_bit_ht1621(uint8_t data, uint8_t num)
{
   
    uint8_t i;

    for (i = 0; i < num; i++)
    {
   
        LCD_WR_0();                     /* 拉低WR脚  Data线上的数据在WR脚位上升沿写入   */
        if (((data & 0x80) >> 7) == 1)  /* 如果当前bit为1,就拉高DATA引脚 */
        {
   
            LCD_DATA_1();
        }
        else if (((data & 0x80) >> 7) == 0)  /* 如果当前bit为0,就拉低DATA引脚 */
        {
   
            LCD_DATA_0();
        }
        LCD_WR_1();                     /* 当前这一bit写完,拉高WR脚,为下次WR为上升沿做准备 */
        data <<= 1;                     /* 当前位用完了,移到下一位继续上述动作 */
    }
}

3.2 向HT1621B相应地址写入数据,来控制段码屏显示相应字符

首先,我们先了解一下HT1621B的地址映射,如下图
在这里插入图片描述
这个图的意思就是SEG0就是地址0,程序中传地址时你可以写为十进制的0也可以写为十六进制的0,每个地址位可以控制4个位,对应LCD屏上4个点的显示(在下面数码管中,a、b、c、d就代表4个点)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3939a5a9cfab49c797012b87318c39b0.png
在编写具体的显示程序时,要根据厂商给出的真值表进行编写,如下图是我所用的,
请添加图片描述
我的思路是,14个地址,一个地址4bit,那就相当于7个8bit数据,所以我定义了1个char型的数组有7个元素。HT1621B是支持连续写的。

/* 真值表顺序  FGEABCD */
/* 0,1,2,3,4,5,6,7,8,9,灭 */
const char num[] = {
   0x5F, 0x06, 0x3D, 0x2F, 0x66, 0x6B, 0x7B, 0x0E, 0x7F, 0x6F, 0x00};
char dispnum[7] = {
   0x00};

/**
 * @brief   将要显示的数据写到HT1621
 * @param   Addr:写入初始地址
 * @param   Data:要写入的数据
 * @param   Mode:COMMAND_CODE(0X80) / WRITE_DATA_CODE(0XA0)
 * @retval  无
 */
void write_ht1621(uint8_t addr, uint8_t data)
{
   
    LCD_CS_0();
    write_bit_ht1621(WRITE_DATA_CODE, 3); /* 命令模式或数据模式 */
    write_bit_ht1621(addr << 2, 6);       /* 写入地址 */
    write_bit_ht1621(data, 8);             /* 写入数据  */
    LCD_CS_1();
}

这里可能会有人有疑问,时序图中数据是低位先传,而我们这里却是高位先传,不用担心我们在编写真值表时已经将低位放在了高位,所以完全没问题。

3.3 向HT1621B写入命令

在这里插入图片描述
在这里插入图片描述
从时序图中可以看出,命令模式码有3位,而命令代码有9位,但最后一位0、1都行,有些朋友喜欢直接舍弃不管它,而我则是把C8和3位命令码放在一起 C0和C7放在一起注意不同的排序方法,命令代码的值不同,数据手册有详细的命令代码

/*  HT1621 命令定义 */
#define COMMAND_CODE                0x80        /* 命令码 */
#define WRITE_DATA_CODE            0xA0        /* 写命令 */

#define HT1621_SYS_EN               0x02        /* 打开系统振荡器 */
#define HT1621_RC256                	0x30        /* 内部时钟 */
#define HT1621_BIAS                 	0x52        /* 1/3duty 4com LCD偏置 */

/**
 * @brief   写命令到HT1621
 * @param   Cmd:命令
 * @retval  无
 */
void write_cmd_ht1621(uint8_t cmd)
{
   
    LCD_CS_0();                        /* 拉低CS脚  CS拉低时WR有效 */
    write_bit_ht1621(COMMAND_CODE, 4); /* 写入命令标志100   0x80  */
    write_bit_ht1621(cmd, 8);          /* 写入命令数据 */
    LCD_CS_1();                        /* 拉高CS脚 */
}

从真值表来看,有些单个符号在和数码管显示混在了一起,这时只需使用位与和位或就可以单独控制它了,可以看下lcd_display(),看下各位就有思路了。

3.4 ht1621.h

#ifndef __HT1621_H
#define __HT1621_H

 #include "stm32f10x.h"

/*  HT1621硬件连接端口定义 */
#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_1
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值