TM1652驱动程序例子
一、简介
TM1652 是一款LED(发光二极管、数码管、点阵屏)驱动控制专用芯片,内部集成了数字通讯电路、 解码电路、数据锁存器、震荡器、LED驱动电路。通讯方式采用异步串口通信(UART)协议,因芯片只 接收单片机发来的数据,仅需要单片机的一个TX端口发送数据给芯片即可,实现单线通讯;在显示驱动 方面,芯片采用动态扫描方式,两种显示模式可选,8级段驱动电流可调,16级位占空比可调;TM1652 内置消隐处理优化电路。
二、通讯协议
通信协议 本芯片采用异步串口通信(UART)协议,工作原理是将传输数据的每个字符以串行方式一位接一位 的传输。下图给出了其工作模式:

TM1652 每一位的时间为:52us。
其中每一位(bit)的意义如下:
▲起始位:为由高变低,低电平时间为一位的时间,表示传输字符的开始。
▲数据位:紧跟起始位之后,D0-D7,低位先发。
▲校验位:为一位的时间,如果 8 位数据位中 1 的个数为奇数,该位设为 0(置低电平),否则为 1(置 高电平)。
▲停止位:置高。时间为一位的时间,它是发送完一个字符数据的结束标志。
▲空闲位:置高。如果空闲位置高的时间大于 3ms,TM1652 就认为本次数据帧结束,本次数据从暂存器 打入相应寄存器开始控制芯片输出。如果一帧数据传输没有结束,那么建议设置空闲位时间范围在 0-0.5ms 以内。
TM1652 的一帧数据包括以下两种形式: ⑴ 显示地址命令+显示数据; ⑵ 显示控制命令+显示控制调节命令。
波特率:是衡量数据传输速率的指针。表示为每秒钟传送的二进制位数(bit 数)。例如资料传送速率 为 120 字符/秒,而每一个字符为 11 位,则其传送的波特率为 11×120=1320 bit/秒=1320 波特。TM1652 支持波特率范围为:17500bps~21200bps,这里我们建议用 19200bps 即每位的 LED 驱动控制专用电路 TM1652 5 ©Titan Micro Electronics www.titanmec.com V1.0 时间为:1s(秒)/19200≈52us(微秒)。所以 TM1652 支持的每位的时间范围为:47us~57us。 在用 IO 模拟 UART 通讯时候,SDA 数据的位宽应该满足提供的位宽范围。 下面我们以波特率为 19200bps 为例,给 SDA 脚发送显示控制命令“0X18”,时序波形图如下:

如上图,发送“0X18”总共 11 位,从左至右依次为 1 位起始位、8 位数据位、1 位校验位、1 位停止 位,每位的时间约为 52us ,11 位总时间约为 572us。由上图读出二进制为“00011000”即转换为十六 进制为“0X18”。
三、数据定义
第一个 Byte 数据为控制命令设定,低位先发。其中低四位 B3 ~B0 为 1000 为固定数据。B4 为寄 存器类型选择,“1”时选择显示控制命令,“0”时选择显示地址命令。B7~B5 为设定显示地址。 从第二 Byte 数据开始为数据,按照第一个 Byte 中的地址送到相应的暂存器存器中,如果是显示控 制命令,第二 Byte 必须是显示控制调节命令。如果是显示地址命令,可以是多 Byte 数据,后续 Byte 数据按地址累加 1 放入相应暂存器中。如果地址超过相应有效地址,显示地址 101 以上,超过部分数据 无效,如果开始第一 Byte 含的地址就超过相应有效地址或是无效地址,本次数据无效。应用时建议先发显示数据,然后再发控制数据(开显示),如果先发控制数据(开显示),显示寄存器没有清零,此 时就会输出显示寄存器里面的随机数据,导致数码管显示乱码直到显示寄存器接收到正确的显示数据。
四、示例
根据TM1652的规格书,它只支持8段5位输出和7段6位输出,要实现7段4位输出,只要将最后两位数据都设置成0即可。
另外根据通讯协议,TM1652是支持串口协议的,推荐波特率是19200,因为只需要单向控制,所以只要将主控芯片的TX脚接到TM1652的SDA脚即可,如果没有串口,可以用一个GPIO口进行模拟,只要控制好每个位的时间为52us即可。
下面是使用4位7段数码管,用串口实现输出的案例。
/*Definition for 7-seg display
AAAA
F B
F B
GGGG
E C
E C
DDDD
*/
//数码数码管显示位的显示地址
#define GR1_DISPLAY_ADDR (0x08)
#define GR1_CTRL_ADDR (0x18)
#define DISPLAY_ON (0x4F)
#define VFD_7SEG_SA (0x01)
#define VFD_7SEG_SB (0x02)
#define VFD_7SEG_SC (0x04)
#define VFD_7SEG_SD (0x08)
#define VFD_7SEG_SE (0x10)
#define VFD_7SEG_SF (0x20)
#define VFD_7SEG_SG (0x40)
#define VFD_7SEG_0 (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SD|VFD_7SEG_SF|VFD_7SEG_SC|VFD_7SEG_SE)
#define VFD_7SEG_1 (VFD_7SEG_SB|VFD_7SEG_SC)
#define VFD_7SEG_2 (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SG|VFD_7SEG_SE|VFD_7SEG_SD)
#define VFD_7SEG_3 (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SG|VFD_7SEG_SC|VFD_7SEG_SD)
#define VFD_7SEG_4 (VFD_7SEG_SF|VFD_7SEG_SG|VFD_7SEG_SB|VFD_7SEG_SC)
#define VFD_7SEG_5 (VFD_7SEG_SA|VFD_7SEG_SF|VFD_7SEG_SG|VFD_7SEG_SC|VFD_7SEG_SD)
#define VFD_7SEG_6 (VFD_7SEG_SA|VFD_7SEG_SF|VFD_7SEG_SE|VFD_7SEG_SD|VFD_7SEG_SC|VFD_7SEG_SG)
#define VFD_7SEG_7 (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SC)
#define VFD_7SEG_8 (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SC|VFD_7SEG_SD|VFD_7SEG_SE|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_9 (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SC|VFD_7SEG_SD|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_DIG_MASK (VFD_7SEG_8)
#define VFD_7SEG_A (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SC|VFD_7SEG_SE|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_b (VFD_7SEG_SC|VFD_7SEG_SD|VFD_7SEG_SE|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_B VFD_7SEG_b
#define VFD_7SEG_C (VFD_7SEG_SA|VFD_7SEG_SD|VFD_7SEG_SE|VFD_7SEG_SF)
#define VFD_7SEG_d (VFD_7SEG_SB|VFD_7SEG_SD|VFD_7SEG_SE|VFD_7SEG_SC|VFD_7SEG_SG)
#define VFD_7SEG_D VFD_7SEG_d
#define VFD_7SEG_E (VFD_7SEG_SA|VFD_7SEG_SE|VFD_7SEG_SD|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_F (VFD_7SEG_SA|VFD_7SEG_SE|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_G (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SC|VFD_7SEG_SD|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_H (VFD_7SEG_SB|VFD_7SEG_SC|VFD_7SEG_SG|VFD_7SEG_SF|VFD_7SEG_SE)
#define VFD_7SEG_I (VFD_7SEG_SB|VFD_7SEG_SC)
#define VFD_7SEG_J (VFD_7SEG_SB|VFD_7SEG_SC|VFD_7SEG_SD|VFD_7SEG_SE)
#define VFD_7SEG_K (VFD_7SEG_SB|VFD_7SEG_SC|VFD_7SEG_SD|VFD_7SEG_SE)
#define VFD_7SEG_L (VFD_7SEG_SF|VFD_7SEG_SE|VFD_7SEG_SD)
#define VFD_7SEG_M (VFD_7SEG_SE|VFD_7SEG_SG|VFD_7SEG_SC)
#define VFD_7SEG_n (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SC|VFD_7SEG_SE|VFD_7SEG_SF)
#define VFD_7SEG_N VFD_7SEG_n
#define VFD_7SEG_O (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SD|VFD_7SEG_SC|VFD_7SEG_SE|VFD_7SEG_SF)
#define VFD_7SEG_P (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SE|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_Q (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SE|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_r (VFD_7SEG_SE|VFD_7SEG_SG)
#define VFD_7SEG_R VFD_7SEG_r
#define VFD_7SEG_S (VFD_7SEG_SA|VFD_7SEG_SF|VFD_7SEG_SG|VFD_7SEG_SC|VFD_7SEG_SD)
#define VFD_7SEG_t (VFD_7SEG_SD|VFD_7SEG_SE|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_T VFD_7SEG_t
#define VFD_7SEG_U (VFD_7SEG_SC|VFD_7SEG_SB|VFD_7SEG_SF|VFD_7SEG_SE|VFD_7SEG_SD)
#define VFD_7SEG_V (VFD_7SEG_SC|VFD_7SEG_SB|VFD_7SEG_SF|VFD_7SEG_SE|VFD_7SEG_SD)
#define VFD_7SEG_W (VFD_7SEG_SC|VFD_7SEG_SB|VFD_7SEG_SF|VFD_7SEG_SE|VFD_7SEG_SD)
#define VFD_7SEG_X (VFD_7SEG_SC|VFD_7SEG_SB|VFD_7SEG_SF|VFD_7SEG_SE|VFD_7SEG_SD)
#define VFD_7SEG_Y (VFD_7SEG_SC|VFD_7SEG_SD|VFD_7SEG_SB|VFD_7SEG_SF|VFD_7SEG_SG)
#define VFD_7SEG_Z (VFD_7SEG_SA|VFD_7SEG_SB|VFD_7SEG_SD|VFD_7SEG_SE|VFD_7SEG_SG)
#define VFD_7SEG_MASK 0xff
#define TOTAL_SEG (4)
static const uint8_t vfd_char[26] = {
VFD_7SEG_A,
VFD_7SEG_B,
VFD_7SEG_C,
VFD_7SEG_D,
VFD_7SEG_E,
VFD_7SEG_F,
VFD_7SEG_G,
VFD_7SEG_H,
VFD_7SEG_I,
VFD_7SEG_J,
VFD_7SEG_K,
VFD_7SEG_L,
VFD_7SEG_M,
VFD_7SEG_N,
VFD_7SEG_O,
VFD_7SEG_P,
VFD_7SEG_Q,
VFD_7SEG_R,
VFD_7SEG_S,
VFD_7SEG_T,
VFD_7SEG_U,
VFD_7SEG_V,
VFD_7SEG_W,
VFD_7SEG_X,
VFD_7SEG_Y,
VFD_7SEG_Z
};
static const uint8_t vfd_digit[] = {
VFD_7SEG_0,
VFD_7SEG_1,
VFD_7SEG_2,
VFD_7SEG_3,
VFD_7SEG_4,
VFD_7SEG_5,
VFD_7SEG_6,
VFD_7SEG_7,
VFD_7SEG_8,
VFD_7SEG_9
};
struct pm_uart_samp_priv_info {
uint32_t custom;
void *dvc_hdl;
};
void *dev;
void pm_uart_samp_evt_proc(uint8_t event, void *frame, uint32_t length, void *caller)
{
struct pm_uart_samp_priv_info *pcaller;
pcaller = (struct pm_uart_samp_priv_info *)caller;
switch (event) {
case PM_SEND_OK:
UART_SAMP_LOGI("PM_SEND_OK \r\n");
break;
case PM_SEND_ERROR:
UART_SAMP_LOGI("PM_SEND_ERROR\r\n");
dev_close(pcaller->dvc_hdl);
break;
case PM_RECV_OK:
UART_SAMP_LOGI("PM_RECV_OK\r\n");
break;
case PM_RECV_ERROR:
UART_SAMP_LOGI("PM_RECV_ERROR\r\n");
break;
}
}
int32_t vfd_set_str_Tm1652(const char *s)
{
uint8_t i, bStrLen;
uint8_t vfd_buf[1+TOTAL_SEG+2];
uint8_t data[2] = {GR1_CTRL_ADDR, DISPLAY_ON};
int16_t c = 0;
bStrLen = strlen(s);
vfd_buf[0] = GR1_DISPLAY_ADDR;
for (i = 0; i < TOTAL_SEG; i++) {
if (i < bStrLen) {
if ((s[i] >= 'a') && (s[i] <= 'z')) {
c = vfd_char[s[i] - 'a'];
} else if ((s[i] >= 'A') && (s[i] <= 'Z')) {
c = vfd_char[s[i] - 'A'];
} else if ((s[i] >= '0') && (s[i] <= '9')) {
c = vfd_digit[s[i] - '0'];
} else {
c = 0;
}
} else {
c = 0;
}
vfd_buf[i+1] = c & 0xff;
}
vfd_buf[TOTAL_SEG+1] = 0x00 & 0xff;
vfd_buf[TOTAL_SEG+2] = 0x00 & 0xff;
dev_write(dev, vfd_buf, (TOTAL_SEG+3), pm_uart_samp_evt_proc); //发送显示数据
vTaskDelay(5);//根据规格书,发送间隔要> 3ms
dev_write(dev, data, 2, pm_uart_samp_evt_proc); //发送显示控制命令
return 0;
}
int32_t InitVfd_Tm1652(void)
{
struct pm_uart_param cfg;
cfg.baud = 19200;//波特率设置为19200
cfg.mode = PM_UART_MODE_NORMAL;
cfg.bit = PM_UART_DATA_BITS_8; //设置为8位数据位
cfg.parity = PM_UART_PARITY_ODD;//设置为奇数校验
cfg.stop = PM_UART_STOP_BITS_1; //设置为1位停止位
struct pm_uart_samp_priv_info *pcaller;
pcaller = (struct pm_uart_samp_priv_info *)malloc(sizeof(struct pm_uart_samp_priv_info));
dev = dev_open("uart1", &cfg, sizeof(cfg), pcaller);
if (dev == NULL) {
UART_SAMP_LOGI("open error\r\n");
return -1;
}
pcaller->dvc_hdl = dev;
return 0;
}
int32_t DeinitVfd_Tm1652(void)
{
dev_close(dev);
return 0;
}
更多推荐


所有评论(0)