TM1650数码管驱动:强大而先进的芯片

简介

TM1650是一款国产4位共阴数码管驱动芯片,它还带有矩阵按键扫码功能。它的基本参数如下:

  • 工作电压:3~5V
  • 数码管驱动模式:8段x4位共阴数码管
  • 矩阵按键驱动模式:7×4矩阵按键,不支持组合键
  • 通信接口:类IIC,使用了IIC相同的时序,但没有完全遵守IIC的协议,不带从机地址。
  •  

    引脚定义

    SCL:串行通信时钟线

    SDA:串行通信数据线

    做数码管驱动使用时

  • DIGx:数码管的位选引脚,灌电流驱动,最大可吸收150mA电流
  • A~DP:数码管的段驱动引脚,拉电流驱动,最大可输出25mA电流
  • 典型应用原理图

     

    通信协议

    TM1650使用的是类IIC接口,只是不带从机地址机制。所以总线上的基本信号也包含起始信号,ACK应答,结束信号,同时字节数据发送时,也是按照标准IIC的MSB First顺序。

    虽然TM1650不带从机地址,但是可以和其他标准I2C从机器件如AT24C02挂同一个IIC总线下,前提是地址不冲突。对于TM1650来说,所谓的从机地址就是发送start信号后紧跟的那个字节数据。拿本文来说,使用了从机地址为:0x48,0x68,0x6A,0x6C,0x6E。笔者在一个项目中,就将AT24C02和TM1650挂同一个IIC总线使用了。

    发送命令设置数码管显示工作参数

    通信格式:起始信号,模式命令(1字节),显示命令(1字节),结束信号

    这个指令用于设置数码管显示的相关参数。例如亮度,7段或者8段显示,显示的开关。模式命令固定为0x48,而显示命令则满足以下格式:

    也就是说,显示命令字节的B6~B4用于设置显示亮度,B3用于选择7段或者8段显示模式,B0用于打开或者关闭显示。

    发送驱动数码管显示的段码数据到显存

    通信格式:起始信号,地址码(1字节),数码管段数据(1字节),结束信号

    TM1650内部有4字节的显存,地址分别为0x68,0x6A,0x6C,0x6E,分别用于存放显示在DIG1,DIG2,DIG3,DIG4的段码数据。例如想要让DIG1对应的数码管位显示数字2,则要往0x68单元写入数字2的共阴段码0x5b。

    TM1650数码管驱动例程

    开发环境:Keil+GD32F130。移植的时候只需要修改tm1650_config.h 进行适配即可。

    tm1650.c

    #include "tm1650.h"
    #include "tm1650_config.h"
    
    //产生IIC总线起始信号
    static void TM1650_IIC_start(void)
    {
    	TM1650_IIC_SCL_HIGH;     //SCL=1
    	TM1650_IIC_SDA_HIGH;    //SDA=1
    	TM1650_IIC_DELAY_4US;
    	TM1650_IIC_SDA_LOW;     //SDA=0
    	TM1650_IIC_DELAY_4US;
    	TM1650_IIC_SCL_LOW;      //SCL=0
    }
    
    //产生IIC总线结束信号
    static void TM1650_IIC_stop(void)
    {
    	TM1650_IIC_SCL_LOW;      //SCL=0
    	TM1650_IIC_SDA_LOW;      //SDA=0
    	TM1650_IIC_DELAY_4US;
    	TM1650_IIC_SCL_HIGH;     //SCL=1
    	TM1650_IIC_DELAY_4US;
    	TM1650_IIC_SDA_HIGH;    //SDA=1
    }
    
    //通过IIC总线发送一个字节
    static void TM1650_IIC_write_byte(uint8_t dat)
    {
    	uint8_t i;
    	
    	TM1650_IIC_SCL_LOW;
    	for(i=0;i<8;i++)
    	{
    		TM1650_IIC_SDA_WR(dat&0x80);
    		dat<<=1;	
    		
    		TM1650_IIC_DELAY_2US;
    		TM1650_IIC_SCL_HIGH;
    		TM1650_IIC_DELAY_2US;
    		TM1650_IIC_SCL_LOW;
    		TM1650_IIC_DELAY_2US;
    	}
    }
    
    //通过IIC总线接收从机响应的ACK信号
    static uint8_t TM1650_IIC_wait_ack(void)
    {
    	uint8_t ack_signal = 0;
    	
    	TM1650_IIC_SDA_HIGH;    //SDA=1
    	TM1650_IIC_DELAY_2US;
    	TM1650_IIC_SCL_HIGH;
    	TM1650_IIC_DELAY_2US;
    	if(TM1650_IIC_SDA_RD()) ack_signal = 1;   //如果读取到的是NACK信号
    	TM1650_IIC_SCL_LOW;
    	TM1650_IIC_DELAY_2US;
    	return ack_signal;
    }
    
    
    //TM1650初始化
    void TM1650_init(void)
    {
    	TM1650_IIC_SCL_MODE_OD;  //SCL开漏输出
        TM1650_IIC_SDA_MODE_OD;  //SDA开漏输出
    
        TM1650_IIC_SDA_HIGH;   //释放SDA线
        TM1650_IIC_SCL_HIGH;   //释放SCL线
    	
    	TM1650_cfg_display(TM1650_BRIGHT5);   //初始化为5级亮度,打开显示
    	TM1650_clear();     //将显存内容清0
    }
    
    
    //作用:设置显示参数
    //备注:这个操作不影响显存中的数据
    //用例:
    //	设置亮度并打开显示:TM1650_cfg_display(TM1650_BRIGHTx)
    //	关闭显示:TM1650_cfg_display(TM1650_DSP_OFF)
    void TM1650_cfg_display(uint8_t param)
    {
    	TM1650_IIC_start();
    	TM1650_IIC_write_byte(0x48);  TM1650_IIC_wait_ack();     //固定命令
    	TM1650_IIC_write_byte(param); TM1650_IIC_wait_ack();    //参数值
    	TM1650_IIC_stop();
    }
    
    
    //将显存数据全部刷为0,清空显示
    void TM1650_clear(void)
    {
    	uint8_t dig;
    	for(dig = TM1650_DIG1 ; dig<= TM1650_DIG4 ;dig++)
    	{
    		TM1650_print(dig,0);   //将显存数据刷为0
    	}
    }
    
    //往一个指定的数码管位写入指定的显示数据
    //共阴数码管段码表:
    //const uint8_t TUBE_TABLE_0[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};                                  //共阴,0~9的数字
    //const uint8_t TUBE_TABLE_0[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};    //共阴,0~9~A~F
    //用例:
    //	在DIG1位上显示数字3: TM1650_print(TM1650_DIG1,TUBE_TABLE_0[3]);
    void TM1650_print(uint8_t dig,uint8_t seg_data)
    {
    	TM1650_IIC_start();
    	TM1650_IIC_write_byte(dig*2+0x68); TM1650_IIC_wait_ack();  //显存起始地址为0x68
    	TM1650_IIC_write_byte(seg_data); TM1650_IIC_wait_ack();    //发送段码
    	TM1650_IIC_stop();
    }
    

    tm1650.h 

    #ifndef TM1650_H_
    #define TM1650_H_
    
    
    //显示参数
    #define TM1650_BRIGHT1       0x11   /*一级亮度,打开LED显示*/
    #define TM1650_BRIGHT2       0x21   /*二级亮度,打开LED显示*/
    #define TM1650_BRIGHT3       0x31   /*三级亮度,打开LED显示*/
    #define TM1650_BRIGHT4       0x41   /*四级亮度,打开LED显示*/
    #define TM1650_BRIGHT5       0x51   /*五级亮度,打开LED显示*/
    #define TM1650_BRIGHT6       0x61   /*六级亮度,打开LED显示*/
    #define TM1650_BRIGHT7       0x71   /*七级亮度,打开LED显示*/
    #define TM1650_BRIGHT8       0x01   /*八级亮度,打开LED显示*/
    #define TM1650_DSP_OFF       0x00   /*关闭LED显示*/
    
    //数码管位选
    #define TM1650_DIG1     0
    #define TM1650_DIG2     1
    #define TM1650_DIG3     2
    #define TM1650_DIG4     3
    
    void TM1650_init(void);
    void TM1650_cfg_display(uint8_t param);
    void TM1650_clear(void);
    void TM1650_print(uint8_t dig,uint8_t seg_data);
    
    #endif //TM1650_H_
    

    tm1650_config.h 

    #ifndef TM1650_CONFIG_H_
    #define TM1650_CONFIG_H_
    
    #include "gd32f1x0.h"
    
    //==========【配置IIC驱动引脚】========
    
    //配置驱动SCL的gpio为开漏输出模式
    #define  TM1650_IIC_SCL_MODE_OD   \
    do{ gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_10); \
    gpio_output_options_set(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_10MHZ, GPIO_PIN_10); \
    }while(0)
    
    //配置驱动SDA的gpio为开漏输出模式
    #define  TM1650_IIC_SDA_MODE_OD  \
    do{ gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_9); \
    gpio_output_options_set(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_10MHZ, GPIO_PIN_9); \
    }while(0)
    
    //=====================================
    
    
    //========【配置IIC总线的信号读写和时序】=======
    //主机拉高SCL
    #define TM1650_IIC_SCL_HIGH     gpio_bit_set(GPIOA,GPIO_PIN_10)
    
    //主机拉低SCL
    #define TM1650_IIC_SCL_LOW      gpio_bit_reset(GPIOA,GPIO_PIN_10)
    
    
    //主机拉高SDA
    #define TM1650_IIC_SDA_HIGH     gpio_bit_set(GPIOA,GPIO_PIN_9)
    
    //主机拉低SDA
    #define TM1650_IIC_SDA_LOW      gpio_bit_reset(GPIOA,GPIO_PIN_9)
    
    //参数b为0时主机拉低SDA,非0则拉高SDA
    #define TM1650_IIC_SDA_WR(b)    do{                                       \
                                   if(b) gpio_bit_set(GPIOA,GPIO_PIN_9);   \
                                   else  gpio_bit_reset(GPIOA,GPIO_PIN_9); \
                                  }while(0)
    
    
    //主机读取SDA线电平状态,返回值为0为低电平,非0则为高电平
    #define TM1650_IIC_SDA_RD()    gpio_input_bit_get(GPIOA,GPIO_PIN_9) 
    
    //软件延时2us
    #define TM1650_IIC_DELAY_2US   do{for(int ii_=0;ii_<22;ii_++);}while(0)
    
    //软件延时4us
    #define TM1650_IIC_DELAY_4US   do{for(int ii_=0;ii_<40;ii_++);}while(0)
    //================================
    
    
    #endif //TM1650_CONFIG_H_
    

    物联沃分享整理
    物联沃-IOTWORD物联网 » TM1650数码管驱动:强大而先进的芯片

    发表评论