基于STM32CUBE的UART串口驱动TM1652程序

最近用到了TM1652这个芯片,它是天微的一款LED(发光二极管、数码管、点阵屏)驱动控制专用芯片。之前用过天微的TM1638,除了能驱动LED,还支持按键状态检测,简直是节省IO的利器。TM1638的通信接口是一个类似SPI的接口,需要三个IO。

而这次的TM1652因为功能相对少一些(只能驱动LED,不能检测按键),所以用到的IO也少了,只需要一个IO。功能特点如下:

这里关注几个地方:

  • 典型工作电压,手册里写的是5V,但是3.3V我试了,没问题。
  • 只支持共阴极数码管,不支持共阳极数码管。
  • 显示模式,支持7段X6位,或者8段X5位
  • 使用类似UART串口的协议进行通信,波特率固定19200。

别的就没什么了。我这里的电路如下,使用了一个3位的共阴极数码管,同时需要小数点,所以显示模式我需要8段的模式:

PCB布局的时候,那两个电容尽量离芯片近一些。

接下来是程序方面,我使用的单片机是STM32G030F6P6,串口2,使用软件STM32CUBE进行了UART2的基本配置,手册中对串口工作模式要求如下:

简单来说,STM32的串口配置时,波特率19200,数据长度9bits(其中包含校验位),校验位需要偶校验,以及一个停止位。STM32CUBE软件中USART2的配置如下:

除了上面说的那些配置,数据方向那里,我选择了只发送。

然后是程序,程序基于串口进行数据发送。TM1652的一帧数据包含以下内容:

  • 显示地址命令+显示数据;
  • 示控制命令+显示控制调节命令。

    简单来说:1、告诉芯片你要让哪一位显示什么数据;2、告诉芯片工作模式,例如亮度、占空比、7段还是8段的工作模式。

    这里我使用了地址自动加1的模式,即写入一个地址(要显示的那一位)后,连续写入三个数据。因为地址会自动加1,所以不用频繁写入地址。具体代码如下:

    //0~9 最后一个是:空 
    
      const uint8_t seg_no_dot[11] = {0x3f,0x06,0x5b,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00}; 
    
      const uint8_t seg_with_dot[11] = {0xbf,0x86,0xdb,0xcF,0xe6,0xeD,0xfD,0x87,0xfF,0xeF,0x80};
    
      void address_auto_add1(uint8_t addr,uint8_t dat1,uint8_t dat2,uint8_t dat3)
      {
      	uint8_t dat_buf[4] = {0};
      	dat_buf[0] = addr;
      	dat_buf[1] = dat1;
      	dat_buf[2] = dat2;
      	dat_buf[3] = dat3;
      	HAL_UART_Transmit(&huart2,dat_buf,4,0xfff);
      	HAL_Delay(5);
    
      	dat_buf[0] = 0x18;
      	dat_buf[1] = 0x1c;
      	HAL_UART_Transmit(&huart2,dat_buf,2,0xfff);
      	HAL_Delay(5);
    }

    这是一帧完整的数据操作,首先定义了一个数组,然后把第一个数据地址写入,然后依次写入三个数据。然后使用STM32的串口函数发送这四个数据。

    第二步,首先写入显示控制命令(0x18),然后写入显示调节控制命令(0x1c)。参照手册中的表格:

    可以知道,0x1c的功能是:设置占空比为8/16,设置段驱动电流为4/8,设置8段5位输出。每一步操作完成后,手册建议加3毫秒的延时,我这里加了5毫秒。

    在主函数中调用该函数:

    address_auto_add1(0x08, seg_no_dot[i], seg_no_dot[i], seg_no_dot[i]); 

    显示正常:

    有需要TM1652程序的,关注公众号,回复关键词:025,即可获取下载链接。我是单片机爱好者-MCU起航,打完收工!

    发表评论

    此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据