找回密码
 立即注册
查看: 143|回复: 7

TM1638按键数码管模块应用

[复制链接]
已绑定手机

6

主题

16

回帖

770

积分

高级会员

积分
770
发表于 2026-10-19 18:36:36 | 显示全部楼层 |阅读模式
网购了一块TM1638模块,跟单片机STC8G1K08A接在一起搞了个时钟。

TM1638模块使用了三根端口与单片机联接,分别是STB(片选),CLK(时钟输入),DIO(数据输入/输出),再加两VCC和GND两根电源。
TM1638图及数据分配.png



这个模块共有S1-S8共8个按键,有8位的数码管显示,另外还有一排共8个的LED灯。可通过单片机编程分别控制各个按键,数码管显示不同内容。


TM1638.jpg
回复

使用道具 举报 送花

已绑定手机

6

主题

16

回帖

770

积分

高级会员

积分
770
 楼主| 发表于 2026-10-19 19:00:34 | 显示全部楼层
  1. void init_TM1638(void)
  2. {
  3.         unsigned char i;
  4.         Write_COM(0x8A);       //亮度 (0x88-0x8f)8级亮度可调 0x80关闭
  5.         Write_COM(0x40);       //采用地址自动加1
  6.         STB=0;                             //
  7.         TM1638_Write(0xc0);    //设置起始地址
  8.         for(i=0;i<16;i++)             //传送16个字节的数据--这里是初始化全部写0
  9.         TM1638_Write(0x00);
  10.         STB=1;
  11. }
复制代码


TM1638数据.png
回复

使用道具 举报 送花

已绑定手机

6

主题

16

回帖

770

积分

高级会员

积分
770
 楼主| 发表于 2026-10-19 19:05:47 | 显示全部楼层
  1. unsigned char TM1638_Read(void)                                        //读数据函数
  2. {
  3.         unsigned char i;
  4.         unsigned char temp=0;
  5.         DIO=1;        //设置为输入
  6.         for(i=0;i<8;i++)
  7.         {
  8.                 temp>>=1;
  9.                 CLK=0;
  10.                 CLK=1;
  11.                 if(DIO) temp|=0x80;    //上升延后读数据
  12.         }
  13.         return temp;
  14. }
复制代码



读取与接收1个Bit数据都是在时钟的上升沿后进行操作
截图202610191903273915.jpg
回复

使用道具 举报 送花

已绑定手机

6

主题

16

回帖

770

积分

高级会员

积分
770
 楼主| 发表于 2026-10-19 19:07:43 | 显示全部楼层
  1. void Write_DATA(unsigned char add,unsigned char DATA)                //指定地址写入数据
  2. {
  3.         Write_COM(0x44);                                //~~~ 设 置 写 显 存 的 数 据 命 令 采 用 固 定 地 址
  4.         STB=0;
  5.         TM1638_Write(0xc0|add);
  6.         TM1638_Write(DATA);
  7.         STB=1;
  8. }
复制代码


截图202610191907391410.jpg
回复

使用道具 举报 送花

已绑定手机

6

主题

16

回帖

770

积分

高级会员

积分
770
 楼主| 发表于 2026-10-19 19:09:56 | 显示全部楼层
  1. unsigned char Read_key(void)
  2. {
  3.         unsigned char c[4],i,key_value=0;
  4.         STB=0;
  5.         TM1638_Write(0x42);                    //读键扫数据 命令
  6.         for(i=0;i<4;i++)               
  7.                 c[i]=TM1638_Read();
  8.         STB=1;
  9.         for(i=0;i<4;i++)                                        //4个字节数据合成一个字节
  10.                 key_value|=c[i]<<i;
  11.         for(i=0;i<8;i++)
  12.                 if((0x01<<i)==key_value)
  13.                         break;
  14.         return i;
  15. }
复制代码
读按键的扫描程序

截图202610191909396403.jpg
回复

使用道具 举报 送花

已绑定手机

6

主题

16

回帖

770

积分

高级会员

积分
770
 楼主| 发表于 2026-10-19 19:14:23 | 显示全部楼层
  1. void Write_allLED(unsigned char LED_flag)                                        //控制全部LED函数,LED_flag表示各个LED状态
  2. {
  3.         unsigned char i;
  4.         for(i=0;i<8;i++)
  5.                 {
  6.                         if(LED_flag&(1<<i))
  7. //                                Write_DATA(2*i+1,3);
  8.                                 Write_DATA(2*i+1,1);                                //地址是 0x01,0x03,0x05,0x07,0x09,0x0B,0x0D,0x0F  +0xC0
  9.                         else
  10.                                 Write_DATA(2*i+1,0);
  11.                 }
  12. }
复制代码
写8个LED灯的程序 ,因为LED接的都是SEG9脚,所以地址是0xC1,0xC3,0xC5,0xC7,0xC9,0xCB,0xCD,0xCE这些。

截图202610191912108397.jpg
回复

使用道具 举报 送花

已绑定手机

6

主题

16

回帖

770

积分

高级会员

积分
770
 楼主| 发表于 2026-10-19 19:19:32 | 显示全部楼层
  1. #include "stc8g.h"
  2. // #include        <REGX51.H>
  3. #include        <tm1638.h>
  4. typedef     unsigned char   u8;
  5. typedef     unsigned int    u16;
  6. typedef     unsigned long   u32;
  7. unsigned int num[13];                //各个数码管显示的值
  8. char num1=0,swan,wan,qian,bai,shi,ge;
  9. /*
  10. TIM_1000MS_Flag=1000ms的标志位 ;
  11. TIM_xz_Flag=修正标志位
  12. ALM_zd_Flag=整点报时标志位
  13. TIM_ds1_Flag=定时报警标志位
  14. ALM_beep_Flag=蜂鸣响标志位
  15. */
  16. bit  TIM_1000MS_Flag,TIM_100MS_Flag,TIM_xz_Flag,TIM_zd_Flag,TIM_ds1_Flag,TIM_ds2_Flag,TIM_ds3_Flag,ALM_beep_Flag;                       
  17. u8 k=0,w=0x5f,u=0;
  18. u16 j=0,z=0,y=0,x,t,s,v=0x28140;
  19. int main(void)
  20. {
  21.         unsigned char i;
  22.                 P5M0 = 0x00;
  23.     P5M1 = 0x00;
  24.           P3M0 = 0x00;
  25.     P3M1 = 0x00;
  26.   time0_init();
  27.         EA=1;            //总中断允许
  28.         init_TM1638();                                 //初始化TM1638
  29.         for(i=0;i<8;i++)
  30.         Write_DATA(i<<1,tab[0]);                       //初始化寄存器
  31.        
  32.         while(1)
  33.         {
  34.                 i=Read_key();                         //读按键值   ~~~ 这里 i=(0-7)
  35.                 if(i<8)               
  36.                         {       
  37.                           if (i==0)        //如果S1按下    k:模式切换
  38.                                  {
  39.                                         while(Read_key()==i);                                               //等待按键释放
  40.                                                 k++;
  41.                                          if (k>3) k=0;
  42.                                   }                                                
  43.                                 if (i==1)         //如果S2按下     小时-
  44.                                          {
  45.                                 while(Read_key()==i);                                                               
  46.                                          num[3+3*k]--;                                     //~~~ 数组 num[0]里的数值加                               
  47.                                                 }
  48.                                  if (i==2)        //如果S3按下     小时+
  49.                                          {                                                                                                                                               
  50.                                                 while(Read_key()==i);
  51.                                                  num[3+3*k]++;                                                                                                        //~~~ 数组 num[0]里的数值加
  52.                                                 }               
  53.                                  if (i==3)        //如果S4按下     分钟-
  54.                                          {
  55.                                                 while(Read_key()==i);
  56.                                                         num[2+3*k]--;
  57.                                                 }               
  58.                                  if (i==4)        //如果S5按下     分钟+
  59.                                          {
  60.                                                 while(Read_key()==i);
  61.                                                         num[2+3*k]++;
  62.                                                 }               
  63.                                  if (i==5)        //如果S6按下     秒-
  64.                                          {
  65.                                                 while(Read_key()==i);
  66.                                                         num[1+3*k]--;
  67.                                     }               
  68.                                  if (i==6)        //如果S7按下     秒+
  69.                                          {
  70.                                                 while(Read_key()==i);       
  71.                                                         num[1+3*k]++;
  72.                                          }                                                 
  73.                                         if (i==7)        //如果S8按下     空置
  74.                                          {
  75.                                                 while(Read_key()==i);       
  76.                                    }
  77.                   }
  78. if ((num[2]==0) &&(num[1]==0))  TIM_zd_Flag=1;      
  79. if (num[3]==num[6] && num[2]==num[5] && num[1]==num[4]) TIM_ds1_Flag=1;
  80. if (num[3]==num[9] && num[2]==num[8] && num[1]==num[7]) TIM_ds2_Flag=1;
  81. if (num[3]==num[12] && num[2]==num[11] && num[1]==num[10]) TIM_ds3_Flag=1;
  82. /*整点铃声------------------*/
  83.         if (TIM_zd_Flag==1)  
  84.                         {
  85.                                 TIM_zd_Flag=0;
  86.                                 if (TIM_100MS_Flag == 1)        {        TIM_100MS_Flag=0;        w=w<<1; ALM_beep_Flag=w & 0x80;}   
  87.                         }
  88.                         else {w=0x5f; }  //01011111  嘀。嘀嘀嘀
  89. /*定时铃声------------------*/                       
  90.                         if (TIM_ds1_Flag==1 || TIM_ds2_Flag==1 || TIM_ds3_Flag==1)
  91.                         {
  92.                                 if (TIM_100MS_Flag == 1)        {       
  93.                                 TIM_100MS_Flag=0;  v=v<<1; ALM_beep_Flag=v & 0x8000;
  94.                                 u++;
  95.                                 if (u>=30) {u=0;TIM_ds1_Flag=0;TIM_ds2_Flag=0;TIM_ds3_Flag=0;}         //u BEEP时间控制 50是5s                                               
  96.                                 }
  97.                                 if (v==0) v=0x28140;
  98.                         }       
  99.                         else  {v=0x28140;  }   //  00101000000101000000   嘀。嘀。。。。嘀。嘀。。。。
  100.                         if (ALM_beep_Flag) ALM=0; else ALM=1;       
  101.                 if (num[1+3*k]>=60) {num[1+3*k]=0;num[2+3*k]++;}
  102.                 if (num[2+3*k]>=60) {num[2+3*k]=0;num[3+3*k]++;}
  103.                 if (num[3+3*k]>=24) {num[3+3*k]=0;}
  104.                        
  105.                   swan=(num[3+3*k]/10)%10;    //小时
  106.                         wan=num[3+3*k]%10;                      //小时
  107.                   qian=(num[2+3*k]/10)%10;    //分钟
  108.                         bai=num[2+3*k]%10;                                        //分钟
  109.                         shi=(num[1+3*k]/10)%10;     //秒
  110.                         ge=num[1+3*k]%10;           //秒
  111.                
  112.                 Write_DATA((7)*2,tab[ge]);                                        //0xCE
  113.                 Write_DATA((6)*2,tab[shi]);                                        //0xCC
  114.                 Write_DATA((5)*2,tab[bai]);                                        //0xCA
  115.                 Write_DATA((4)*2,tab[qian]);                                //0xC8
  116.                 Write_DATA((3)*2,tab[wan]);                                        //0xC6
  117.                 Write_DATA((2)*2,tab[swan]);                                //0xC4
  118.            Write_DATA((0)*2,tab[k]);                                                //0xC0
  119. //                        Write_DATA(i*2,tab[num[i]]);                     // ~~~ 左边是要显示的位置(0-7)显示在1-8位数码管上。
  120. //      Write_DATA((7-num1)*2,tab[num[i]]);   // ~~~ 左边是要显示的位置(0-7)显示在1-8位数码管上。右边是要显示的数值
  121.                         Write_allLED(led[ge]);                                                        //  led灯会按跑马灯形式按 ge 的数值往右移
  122.                 }
  123. }
  124. void time0_init(void)
  125. {
  126.         AUXR |= 0x80;                        //定时器时钟1T模式
  127.         TMOD = 0x01;                        //设置定时器模式
  128.         TL0 = 0xCD;                                //设置定时初始值
  129.         TH0 = 0xD4;                                //设置定时初始值
  130.         ET0 = 1;                                //定时器中断控制位
  131.         TR0 = 1;                                //定时器0开始计时
  132. }
  133. void time0(void) interrupt 1
  134. {
  135.         TL0 = 0xCD;                                //设置定时初始值
  136.         TH0 = 0xD4;                                //设置定时初始值
  137.         t++;
  138.         j++;
  139. if (j>=1000) {j=0;num[1]++;        z++;}        //1S到计时+1
  140. if (z>=520) {z=0;  if (num[1]>0) num[1]--; }         //时间修正
  141.    
  142. if (t>=100){t=0;TIM_100MS_Flag=1;}       
  143.                 if (num[1]>=60) {num[1]=0;num[2]++;}
  144.                 if (num[2]>=60) {num[2]=0;num[3]++;}
  145.                 if (num[3]>=24) {num[3]=0;}
  146.                   swan=(num[3+3*k]/10)%10;    //小时
  147.                         wan=num[3+3*k]%10;                      //小时
  148.                   qian=(num[2+3*k]/10)%10;    //分钟
  149.                         bai=num[2+3*k]%10;                                        //分钟
  150.                         shi=(num[1+3*k]/10)%10;     //秒
  151.                         ge=num[1+3*k]%10;           //秒
  152. }
  153.                
复制代码
程序使用定时器产生1ms中断给时钟计时,分别设了整点报时和几个闹铃。
回复

使用道具 举报 送花

已绑定手机

24

主题

701

回帖

2731

积分

金牌会员

积分
2731
发表于 2026-10-20 08:55:14 | 显示全部楼层
读按键死等要不得的
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-11-8 02:08 , Processed in 0.082168 second(s), 73 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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