Nucleo-L412KB驱动TM1628LED控制芯片

2020-03-01 11:52发布

    TM1628是一个带键盘扫描的LED驱动控制专用芯片,我正好有一块从旧点钞机上拆卸的TM1628控制板,板上除了TM1628芯片外,还有一个三位的数码管和三个微动按键(见下图),这段时间不能外出,正好就琢磨将其驱动起来。
    下面是控制板的正面,一个三位数码管和三个独立的微动按键:
TM1628_0.jpg


    这是控制板的反面,一颗TM1628在正中央:
TM1628_1.jpg


    网上搜索到相关的资料后便开始编写代码,尝试将其点亮起来。首先根据器件的引脚和控制板上的连线,检查出三个按键分别接在KS1~KS3引脚上,数据管对应的引脚位置见下图,这些都是驱动编制程序的基本数据。
Boad_2.jpg


    TM1628的控制主要有3个引脚,首先的STB,这个类似片选引脚,每当其从高低拉低后紧接着就是发出命令,之后可以进行读写操作,STB拉高后结束操作。其次是DIO,这是数据输入、输出引脚,串行输送,低位在前。然后是CLK,由主控设备给出时钟信号,时钟从高拉低时芯片准备输出数据(读取键盘数据时),时钟从低拉高时输入数据(主控设备应先准备好数据)。
    然后就按照数据手册中的时序图和程序设计流程图来编写代码。TM1628有固定地址和自动地址两种方式,自动地址是每输入一个字节到芯片后,地址自动加一,我采用的是自动地址方式。
    参照软件I2C的代码很快就完成了基本代码的编写,但在调试时却掉进了坑里,反复修改调试都不成功,时钟无论如何都无法调准,高电平维持时间不到1us,无论如何调整延时,延长的都是低电平时间,高电平时间纹丝不动,更换单片机的引脚也是同样结果。两天时间过去了,调试毫无进展,我以为可能是TM1628芯片损坏了准备放弃时,忽然想到不连接时钟引脚,单独测试单片机时发现时钟信号正常了由此确定还是TM1628控制板的问题。
    连接了TM1628时的时序图:
TM1628_5.jpg


    时钟高电平时宽度不到1us:
TM1628_4.jpg



    不连接TM1628的CLK引脚时,单片机的时序正常:
TM1628_3.jpg


    时钟高低电平的宽度基本在5us左右:
TM1628_2.jpg



    通过仔细分析发现这块控制板上DIO引脚有上拉电阻,而CLK引脚却没有,目前的现象是时钟上拉后不能维持,我就尝试添加了一个上拉电阻,然后再测试,成功了,下面是成功之后的时序图:
TM1628_6.jpg


    下图是控制板上添加了时钟的上拉电阻:
TM1628_9.jpg

    这是数码管显示与LCD显示屏同步显示:
TM1628_8.jpg


    下面是驱动代码:


  1. #include "main.h"
  2. #include "tm1628.h"
  3. #include "lcd_5110.h"

  4. extern uint8_t buf[14],keys[3];

  5. const uint8_t dig[][2]=
  6. {

  7.     0x03,0xf0,    //'0'
  8.         0x02,0x10,    //'1'
  9.         0x02,0xe8,    //'2'
  10.         0x02,0xb8,    //'3'
  11.         0x03,0x18,    //'4'
  12.         0x01,0xb8,    //'5'
  13.         0x01,0xf8,    //'6'
  14.         0x02,0x90,    //'7'
  15.         0x03,0xf8,    //'8'
  16.         0x03,0xb8,    //'9'
  17.         0x03,0x38,    //'Y'
  18.         0x03,0xd0,    //'M'
  19.         0x02,0x78,    //'D'
  20.         0x01,0x58,    //'h'
  21.         0x00,0x58,    //'m'
  22.         0x00,0x38,    //'s'
  23.         0x00,0x08,    //'-'
  24.         0x00,0x20,    //'-'
  25.        
  26.        
  27. };

  28. void Delay_us(uint8_t s)
  29. {
  30.     uint8_t i;
  31.         for(i=0; i<s; i++);
  32. //        for(j=0; j<10; j++);
  33. }


  34. /***************************************************
  35. *程 序 名:SI2C_Sda(uint8_t dir)
  36. *作    用:DAT引脚配置
  37. *输入参数:dir(0=输出,1=输入)
  38. *转出参数:无
  39. ***************************************************/
  40. void SI2C_Sda(uint8_t dir)                  //DAT端口配置(根据需要配置成输出或输入模式)
  41. {
  42.         GPIO_InitTypeDef GPIO_InitStruct;
  43.     if(dir == 0){
  44.         GPIO_InitStruct.Pin = SI2C_SDA_Pin; //SDA输出模式、弱上拉
  45.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  46.         GPIO_InitStruct.Pull = GPIO_NOPULL;
  47.         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  48.         HAL_GPIO_Init(SI2C_SDA_GPIO_Port, &GPIO_InitStruct);
  49.         }
  50.         else{
  51.             GPIO_InitStruct.Pin = SI2C_SDA_Pin; //SDA输入模式
  52.         GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  53.         HAL_GPIO_Init(SI2C_SDA_GPIO_Port, &GPIO_InitStruct);
  54.         }
  55.         HAL_GPIO_WritePin(SI2C_SDA_GPIO_Port,SI2C_SDA_Pin,GPIO_PIN_SET);
  56. }


  57. /******************************************************
  58. *程 序 名:TM6128_Init
  59. *作    用:初始化TM6128芯片引脚
  60. *输入参数:无
  61. *返回参数:无
  62. ******************************************************/
  63. void TM1628_Init(void)
  64. {
  65.     //配置GPIO
  66.         GPIO_InitTypeDef GPIO_InitStruct;
  67.         GPIO_InitStruct.Pin = SI2C_SCL_Pin|SI2C_SDA_Pin;
  68.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  69.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  70.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  71.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  72.     //设置引脚为高电平
  73.     HAL_GPIO_WritePin(LED1_2_GPIO_Port,LED1_2_Pin,GPIO_PIN_SET);
  74.         HAL_GPIO_WritePin(SI2C_SCL_GPIO_Port,SI2C_SCL_Pin,GPIO_PIN_SET);
  75.         HAL_GPIO_WritePin(SI2C_SDA_GPIO_Port,SI2C_SDA_Pin,GPIO_PIN_SET);
  76.        
  77. }


  78. /******************************************************
  79. *程 序 名:TM6128_Data(viod)
  80. *作    用:将Buf缓冲区14个字节写入TM6128芯片
  81. *          同时读5个字节的键盘数据到Buf
  82. *输入参数:无
  83. *返回参数:无
  84. ******************************************************/
  85. void TM1628_Data(void)
  86. {
  87.     uint8_t i;
  88.         SI2C_Sda(0);           //设置DIO为输出
  89.        
  90.         STB_reset();           //拉低STB开始操作
  91.         TM1628_Write(0x03);    //设置显示模式(7位10段)
  92.         STB_set();             //结束本命令
  93.        
  94.         STB_reset();           //拉低STB开始操作
  95.         TM1628_Write(0x40);    //设置写操作
  96.         STB_set();             //结束本命令
  97.        
  98.         STB_reset();           //拉低STB开始操作
  99.         TM1628_Write(0xc0);    //地址从0开始
  100.         Delay_us(1);
  101.        
  102.         for(i=0; i<14; i++){
  103.             TM1628_Write(buf[i]);
  104.                 Delay_us(2);       //Twait>2us
  105.         }
  106.         STB_set();             //拉高STB结束写操作
  107.         Delay_us(4);
  108.         STB_reset();           //拉低STB发出显示模式命令
  109.         TM1628_Write(0x8c);    //开显示,脉冲宽度11/16
  110.     STB_set();             //拉高STB结束写操作
  111.        
  112.         STB_reset();           //拉低STB发出读键盘命令
  113.         TM1628_Write(0x42);    //

  114.         SI2C_Sda(1);           //设置sda为输入状态

  115.         STB_reset();           //拉低STB开始读按键
  116.         for(i=0; i<5; i++){
  117.             buf[i] = TM1628_Read();
  118.         }
  119.         STB_set();             //拉高STB结束读操作
  120.         //处理按键

  121.     if(buf[0]&0x01)
  122.                 keys[0]++;
  123.         if(buf[0]&0x08)
  124.                 keys[1]++;
  125.         if(buf[1]&0x01)
  126.                 keys[2]++;

  127.         LCD_write_value(0,3,3,0,1,keys[0]);
  128.         LCD_write_value(30,3,3,0,1,keys[1]);
  129.         LCD_write_value(60,3,3,0,1,keys[2]);
  130.        
  131. }


  132. /******************************************************
  133. *程 序 名:TM6128_Read
  134. *作    用:TM6128芯片读1字节操作
  135. *输入参数:无
  136. *返回参数:读到的数据(1bety)
  137. ******************************************************/
  138. uint8_t TM1628_Read(void)
  139. {
  140.     uint8_t dat,i;
  141. //        CLK_reset();           //拉高CLK准备读数据

  142.         for(i=0;i<8;i++){
  143.                 CLK_reset();       //拉低CLK
  144.                 Delay_us(1);       //延时并准备数据

  145.                 dat>>=1;
  146.                 CLK_set();         //拉高CLK

  147.         if(1 == HAL_GPIO_ReadPin(SI2C_SDA_GPIO_Port,SI2C_SDA_Pin))
  148.             dat|=0x80;
  149.                 else
  150.                 __NOP();

  151. //                Delay_us(1);
  152.         }
  153.         return dat;
  154. }


  155. /******************************************************
  156. *程 序 名:TM6128_Write
  157. *作    用:TM6128芯片写1字节操作
  158. *输入参数:要写入的数据(bety)
  159. *返回参数:无
  160. ******************************************************/
  161. void TM1628_Write(uint8_t dat)
  162. {
  163.     uint8_t i;
  164.        
  165.         //开始写一字节数据(低位先)

  166.         for(i=0;i<8;i++){
  167.                 CLK_reset();       //拉低CLK准备写数据
  168.         if(dat&0x01)
  169.                 {
  170.                         DIO_set();
  171.                 }
  172.                 else
  173.                 {
  174.                         DIO_reset();
  175.                 }
  176. //                Delay_us(1);       //延时并准备数据

  177.         CLK_set();         //拉高CLK
  178.                 __NOP();
  179.                 __NOP();
  180.                 __NOP();
  181. //                Delay_us(1);       //延时并准备数据         
  182.         dat = dat>>1;               
  183.         }
  184. }


  185. /******************************************************
  186. *程 序 名:Display_Digits(uint16_t value)
  187. *作    用:TM6128芯片显示变量(3位有效数字)
  188. *输入参数:要显示的变量(value)
  189. *返回参数:无
  190. ******************************************************/
  191. void Display_Digits(uint16_t value)
  192. {
  193.     uint8_t n;              //当前位值
  194.        
  195.     n = value / 100;
  196.     buf[1] = dig[n][0];
  197.         buf[0] = dig[n][1];
  198.        
  199.         n = value % 100 / 10;
  200.         buf[3] = dig[n][0];
  201.         buf[2] = dig[n][1];
  202.        
  203.         n = value % 10;
  204.         buf[5] = dig[n][0];
  205.         buf[4] = dig[n][1];
  206.        
  207.         TM1628_Data();
  208.        
  209. }


复制代码




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
mmuuss586
1楼-- · 2020-03-01 13:45
 精彩回答 2  元偷偷看……
21ic小喇叭
2楼-- · 2020-03-01 17:27
您可以把您的帖子链接,分享到论坛活动:https://bbs.21ic.com/icview-2901292-1-1.html ,可以赢得打赏哦
hu9jj
3楼-- · 2020-03-01 21:57
21ic小喇叭 发表于 2020-2-25 10:23
您可以把您的帖子链接,分享到论坛活动:https://bbs.21ic.com/icview-2901292-1-1.html ,可以赢得打赏哦 ...

谢谢提醒!已经分享了。
一路向北lm
4楼-- · 2020-03-01 23:23
感谢分享,那匹马被板子挡着了哈
hu9jj
5楼-- · 2020-03-02 03:16
一路向北lm 发表于 2020-2-25 19:01
感谢分享,那匹马被板子挡着了哈

用杜邦线连接测试,不方便观察,所以就利用了旧摆件,将显示屏粘在松树上,核心板正好将马头遮住了,只好委屈它们了。
一路向北lm
6楼-- · 2020-03-02 05:00
 精彩回答 2  元偷偷看……

一周热门 更多>