23116|11

1234

帖子

4

TA的资源

纯净的硅(高级)

楼主
 

MCU对TM1638的控制详谈(不包括按键) [复制链接]

 
本帖最后由 ywlzh 于 2017-2-22 18:04 编辑


    从淘宝买来的,TM1638专门是控制LED的,LED组合起来就可以变成数码管,还有按键,这个我就没管了,不想管了,发这个帖子只是为了记录下经验,待以后会过头来看的时候,可以一遍就知道,所以尽量写得详细点。
   手头上的项目用的是共阳极,而我买的是共阴极的,还好,全都弄出来了。
   单片机怎么跟它通信,这个还得细看TM1638的数据手册,一个新的芯片到手,千万别第一时间上网找例程,先把这个片子的数据手册看一遍
    TM1638.pdf (873.68 KB, 下载次数: 324)
    先截个图出来看   
   
    可以看的出来,跟单片机通信就只需要DIO,STB, CLK三根线,这三根线最好是做好上拉电阻,TM1638是不需要刷数据的,共阴极的是只需要在对应的地址上写data就OK了,它自己会去刷新数据。   先看共阴极的电路图,也就是淘宝买的这个模块的电路图
   

   段码是SEG1-SEG8,片选是GR1-GR8 ,片选的几个正好对应着地址   
   
   从上面的图就可以看出,写这些数据进去就可以了:自动地址增加,是否显示,调节亮度...写这些命令的时候是需要先让STB信号为高电平的,写命令,再拉低STB信号,写数据到对应地址的时候,也需要先把STB信号给拉高,写地址,写数据,再拉低STB信号。
   怎么写数据进去呢?就得看时序图了
   
   基本靠STB为低,CLK的上升沿,然后来确定DIO的高低,高为1,低为0。
   开始写程序吧,我用的stm32f407
   先确定引脚
   
  1. #define DIO   PAout(1)
  2. #define CLK   PAout(4)
  3. #define STB   PAout(6)
复制代码


再把引脚初始化,如果要读按键的话,就需要把DIO写成开漏模式,这样就既可以读也可以写了,
  1. void TM1638_GPIO_init(void)
  2. {
  3.         GPIO_InitTypeDef GPIO_InitStructure;
  4.         
  5.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //ê1ÄüGPIODμÄê±Öó
  6.         
  7.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_4;
  8.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//êä3ö
  9.         GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;  //íÆíìêä3ö
  10.         GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;  //éÏà-êä3ö
  11.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; //¸ßËùGPIO
  12.         GPIO_Init(GPIOA,&GPIO_InitStructure);
  13.         
  14.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;  //DIO ¿a©Ä£ê½
  15.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//êä3ö
  16.         GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;  //¿a©êä3ö
  17.         GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;  //éÏà-êä3ö
  18.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; //¸ßËùGPIO
  19.         GPIO_Init(GPIOA,&GPIO_InitStructure);
  20.         
  21. }
复制代码


引脚做好初始化后,就需要开始写怎么写一个字节了。
  1. void TM1638_Write(unsigned char        DATA)                        //D′êy¾Yoˉêy
  2. {
  3.         unsigned char i;
  4.         for(i=0;i<8;i++)
  5.         {
  6.                 CLK=0;
  7.                 if(DATA&0X01)
  8.                         DIO=1;
  9.                 else
  10.                         DIO=0;
  11.                 DATA>>=1;
  12.                 CLK=1;
  13.         }
  14. }
复制代码

读一个字节,我就没管了,继续下去,要向对应的地址上写入一个字节,封装一些上面的函数就可以了
  1. void Write_Nixie_DATA(unsigned char add,unsigned char DATA)                //Ö¸¶¨μØÖ·D′èëêy¾Y
  2. {
  3.         Write_COM(0x44);
  4.         STB=0;
  5.         TM1638_Write(0xc0|add);
  6.         TM1638_Write(0xff&DATA); //这样不影响其他位,考虑共阳极的接法。
  7.         STB=1;
  8. }
复制代码

还可以封装成写命令的函数
  1. void Write_COM(unsigned char cmd)                //·¢ËíÃüáî×Ö
  2. {
  3.         STB=0;
  4.         TM1638_Write(cmd);
  5.         STB=1;
  6. }
复制代码

这样基本就可以了,举个例子,我要让GR3对应的数码管显示0怎么办?看图

如果对应的段码显示用的SEG1-SEG8,则需要在04H地址上写0的段码就可以了,比如这样
Write_Nixie_DATA(2<<1,0x3F);   //从0开始数,GR3对应着第2个数码管,左移有个好处就是在06H地址就可以表示成 3<<1
这样看程序就知道是哪个数码管需要显示什么数据,如果用的SEG9做LED驱动的,我要第6个LED亮,就是GR7做片选,SEG9要为高,对应的地址为0DH。
Write_Nixie_DATA(2*6+1,0x3F);          //用2*i+1 可以一下就知道是哪个LED了。
好了,共阴极的程序基本算是完了,共阳极的怎么办,有共阴极的要共阳的干嘛?有没有考虑过共阴极的电路最多只能控制8个数码管,而共阳极的可以控制10个数码管(不用LED)。先看电路图。

咋一眼一看,很奇怪的电路,原本设计片选的GR1-GR8变成了段码输送。原本设计成段码的变成了片选。这里就得转换一下思路了,还是在对应的地址上写数据,怎么写,而且一个数码管有变动,整个地址的数据就得重新写一遍。这一点比较麻烦,花点时间想想也是可以想出来的。先看程序
  1. uint8_t Seg1[] = {                                                                        // 第一位数码管显示码值
  2.         0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,                // 0
  3.         0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,                  // 1
  4.         0x01,0x01,0x00,0x01,0x01,0x00,0x01,0x00,                // 2
  5.         0x01,0x01,0x01,0x01,0x00,0x00,0x01,0x00,                // 3
  6.         0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,                // 4
  7.         0x01,0x00,0x01,0x01,0x00,0x01,0x01,0x00,                // 5
  8.         0x01,0x00,0x01,0x01,0x01,0x01,0x01,0x00,                // 6
  9.         0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,                // 7
  10.         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,                // 8
  11.         0x01,0x01,0x01,0x01,0x00,0x01,0x01,0x00,                // 9
  12.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,                // 10
  13. };
  14. uint8_t Seg2[] = {                                                                        // 第二位数码管显示码值
  15.         0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00,                // 0
  16.         0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,                  // 1
  17.         0x02,0x02,0x00,0x02,0x02,0x00,0x02,0x00,                // 2
  18.         0x02,0x02,0x02,0x02,0x00,0x00,0x02,0x00,                // 3
  19.         0x00,0x02,0x02,0x00,0x00,0x02,0x02,0x00,                // 4
  20.         0x02,0x00,0x02,0x02,0x00,0x02,0x02,0x00,                // 5
  21.         0x02,0x00,0x02,0x02,0x02,0x02,0x02,0x00,                // 6
  22.         0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,                // 7
  23.         0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,                // 8
  24.         0x02,0x02,0x02,0x02,0x00,0x02,0x02,0x00,                // 9
  25.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,                // 10
  26. };        
复制代码


先用第一个和第二数码管做例子,
  1. [size=3]void TM_Disp(uint8_t num1, uint8_t num2)
  2. {
  3.         Write_Nixie_DATA(0x00, Seg1[num1*8]  |Seg2[num2*8] );
  4.         Write_Nixie_DATA(0x02,Seg1[num1*8+1]|Seg2[num2*8+1]);
  5.         Write_Nixie_DATA(0x04,Seg1[num1*8+2]|Seg2[num2*8+2]);
  6.         Write_Nixie_DATA(0x06, Seg1[num1*8+3]|Seg2[num2*8+3]);
  7.         Write_Nixie_DATA(0x08, Seg1[num1*8+4]|Seg2[num2*8+4]);
  8.         Write_Nixie_DATA(0x0a, Seg1[num1*8+5]|Seg2[num2*8+5]);
  9.         Write_Nixie_DATA(0x0c, Seg1[num1*8+6]|Seg2[num2*8+6]);
  10.         Write_Nixie_DATA(0x0e, Seg1[num1*8+7]|Seg2[num2*8+7]);
  11. }[/size]
复制代码
假如要第一个数码管显示1,第二数码管显示7,就只需要 TM_Disp(1,7);就可以了
要是第三个数码管呢?在这个函数的基础上再增加个数组,应该是0x04,对应的第三位。0x08对应的第4个数码管了。
  1. uint8_t Seg3[] = {                                                                        // 第三位数码管显示码值
  2.         0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x00,                // 0
  3.         0x00,0x04,0x04,0x00,0x00,0x00,0x00,0x00,                  // 1
  4.         0x04,0x04,0x00,0x04,0x04,0x00,0x04,0x00,                // 2
  5.         0x04,0x04,0x04,0x04,0x00,0x00,0x04,0x00,                // 3
  6.         0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,                // 4
  7.         0x04,0x00,0x04,0x04,0x00,0x04,0x04,0x00,                // 5
  8.         0x04,0x00,0x04,0x04,0x04,0x04,0x04,0x00,                // 6
  9.         0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,                // 7
  10.         0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,                // 8
  11.         0x04,0x04,0x04,0x04,0x00,0x04,0x04,0x00,                // 9
  12.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,                // 10
  13. };
复制代码

函数再增加一个参数
  1. void TM_Disp(uint8_t num1, [/size][size=3]uint8_t [/size][size=3]num2, [/size][size=3]uint8_t [/size][size=3]num3)
  2. {
  3.         Write_Nixie_DATA(0x00, Seg1[num1*8]  |Seg2[num2*8]  |Seg3[num3*8]  );
  4.         Write_Nixie_DATA(0x02,Seg1[num1*8+1]|Seg2[num2*8+1]|Seg3[num3*8+1]);
  5.         Write_Nixie_DATA(0x04,Seg1[num1*8+2]|Seg2[num2*8+2]|Seg3[num3*8+2]);
  6.         Write_Nixie_DATA(0x06, Seg1[num1*8+3]|Seg2[num2*8+3]|Seg3[num3*8+3]);
  7.         Write_Nixie_DATA(0x08, Seg1[num1*8+4]|Seg2[num2*8+4]|Seg3[num3*8+4]);
  8.         Write_Nixie_DATA(0x0a, Seg1[num1*8+5]|Seg2[num2*8+5]|Seg3[num3*8+5]);
  9.         Write_Nixie_DATA(0x0c, Seg1[num1*8+6]|Seg2[num2*8+6]|Seg3[num3*8+6]);
  10.         Write_Nixie_DATA(0x0e,Seg1[num1*8+7]|Seg2[num2*8+7]|Seg3[num3*8+7]);
  11. }
复制代码



以此类推,9个数码管就可以写了 上个图,做结束吧,这个是共阳极的




此内容由EEWORLD论坛网友ywlzh原创,如需转载或用于商业用途需征得作者同意并注明出处








此帖出自单片机论坛

最新回复

谢楼主分享。   详情 回复 发表于 2020-1-27 15:29
点赞 关注(4)
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 

回复
举报

4

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
本帖最后由 江枫三号楼 于 2017-7-14 15:55 编辑

围观,刚刚刚接触数据手册的时候,看得是一头雾水,然后来看这篇文章,感觉有那么一点意思了。 不过信号拉低或者拉高,没有最小hold时间吗?
此帖出自单片机论坛
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
看帖顶贴,谢楼主
此帖出自单片机论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

4
 
江枫三号楼 发表于 2017-7-14 15:48
围观,刚刚刚接触数据手册的时候,看得是一头雾水,然后来看这篇文章,感觉有那么一点意思了。 不过信号拉 ...

这是我写的吗?怎么一点印象都没有了呢?
此帖出自单片机论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

5
 
买了块类似的板子,8位共阳数码管,更新一个数字就得整个寄存器重写一遍,如果不是要驱动10位数码管,共阳实在得不偿失。
此帖出自单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

6
 
本帖最后由 yxrj 于 2018-7-9 18:14 编辑

我也是用的共阳数码管,按楼主的程序已经调通。只是8个数码管需要8个数组,如果加上小数点就更多了,所以改动了一下显示函数,只要一个数组就可以了。
void TM_Disp(uint8_t num1,uint8_t num2,uint8_t num3,uint8_t num4,uint8_t num5,uint8_t num6,uint8_t num7,uint8_t num8)
{
unsigned char i;
for(i =0;i<8;i++)
  Write_Nixie_DATA(i<<1,Seg1[num1*8+i]|Seg1[num2*8+i]<<1|Seg1[num3*8+i]<<2|Seg1[num4*8+i]<<3|Seg1[num5*8+i]<<4|Seg1[num6*8+i]<<5|Seg1[num7*8+i]<<6|Seg1[num8*8+i]<<7);
}
此帖出自单片机论坛

点评

的确 8个数码管的数据正好对应字节的8个位,移位处理就好了,不用额外再写数组  详情 回复 发表于 2018-7-13 10:05
 
 
 

回复

1234

帖子

4

TA的资源

纯净的硅(高级)

7
 
yxrj 发表于 2018-7-9 18:13
我也是用的共阳数码管,按楼主的程序已经调通。只是8个数码管需要8个数组,如果加上小数点就更多了,所以改 ...

的确 8个数码管的数据正好对应字节的8个位,移位处理就好了,不用额外再写数组
此帖出自单片机论坛
 
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

8
 
yxrj 发表于 2018-7-9 18:13
我也是用的共阳数码管,按楼主的程序已经调通。只是8个数码管需要8个数组,如果加上小数点就更多了,所以改 ...

有什么简单的方法可以让想要的数码管显示小数点吗?谢谢
此帖出自单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

9
 
感谢楼主!
此帖出自单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

10
 
yxrj 发表于 2018-7-9 18:13
我也是用的共阳数码管,按楼主的程序已经调通。只是8个数码管需要8个数组,如果加上小数点就更多了,所以改 ...

!真得方便很多
此帖出自单片机论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

11
 

本人小白,LED驱动那块 没看懂,有哪位大神再详细讲解下这个是什么意思Write_Nixie_DATA(2*6+1,0x3F);  

此帖出自单片机论坛
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

12
 

谢楼主分享。

此帖出自单片机论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表