ht1621b和单片机电平匹配_基于HT1621B段式液晶模块的驱动应用

本文介绍了如何使用位段定义和驱动HT1621B段式液晶模块,详细阐述了数码管和图标显示的驱动方法,包括设置位操作、段定义和寄存器更新,展示了位控制的便利性。
摘要由CSDN通过智能技术生成

但是我们知道,除了C51提供位操作为,其他单片机并不提供位操作的定义方式,但是,基本上所有的编译器都提供位段的定义方式,所以下面我们将使用位段进行定义:

由原理图和液晶资料我们可以看出,Seg0对应第一个数码管的F、G、E三段,Seg1对应第一个数码管的A、B、C、D四段。而第二个数码管和第三个数码 管的每一段顺序与第一个相同。所以,我们可以使用与第一个数码管相同的结构体进行三个数码管的定义,当然有时候每个数码管的每一段顺序并不一定相同,这个 是由段式液晶在设计时的走线确定的。如果每一个数码的顺序不同,我们就得分别定义其结构体了。

typedef union

{

struct

{

u8 DA   : 1;         //

u8 DB   : 1;         //

u8 DC   : 1;         //

u8 DD   : 1;         //

u8 Rcv  : 4;         //

} BtL;

struct

{                                 //

u8 DF   : 1;         //

u8 DG   : 1;

u8 DE   : 1;         //

u8 DO   : 1;         //

u8 Rcv  : 4;         //

} BtH;

} HTB_SEG;

在这里,我们把同一个数码管的7段定义在一个结构体中,如果使用F、G、E三个段式,我们使用BtH这个变量,如果使用A、B、C、D四段时,我们使用 BtL这个变量。当然,我们也可以把这两个分开定义。由于第二个数码管多了个冒号,同样把其放入BtH变量中,第一个和第三个数码管中没有使用这个位,不 用即可。

typedef union

{

struct

{

u8 K1   : 1;         //

u8 K2   : 1;         //

u8 K3   : 1;         //

u8 Rcv  : 5;         //

} BtL;

struct

{

u8 K7   : 1;         //

u8 K6   : 1;         //

u8 K5   : 1;         //

u8 K4   : 1;         //

u8 Rcv  : 4;         //

} BtH;

} HTB_ICN;

用同样的方法定义剩余的图标,获得上面的结构体。由此我们看出,每个寄存器实际上只使用了前面4个位,后面的4个位没有使用,保留。

typedef struct

{

HTB_SEG Seg0;

HTB_SEG Seg1;

HTB_SEG Seg2;

HTB_SEG Seg3;

HTB_SEG Seg4;

HTB_SEG Seg5;

HTB_ICN Seg6;

HTB_ICN Seg7;

} HTB_RAM;

HTB_RAM HTBRam;

最后我们把使用的8个寄存器分别使用上面的结构体变量进行定义,前面6个为数码管,后面2个为图标。有了这个结构体,后面定义一个变量用于操作每个数码管。

数码管显示驱动如下,从0~9通过控制每一段形成字符:

/**************************************************************************************

* FunctionName   : HTB_SegVal()

* Description    : 数码管填值

* EntryParameter : None

* ReturnValue    : None

**************************************************************************************/

void HTB_SegVal(HTB_SEG *pSg1, HTB_SEG *pSg2, u8 dat)

{

switch (dat)

{

case 0:  pSg2->BtL.DA = 1; pSg2->BtL.DB = 1; pSg2->BtL.DC = 1; pSg2->BtL.DD = 1;

pSg1->BtH.DE = 1; pSg1->BtH.DF = 1; pSg1->BtH.DG = 0; break;

case 1:  pSg2->BtL.DA = 0; pSg2->BtL.DB = 1; pSg2->BtL.DC = 1; pSg2->BtL.DD = 0;

pSg1->BtH.DE = 0; pSg1->BtH.DF = 0; pSg1->BtH.DG = 0; break;

case 2:  pSg2->BtL.DA = 1; pSg2->BtL.DB = 1; pSg2->BtL.DC = 0; pSg2->BtL.DD = 1;

pSg1->BtH.DE = 1; pSg1->BtH.DF = 0; pSg1->BtH.DG = 1; break;

case 3:  pSg2->BtL.DA = 1; pSg2->BtL.DB = 1; pSg2->BtL.DC = 1; pSg2->BtL.DD = 1;

pSg1->BtH.DE = 0; pSg1->BtH.DF = 0; pSg1->BtH.DG = 1; break;

case 4:  pSg2->BtL.DA = 0; pSg2->BtL.DB = 1; pSg2->BtL.DC = 1; pSg2->BtL.DD = 0;

pSg1->BtH.DE = 0; pSg1->BtH.DF = 1; pSg1->BtH.DG = 1; break;

case 5:  pSg2->BtL.DA = 1; pSg2->BtL.DB = 0; pSg2->BtL.DC = 1; pSg2->BtL.DD = 1;

pSg1->BtH.DE = 0; pSg1->BtH.DF = 1; pSg1->BtH.DG = 1; break;

case 6:  pSg2->BtL.DA = 1; pSg2->BtL.DB = 0; pSg2->BtL.DC = 1; pSg2->BtL.DD = 1;

pSg1->BtH.DE = 1; pSg1->BtH.DF = 1; pSg1->BtH.DG = 1; break;

case 7:  pSg2->BtL.DA = 1; pSg2->BtL.DB = 1; pSg2->BtL.DC = 1; pSg2->BtL.DD = 0;

pSg1->BtH.DE = 0; pSg1->BtH.DF = 0; pSg1->BtH.DG = 0; break;

case 8:  pSg2->BtL.DA = 1; pSg2->BtL.DB = 1; pSg2->BtL.DC = 1; pSg2->BtL.DD = 1;

pSg1->BtH.DE = 1; pSg1->BtH.DF = 1; pSg1->BtH.DG = 1; break;

case 9:  pSg2->BtL.DA = 1; pSg2->BtL.DB = 1; pSg2->BtL.DC = 1; pSg2->BtL.DD = 1;

pSg1->BtH.DE = 0; pSg1->BtH.DF = 1; pSg1->BtH.DG = 1; break;

case 0:  pSg2->BtL.DA = 0; pSg2->BtL.DB = 0; pSg2->BtL.DC = 0; pSg2->BtL.DD = 0;

pSg1->BtH.DE = 0; pSg1->BtH.DF = 0; pSg1->BtH.DG = 0; break;

default:break;

}

}

/**************************************************************************************

* FunctionName   : HTBColon()

* Description    : 冒号

* EntryParameter : None

* ReturnValue    : None

**************************************************************************************/

void HTBColon(OS_SWT swt)

{

HTBRam.Seg2.BtH.DO = (swt > 0) ? 1 : 0;

}

/**************************************************************************************

* FunctionName   : HTBTemStl()

* Description    : 温度

* EntryParameter : None

* ReturnValue    : None

**************************************************************************************/

void HTBTemStl(u8 stl)

{

HTBRam.Seg7.BtH.K4 = 0;

HTBRam.Seg7.BtH.K5 = 0;

HTBRam.Seg7.BtH.K6 = 0;

HTBRam.Seg7.BtH.K7 = 0;

switch (stl)

{

case 0: HTBRam.Seg7.BtH.K4 = 1; break;

case 1: HTBRam.Seg7.BtH.K5 = 1; break;

case 2: HTBRam.Seg7.BtH.K6 = 1; break;

case 3: HTBRam.Seg7.BtH.K7 = 1; break;

default : break;

}

}

/**************************************************************************************

* FunctionName   : HTBWndStl()

* Description    : 风速

* EntryParameter : None

* ReturnValue    : None

**************************************************************************************/

void HTBWndStl(u8 stl)

{

HTBRam.Seg6.BtL.K1 = 0;

HTBRam.Seg6.BtL.K2 = 0;

HTBRam.Seg6.BtL.K3 = 0;

switch (stl)

{

case 0: HTBRam.Seg6.BtL.K3 = 1; break;

case 1: HTBRam.Seg6.BtL.K2 = 1; break;

case 2: HTBRam.Seg6.BtL.K1 = 1; break;

default : break;

}

}

图标的驱动如上,其实就是根据需要修改每一个寄存器位,这个寄存器修改后,我们还必须得传递给HT1621更新显示,才能真正实现显示的驱动:

/**************************************************************************************

* FunctionName   : HTB_SendBitMsb()

* Description    : 发送发送多位[高位在前]

* EntryParameter : None

* ReturnValue    : None

**************************************************************************************/

void HTB_SendBitMsb(u8 dat, u8 cnt)

{

for (u8 i=0; i

{

(dat & 0x80) ? GPIO_WriteHigh(HTB_DT_PORT, HTB_DT_PIN) :

GPIO_WriteLow(HTB_DT_PORT, HTB_DT_PIN);

dat <<= 1;

GPIO_WriteLow(HTB_WR_PORT, HTB_WR_PIN);

HTB_DelayUs(3);

GPIO_WriteHigh(HTB_WR_PORT, HTB_WR_PIN);

}

}

/**************************************************************************************

* FunctionName   : HTB_SendBitLsb()

* Description    : 发送多位[低位在前]

* EntryParameter : None

* ReturnValue    : None

**************************************************************************************/

void HTB_SendBitLsb(u8 dat, u8 cnt)

{

for (u8 i=0; i

{

(dat & 0x01) ? GPIO_WriteHigh(HTB_DT_PORT, HTB_DT_PIN) :

GPIO_WriteLow(HTB_DT_PORT, HTB_DT_PIN);

dat >>= 1;

GPIO_WriteLow(HTB_WR_PORT, HTB_WR_PIN);

HTB_DelayUs(3);

GPIO_WriteHigh(HTB_WR_PORT, HTB_WR_PIN);

}

}

/**************************************************************************************

* FunctionName   : HTB_SendCmd()

* Description    : 发送命令

* EntryParameter : None

* ReturnValue    : None

**************************************************************************************/

void HTB_SendCmd(u8 cmd)

{

GPIO_WriteLow(HTB_CS_PORT, HTB_CS_PIN);

HTB_SendBitMsb(0x80, 3);                                                     // 前面3位命令代码

HTB_SendBitMsb(cmd, 9);                                                      // 后面10位: a5~a0[RAM地址]+d3~d0[RAM数据]

GPIO_WriteHigh(HTB_CS_PORT, HTB_CS_PIN);

}

/**************************************************************************************

* FunctionName   : HTBSendNDat()

* Description    : 发送N数据

* EntryParameter : None

* ReturnValue    : None

**************************************************************************************/

void HTBSendNDat(u8 addr, u8 *pDat, u8 cnt, u8 bitNum)

{

GPIO_WriteLow(HTB_CS_PORT, HTB_CS_PIN);

HTB_SendBitMsb(0xA0, 3);                                                    // 前面3位命令代码

HTB_SendBitMsb(addr<<2, 6);                                                 // a5~a0[RAM地址]

for (u8 i=0; i

{

HTB_SendBitLsb(*pDat++, bitNum);                                        // RAM数据

}

GPIO_WriteHigh(HTB_CS_PORT, HTB_CS_PIN);

}

上面的函数是通过按位传递的方式把数据发给HT1621,并不复杂,这里就不相信介绍了:

typedef enum

{

HTB_CMD_BIAS   = 0x29,                                         // 0B:0010 abXc  -ab控制占空比,-c控制偏压

HTB_CMD_SYSEN  = 0x01,                                         //

HTB_CMD_LCDOFF = 0x02,                                         //

HTB_CMD_LCDON  = 0x03,                                         //

} HTB_CMD;

最后,我们可以看出,在修改了全局变量后,在把更新的数据传递给驱动芯片就可以了,非常简单方便灵活,这个示例让我们充分了解和使用位段进行位控制是非常方便。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值