合泰HT1632C点阵LED芯片 的emuSPI驱动(即软件GPIO模拟方式)

变更历史

1、2021年12月27日,初版
2、2022年1月15日,增加一些心得
3、2022年2月25日,驱动程序在HT1632D上测试通过
4、2022年5月24日,增加连续写函数(命令模式和数据模式各一),在HT1632C上测试通过
5、2022年7月6日,数据模式写函数修正,在HT1632D上测试通过
6、2023年1月15日,调整DATA线操作时机的建议
7、2024年1曰10日,HAL层初始化补全

概述

芯片概述

HT1632C是一款常用的LED点阵屏驱动芯片,支持NMOS或PMOS的共阳/阴布线,支持32ROWx8COM或24ROWx16COM点阵布局。芯片手册的翻译请参考文章:《合泰HT1632C芯片手册 精炼汉化版

HT1632C仅支持串行通信,有4条通信线,分别是:

  • CS:低电平有效
  • WR:写时钟,上升沿有效
  • RD: 读时钟,下降沿有效
  • DATA:数据线

其指令集有两种,一种是12bit的CMD(配置)模式,另一种是14bit的DATA(VRAM数据)模式。

  • Cmd模式:3bit命令码 - 8bit配置 - 1bit任意值

设计理念

我将使用GPIO模拟方式进行设计。我手中的HT1632C开发板是32ROWx8COM + NMOS布局的。测试平台为ST的STM32F1和Renesas的RX130。
原因:

  • 一般的,MCU硬件SPI的数据线与HT1632C的IO不能完整对应,硬件SPI往往是:CLK、MOSI、MISO,即1条时钟线+2条数据线,只能够实现50%的功能(读or写)。
  • 另一个问题是:一般的单片机的硬件SPI不支持变长数据的发送。
  • 使用GPIO模拟方式,可以实现100%的功能(读+写),还能获得可跨平台的可移植性。

为了省事,我只写出两种模式下的写入函数。

HT1632C的驱动

这款芯片的驱动将采用分层设计。

  • 硬件抽象层HAL,包含:GPIO初始化函数,GPIO输出函数。
  • 硬件驱动层HDL,包含:CMD模式-写入函数,DATA模式-写入函数,HT1632C指令集的常数定义。
  • 功能模块层FML,包含:HT1632C初始化函数,LED全亮函数,LED全灭函数。

硬件抽象层HAL

ht1632c_hal.c,主体为GPIO初始化函数。如下。
  1、初始化四条GPIO,均为推挽输出。优先初始化CS:先将其输出寄存器bit置位,再初始化为输出,以防HT1632C被选中。
  如果使用“读数据”功能,需要将DATA线初始化为开漏输出,并配备外部上拉。
  2、四条GPIO的输出函数,形如HT1632xHAL_***WriteBit(uint8_t bit_status)。

硬件驱动层HDL

ht1632c_hdl.c,主体为CMD模式-写入函数,VRAM模式-写入函数。如下。
为了保证WR上升沿时DATA线电压的稳定,建议在两次WR上升沿的时间中点操作DATA线。

/*
FUNCTION        : HT1632xHDL_CmdModeWrite
DESCRIPTION     : Fast write function of Cmd-Mode.
INPUT           : u11_cmd: head address of Cmd array. This parameter will be 
				           left-shifted 1-bit within the function to add 1 useless bit.
                           3bits(cmd) - 7bits(vram addr) - 4bits(vram data)
OUTPUT          : None
DATE            : 
*/
void HT1632xHDL_CmdModeWrite(uint16_t u11_cmd[], uint16_t length) {
    uint16_t i, j;
    uint16_t u12_cmd;
    
    /* Write Process */
    HT1632xHAL_CSWriteBit(Bit_RESET);               /* Chip selected */
    for (j = 0; j < length; j++) {                  /* From u11_cmd[0] to u11_cmd[length-1] */
        /* Cmd Prepare */
        u12_cmd = u11_cmd[j] << 1U;                             /* expand to 12bits */
        /* Write the cmd */
        if (j == 0) {                                           /* Send u11_cmd[zero] */
            for (i = 1<<11U; i != 0; i >>= 1) {                              /* MSB: From bit11 to bit0 */
        		HT1632xHAL_WRWriteBit(Bit_RESET);                                       /* Reset WR_CLK */
                HT1632xHAL_DATAWriteBit( ( !!(u12_cmd & i) )? Bit_SET:Bit_RESET );      /* DATA_OUT(H/L) = DATA_Bit(1/0) */
        		HT1632xHAL_WRWriteBit(Bit_SET);                                         /* Set WR_CLK */
            }
        } else {                                                /* Send u11_cmd[non-zero] */
            for (i = 1<<8U; i != 0; i >>= 1) {                               /* MSB: From bit8 to bit0 */
        		HT1632xHAL_WRWriteBit(Bit_RESET);                                       /* Reset WR_CLK */
                HT1632xHAL_DATAWriteBit( ( !!(u12_cmd & i) )? Bit_SET:Bit_RESET );      /* DATA_OUT(H/L) = DATA_Bit(1/0) */
        		HT1632xHAL_WRWriteBit(Bit_SET);                                         /* Set WR_CLK */
            }
        }
    }
    HT1632xHAL_CSWriteBit(Bit_SET);                 /* Chip un-selected */  
}

/*
FUNCTION        : HT1632xHDL_DataModeWrite
DESCRIPTION     : Fast write function of Data array.
INPUT           : u14_data: head address of HT1632C DATA Array
                            3bits(cmd) - 7bits(vram addr) - 4bits(pixel on/off info)
OUTPUT          : None
DATE            : 
*/
void HT1632xHDL_DataModeWrite(uint16_t u14_data[], uint16_t length) {
    uint16_t i, j;
    
    /* Write Process */
    HT1632xHAL_CSWriteBit(Bit_RESET);               /* Chip selected */
    for (j = 0; j < length; j++) {                  /* From u11_cmd[0] to u14_data[length-1] */
        /* Write the cmd */
        if (j == 0) {                                           /* Send u14_data[zero] */
            for (i = 1<<13U; i != 0; i >= 1) {                              /* MSB: From bit13 to bit0 */
        		HT1632xHAL_WRWriteBit(Bit_RESET);                                       /* Reset WR_CLK */
                HT1632xHAL_DATAWriteBit( ( !!(u14_data[j] & i) )? Bit_SET:Bit_RESET );  /* DATA_OUT(H/L) = DATA_Bit(1/0) */
        		HT1632xHAL_WRWriteBit(Bit_SET);                                         /* Set WR_CLK */
            }
        } else {                                                /* Send u14_data[non-zero] */
            for (i = 1<<3U; i != 0; i >= 1) {                               /* MSB: From bit3 to bit0 */
        		HT1632xHAL_WRWriteBit(Bit_RESET);                                       /* Reset WR_CLK */
                HT1632xHAL_DATAWriteBit( ( !!(u14_data[j] & i) )? Bit_SET:Bit_RESET );  /* DATA_OUT(H/L) = DATA_Bit(1/0) */
        		HT1632xHAL_WRWriteBit(Bit_SET);                                         /* Set WR_CLK */
            }
        }
    }
    HT1632xHAL_CSWriteBit(Bit_SET);                 /* Chip un-selected */
}
/**********************************************************END OF FILE****/

ht1632c_hdl.h,主体为HT1632C的指令集。如下。

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __HT1632X_HDL_H
#define __HT1632X_HDL_H

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Typedef -------------------------------------------------------------------*/
/* Marco ---------------------------------------------------------------------*/
/*
	HT1632C/D Instruction set Definition
*/
/* CMD type */
#define CM_CFG              0x400               /* HT1632C command mode(DM): configure read/write */
#define DM_READ             0x3000              /* HT1632C data mode(CM): VRAM read */
#define DM_WRITE            0x2800              /* HT1632C data mode(CM): VRAM write */
#define DM_READ_WRITE       0x2800              /* HT1632C data mode(CM): VRAM read modify write*/
/* CM: system on/off */
#define CM_SYSDIS           0x00                /* System disable */        /* Default */
#define CM_SYSEN            0x01                /* System enable */
/* CM: led on/off */
#define CM_LEDOFF           0x02                /* led pwm generator DIS */ /* Default */
#define CM_LEDON            0x03                /* led pwm generator EN */
/* CM: blink on/off */
#define CM_BLINKOFF         0x0408              /* Blink OFF */             /* Default */
#define CM_BLINKON          0x0409              /* Blink ON */
/* CM: slave/master */
#define CM_SLAVE            0x10                /* Slave mode */
#define CM_RC_MASTER        0x18                /* RC master mode */        /* Default */
#define CM_EXTCK_MASTER     0x1C                /* EXT clock master mode */
/* CM: Circuit layout: N/P-MOS & COM config */
#define CM_LAYOUT_N_8COM    0x20                /* NMOS & 8-COM */
#define CM_LAYOUT_N_16COM   0x24                /* NMOS & 16-COM */
#define CM_LAYOUT_P_8COM    0x28                /* PMOS & 8-COM */
#define CM_LAYOUT_P_16COM   0x2C                /* PMOS & 16-COM */
/* CM: PWM Ratio configuration (Brightness) */
#define CM_PWM_(r)          (uint16_t)(0x04A0|((r <= 16 && r >= 1)? ( r - 1 ):(0x000F)))    /* PWM Ratio, r∈[1, 16], 16 is Default */
/* DM: VRAM Address */
#define DM_ADDR(n)          (uint16_t)(n << 4)  /* 8COM --> n∈[0, 63],  16COM --> n∈[0, 127] */
#define DM_ADDR_MASK        0x07F0              /* Addr bits mask, bit4~10 */
#define DM_ADDR_8COM_MAX    64                  /* 8COM's MAX */    /* Do not init with (uint16_t) */
#define DM_ADDR_16COM_MAX   96                  /* 16COM's MAX */   /* Do not init with (uint16_t) */
/* DM: Pixel location */
#define DM_LOCATION(n)      ((uint32_t)(1 << ( 3 - n )))    /* n=0,1,2,3 */
#define DM_LOCATION_MASK    0x000F                /* Loaction bits mask, bit0~3 */
/* Pixel Definition */
#define PIXEL(id)           ((uint32_t)(DM_ADDR( (id / 4) ) | DM_LOCATION( (id % 4) )))

/* Constant ------------------------------------------------------------------*/
/* Variables -----------------------------------------------------------------*/
/* Exported function prototypes ----------------------------------------------*/
void HT1632xHDL_CmdModeWrite(uint16_t  u11_cmd[], uint16_t length);
void HT1632xHDL_DataModeWrite(uint16_t u14_data[], uint16_t length);




#endif /* __HT1632X_HDL_H */
/****************************************************************** OF FILE****/

功能模块层FML

ht1632c_fml.c,主体为HT1632C初始化函数,LED全亮函数,LED全灭函数。

/**************************************************************************
FUNCTION        : disp_fml_init
DESCRIPTION     : Initializes display monitor.
INPUT           : None
OUTPUT          : None
UPDATE          : 
DATE            : 
**************************************************************************/
void disp_fml_init(void)
{
    uint16_t i;
    /* HT1632C init data */
   uint16_t Init_Data[] = {
        CM_CFG | CM_SYSDIS,
        CM_CFG | CM_LAYOUT_N_8COM,
        CM_CFG | CM_RC_MASTER,
        CM_CFG | CM_PWM_(16),
        CM_CFG | CM_BLINKOFF,
        CM_CFG | CM_SYSEN,
        CM_CFG | CM_LEDON,
    };
    /* Send init data */
    HT1632xHDL_CmdModeWrite(Init_Data, sizeof(Init_Data)/sizeof(uint16_t));
}

/**************************************************************************
FUNCTION        : disp_fml_disp_all_on
DESCRIPTION     : Send vram data to ht1632c.
INPUT           : None
OUTPUT          : None
UPDATE          : 
DATE            : 
**************************************************************************/
void disp_fml_disp_all_on(void)
{
    uint16_t i;
    uint16_t u14_vram_data[DM_ADDR_8COM_MAX]= {0,};
    /* Send VRAM data */
    for (i = 0U; i< DM_ADDR_8COM_MAX; i++ ) 
    {
    	u14_vram_data[i] = DM_WRITE | (i << 4) | DM_LOCATION_MASK;
    }
    HT1632xHDL_DataModeWrite(u14_vram_data, DM_ADDR_8COM_MAX);
}

/**************************************************************************
FUNCTION        : disp_fml_disp_all_off
DESCRIPTION     : Send vram data to ht1632c.
INPUT           : None
OUTPUT          : None
UPDATE          : 
DATE            : 
**************************************************************************/
void disp_fml_disp_all_off(void)
{
    uint16_t i;
    uint16_t u14_vram_data[DM_ADDR_8COM_MAX]= {0,};
    /* Send VRAM data */
    for (i = 0U; i< DM_ADDR_8COM_MAX; i++ ) 
    {
    	u14_vram_data[i] = DM_WRITE | (i << 4);
    }
    HT1632xHDL_DataModeWrite(u14_vram_data, DM_ADDR_8COM_MAX);
}

展望

现在,你有鱼竿和鱼饵了。快去钓鱼吧!
比如,写个字库,实现数字的显示!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值