数码之家

 找回密码
 立即注册
搜索
查看: 3732|回复: 12

[STM] STM32L412核心板驱动TM1628

[复制链接]
发表于 2020-2-26 11:54:00 | 显示全部楼层 |阅读模式
为了利用一块从旧点钞机上拆卸的数码管和按键控制板,花了几天的时间来研究其控制芯片。下图是这块控制板的正面,主要元件是一个三位的数码管和三个独立的微动按键:



下图是控制板的反面,主角就是TM1628控制芯片:




这是一块带键盘扫描功能的LED驱动专用控制芯片,有28个引脚,最大可以扫描10*2个按键,可以控制从4位17段到7位11段数码管显示。在这块旧点钞机拆下的控制板上,三个按键占用了KEY1的KS1~KS3引脚,三位数码管的位码对应GRID1~GRID3引脚、段码对应SEG4~SEG10引脚,新添加的五色LED灯就利用了GRID4对应的SEG4~SEG8引脚。下图是TM1628管脚定义:


下图是这块控制板上数码管引脚与控制芯片引脚的对应关系:



驱动这块控制板时还遇上了坑,折腾了几天才找到原因,详见求助贴:https://www.mydigit.cn/forum.php?mod=viewthread&tid=126114

下图是测试过程:











本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

打赏

参与人数 2家元 +70 收起 理由
家睦 + 60
人艰不拆了 + 10

查看全部打赏

发表于 2020-2-26 13:15:34 | 显示全部楼层
这个芯片官方手册上就有驱动程序。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-26 14:44:51 | 显示全部楼层
我搜索到的资料中只有程序设计流程图,我是按照流程图来写的代码,通过逻辑分析仪来调整时序的。
回复 支持 反对

使用道具 举报

发表于 2020-2-27 22:55:58 | 显示全部楼层
居然看到STM32驱动NOKIA屏,好新鲜
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-28 08:32:57 | 显示全部楼层
jazzy_zhou 发表于 2020-2-27 22:55
居然看到STM32驱动NOKIA屏,好新鲜

这个LCD5110的显示屏不贵,当时我买了10块,很多制作都用这个屏。
回复 支持 反对

使用道具 举报

发表于 2022-5-31 13:59:31 | 显示全部楼层
这个TM1628与CPU怎么连线?只接CPU的SPI接口的MOSI吗?MISO咋办?
回复 支持 反对

使用道具 举报

发表于 2022-5-31 14:01:27 | 显示全部楼层
这个TM1628与CPU接线怎么接?DIO管脚是连接CPU的SPI接口的MOSI吗?那MISO咋办?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-31 15:45:12 | 显示全部楼层
ivy_tulip 发表于 2022-5-31 14:01
这个TM1628与CPU接线怎么接?DIO管脚是连接CPU的SPI接口的MOSI吗?那MISO咋办?

我没有启用单片机的SPI,而是直接用3个引脚来控制DIO(2)、CLK(2)和STB(3)。
回复 支持 反对

使用道具 举报

发表于 2022-5-31 15:48:11 | 显示全部楼层
hujj 发表于 2020-2-26 14:44
我搜索到的资料中只有程序设计流程图,我是按照流程图来写的代码,通过逻辑分析仪来调整时序的。 ...

楼主方便提供下代码吗?目前小白一个
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-31 17:06:04 | 显示全部楼层
下面是TM1628及TM1639的驱动代码,我在STM32G431开发板上调试通过的,用在其他开发板可能需要调整CLK的延时时间。

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

  4. extern uint8_t LD_Buff[16],keyok,keys[5],LD_dsp; //,half,angles;
  5. extern uint16_t wait,count;

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

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

  31. const uint8_t dig1639[][2]=
  32. {

  33.     0x0f,0x03,    //'0'
  34.         0x06,0x00,    //'1'
  35.         0x0b,0x05,    //'2'
  36.         0x0f,0x04,    //'3'
  37.         0x06,0x06,    //'4'
  38.         0x0d,0x06,    //'5'
  39.         0x0d,0x07,    //'6'
  40.         0x07,0x00,    //'7'
  41.         0x0f,0x07,    //'8'
  42.         0x0f,0x06,    //'9'
  43.         0x0e,0x06,    //'Y'
  44.         0x07,0x03,    //'M'
  45.         0x0e,0x05,    //'D'
  46.         0x04,0x0e,    //'h'
  47.         0x04,0x06,    //'m'
  48.         0x0c,0x08,    //'s'
  49.         0x00,0x04,    //'-'
  50.         0x08,0x00,    //'_'
  51.        
  52.        
  53. };


  54. void Delay_us(uint16_t s)
  55. {
  56.     uint16_t i,j;
  57.         for(i=0; i<s; i++)
  58.         for(j=0; j<10; j++);
  59. }


  60. /***************************************************
  61. *程 序 名:TM1628_DIO(uint8_t dir)
  62. *作    用:DIO引脚配置
  63. *输入参数:dir(0=输出,1=输入)
  64. *转出参数:无
  65. ***************************************************/
  66. void TM1628_DIO(uint8_t dir)                //DAT端口配置(根据需要配置成输出或输入模式)
  67. {
  68.         GPIO_InitTypeDef GPIO_InitStruct;
  69.     if(dir == 0){
  70.         GPIO_InitStruct.Pin = LCD_DIN_Pin;   //SDA输出模式、弱上拉
  71.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  72.         GPIO_InitStruct.Pull = GPIO_NOPULL;
  73.         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  74.         HAL_GPIO_Init(LCD_DIN_GPIO_Port, &GPIO_InitStruct);
  75.         }
  76.         else{
  77.             GPIO_InitStruct.Pin = LCD_DIN_Pin; //SDA输入模式
  78.         GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  79.         HAL_GPIO_Init(LCD_DIN_GPIO_Port, &GPIO_InitStruct);
  80.         }
  81.         HAL_GPIO_WritePin(LCD_DIN_GPIO_Port,LCD_DIN_Pin,GPIO_PIN_SET);
  82. }


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

  119.         TM1628_DIO(1);         //设置sda为输入状态

  120.         STB_reset();           //拉低STB开始读按键
  121.         for(i=0; i<5; i++){
  122.             key[i] = TM1628_Read();
  123.         }
  124.         STB_set();             //拉高STB结束读操作
  125.         TM1628_DIO(0);         //设置DIO为输出,以便其他函数使用
  126.         //处理按键
  127.     if(0 == keyok){
  128.         if(key[0]&0x01){   //功能键
  129.                     keys[0]++;
  130.                         keyok = 1;     //设置按键标志
  131.                 }
  132.             if(key[0]&0x02){   //预置键
  133.                     keys[1]++;
  134.                         keyok = 1;     //设置按键标志
  135.                 }
  136.             if(key[1]&0x01){   //复位键
  137.                     keys[2]++;
  138.                         keyok = 1;     //设置按键标志
  139.                 }
  140.             if(key[1]&0x02){   //绿按键
  141.                     keys[3]++;
  142.                         keyok = 1;     //设置按键标志
  143.                 }
  144.     }
  145. }

  146. /******************************************************
  147. *程 序 名:TM6128_Read
  148. *作    用:TM6128芯片读1字节操作
  149. *输入参数:无
  150. *返回参数:读到的数据(1bety)
  151. ******************************************************/
  152. uint8_t TM1628_Read(void)
  153. {
  154.     uint8_t dat,i;
  155. //        CLK_reset();           //拉高CLK准备读数据

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

  159.                 dat>>=1;
  160.                 CLK_set();         //拉高CLK

  161.         if(DIO_read())
  162.                     dat|=0x80;
  163.                 else
  164.                     __NOP();

  165.                 Delay_us(1);
  166.         }
  167.         return dat;
  168. }


  169. /******************************************************
  170. *程 序 名:TM6128_Write
  171. *作    用:TM6128芯片写1字节操作
  172. *输入参数:要写入的数据(bety)
  173. *返回参数:无
  174. ******************************************************/
  175. void TM1628_Write(uint8_t dat)
  176. {
  177.     uint8_t i;
  178.        
  179.         //开始写一字节数据(低位先)

  180.         for(i=0;i<8;i++){
  181.                 CLK_reset();       //拉低CLK准备写数据
  182.         if(dat&0x01)
  183.                 {
  184.                         DIO_set();
  185.                 }
  186.                 else
  187.                 {
  188.                         DIO_reset();
  189.                 }
  190.                 Delay_us(1);       //延时并准备数据

  191.         CLK_set();         //拉高CLK
  192.                 Delay_us(1);       //延时并准备数据         
  193.         dat = dat>>1;
  194.         }
  195. }


  196. /******************************************************
  197. *程 序 名:Display_Digits(uint16_t value)
  198. *作    用:TM6128芯片转换显示数码(3位有效数字)
  199. *输入参数:要显示的数值(value),转换数码存放在LD_Buff中
  200. *返回参数:无
  201. ******************************************************/
  202. void Display_Digits(uint16_t value)
  203. {
  204.     uint8_t n;              //当前位值
  205.        
  206.     n = value / 100;
  207.     LD_Buff[1] = dig[n][0];
  208.         LD_Buff[0] = dig[n][1];
  209.        
  210.         n = value % 100 / 10;
  211.         LD_Buff[3] = dig[n][0];
  212.         LD_Buff[2] = dig[n][1];
  213.        
  214.         n = value % 10;
  215.         LD_Buff[5] = dig[n][0];
  216.         LD_Buff[4] = dig[n][1];
  217.        
  218. //        TM1628_Data();       
  219. }


  220. /******************************************************
  221. *程 序 名:Display_DateSet(uint8_t type,uint8_t val)
  222. *作    用:准备显示日期调整数据
  223. *输入参数:type(显示类型)
  224. *          val(显示的数值)
  225. *返回参数:无
  226. ******************************************************/
  227. void Display_DateSet(uint8_t type,uint8_t val)
  228. {

  229.         if(type == 6){                  //保存设置'SEV'
  230.         LD_Buff[1] = dig[5][0];
  231.         LD_Buff[0] = dig[5][1];
  232.         LD_Buff[3] = dig[18][0];
  233.         LD_Buff[2] = dig[18][1];
  234.         LD_Buff[5] = dig[19][0];
  235.         LD_Buff[4] = dig[19][1];
  236.         }
  237.         else{
  238.             Display_Digits(val);        //先转换数值
  239.         LD_Buff[1] = dig[9+type][0];
  240.         LD_Buff[0] = dig[9+type][1];//首位显示YMDhm
  241.         }
  242. }


  243. /*********************************************
  244. * 函数名称:LD_display(uint8_t dsp,uint16_t val)
  245. * 函数功能:准备显示ADC转换值
  246. * 入口参数:dsp  当前显示的内容(1=显示标识U1-、2=显示数值、3=显示标识U2-、4=显示数值)
  247. *           val  要显示的数值
  248. * 出口参数:无
  249. * 备注:
  250. *********************************************/
  251. void Display_AdcVal(uint8_t type,uint16_t val)
  252. {
  253.         switch(type){
  254.         case 1:
  255.                         LD_Buff[0] = dig[19][1];   //'U'
  256.                         LD_Buff[1] = dig[19][0];
  257.                         LD_Buff[2] = dig[1][1];    //'1'
  258.                         LD_Buff[3] = dig[1][0];
  259.                         LD_Buff[4] = dig[16][1];   //'-'
  260.                         LD_Buff[5] = dig[16][0];
  261.                     break;

  262.         case 2:
  263.                         LD_Buff[0] = dig[19][1];   //'U'
  264.                         LD_Buff[1] = dig[19][0];
  265.                         LD_Buff[2] = dig[2][1];    //'2'
  266.                         LD_Buff[3] = dig[2][0];
  267.                         LD_Buff[4] = dig[16][1];   //'-'
  268.                         LD_Buff[5] = dig[16][0];                       
  269.                     break;

  270.                 case 3:
  271.                         LD_Buff[0] = dig[19][1];   //'U'
  272.                         LD_Buff[1] = dig[19][0];
  273.                         LD_Buff[2] = dig[3][1];    //'3'
  274.                         LD_Buff[3] = dig[3][0];
  275.                         LD_Buff[4] = dig[16][1];   //'-'
  276.                         LD_Buff[5] = dig[16][0];                       
  277.                     break;

  278.         default:
  279.                         if(val > 999){
  280.                             val = val / 10;
  281.                                 Display_Digits(val);   //转换数字码
  282.                                 LD_Buff[3] |= 0x08;    //在第二位加小数点
  283.                         }
  284.                         else{
  285.                             Display_Digits(val);   //转换数字码
  286.                                 LD_Buff[1] |= 0x08;    //在第一位加小数点
  287.                         }       
  288.         }                       
  289. }


  290. /******************************************************
  291. *程 序 名:TM6139_Data(viod)
  292. *作    用:将Buf缓冲区14个字节写入TM6128芯片
  293. *          同时读5个字节的键盘数据到Buf
  294. *输入参数:无
  295. *返回参数:无
  296. ******************************************************/
  297. void TM1639_Data(void)
  298. {
  299.     uint8_t i,key[5];
  300.         TM1628_DIO(0);         //设置DIO为输出
  301.        
  302.         STB_reset();           //拉低STB开始操作
  303.         TM1628_Write(0x40);    //设置写操作
  304.         STB_set();             //结束本命令
  305.        
  306.         STB_reset();           //拉低STB开始操作
  307.         TM1628_Write(0xc0);    //地址从0开始
  308.         Delay_us(1);
  309.        
  310.         for(i=0; i<16; i++){
  311.             TM1628_Write(LD_Buff[i]);
  312.                 Delay_us(2);       //Twait>2us
  313.         }
  314.         STB_set();             //拉高STB结束写操作
  315.         Delay_us(4);
  316.         STB_reset();           //拉低STB发出显示模式命令
  317.         TM1628_Write(0x8c);    //开显示,脉冲宽度11/16
  318.     STB_set();             //拉高STB结束写操作
  319.        
  320.         STB_reset();           //拉低STB发出读键盘命令
  321.         TM1628_Write(0x42);    //

  322.         TM1628_DIO(1);         //设置sda为输入状态

  323.         STB_reset();           //拉低STB开始读按键
  324.         for(i=0; i<5; i++){
  325.             key[i] = TM1628_Read();
  326.         }
  327.         STB_set();             //拉高STB结束读操作
  328.         TM1628_DIO(0);         //恢复sda为输出状态

  329.         //处理按键

  330.     if(key[0]&0x01)
  331.                 keys[0]++;
  332.         if(key[0]&0x02)
  333.                 keys[1]++;
  334.         if(key[1]&0x01)
  335.                 keys[2]++;
  336.         if(key[1]&0x02)
  337.                 keys[3]++;
  338. /*
  339.         LCD_write_value(0,3,3,0,1,keys[0]);
  340.         LCD_write_value(30,3,3,0,1,keys[1]);
  341.         LCD_write_value(60,3,3,0,1,keys[2]);
  342. */
  343. }

  344. void display1639(uint16_t val,uint16_t cout)
  345. {
  346.     uint8_t n;              //当前位值
  347.        
  348.     n =  val / 100;
  349.     LD_Buff[0] = dig1639[n][0];
  350.         LD_Buff[1] = dig1639[n][1];
  351.        
  352.         n = val % 100 / 10;
  353.         LD_Buff[2] = dig1639[n][0];
  354.         LD_Buff[3] = dig1639[n][1];
  355.        
  356.         n = val % 10;
  357.         LD_Buff[4] = dig1639[n][0];
  358.         LD_Buff[5] = dig1639[n][1];
  359.        
  360.         n = cout / 10000;
  361.         LD_Buff[6] = dig1639[n][0];
  362.         LD_Buff[7] = dig1639[n][1];
  363.        
  364.         n = cout % 10000 / 1000;
  365.         LD_Buff[8] = dig1639[n][0];
  366.         LD_Buff[9] = dig1639[n][1];
  367.        
  368.         n = cout % 1000 / 100;
  369.         LD_Buff[10] = dig1639[n][0];
  370.         LD_Buff[11] = dig1639[n][1];
  371.        
  372.         n = cout % 100 / 10;
  373.         LD_Buff[12] = dig1639[n][0];
  374.         LD_Buff[13] = dig1639[n][1];
  375.        
  376.         n = cout % 10;
  377.         LD_Buff[14] = dig1639[n][0];
  378.         LD_Buff[15] = dig1639[n][1];
  379.        
  380. //           buf[half] |= ld;  //给数组奇单元的第4位置1
  381.        
  382. //        TM1639_Data();       
  383. }


复制代码
回复 支持 反对

使用道具 举报

发表于 2023-2-16 09:47:54 | 显示全部楼层
hujj 发表于 2022-5-31 17:06
下面是TM1628及TM1639的驱动代码,我在STM32G431开发板上调试通过的,用在其他开发板可能需要调整CLK的延时 ...

楼主你好,是不是使用用这个TM1628的芯片的代码段,就可以实现点击按键实现数码管的显示,譬如点击第一行一列,数码管显示1-1
回复 支持 反对

使用道具 举报

发表于 2023-2-16 09:53:23 | 显示全部楼层
hujj 发表于 2022-5-31 17:06
下面是TM1628及TM1639的驱动代码,我在STM32G431开发板上调试通过的,用在其他开发板可能需要调整CLK的延时 ...

还有我看这个相关的代码段,有一部分需要用到从TM1639芯片上引用相关的内容作用到TM1628芯片上面,如果删除的话,通过点击按键实现数码管的相应点亮是否还能实现呢
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-26 13:49 , Processed in 0.171601 second(s), 13 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表