一、简介

        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;
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐