如图所示 验证成功
这是厂家给的原理图
可以看到只用了9个按键,TM1638最高支持3bitx8 24个按键 典型电路如下
代码如下 精简了一些代码 增加了串口输出 打印按键的键值
<代码直接复制粘贴就行 引脚不要接错哈>
/*********************************************************************/
/*--TM1638.ino
/*--2022.10.6--
/*--ESP32_WROOM_32E--
/*--ARDUINO IDE 2.0--
/ ********************************************************************/
//esp32 IO初始化
void IO_init(void)
{
pinMode(18,OUTPUT); //18 DIO
pinMode(19,OUTPUT); //19 CLK
pinMode(21,OUTPUT); //21 STB
}
//CLK DIO STB 引脚高低电平 宏定义
#define CLK_1() digitalWrite(19, HIGH)
#define CLK_0() digitalWrite(19, LOW)
#define DIO_1() digitalWrite(18, HIGH)
#define DIO_0() digitalWrite(18, LOW)
#define STB_1() digitalWrite(21, HIGH)
#define STB_0() digitalWrite(21, LOW)
//读 DIO 引脚电平
#define R_DIO digitalRead(18)
//共阴数码管段码
unsigned char Num_tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
//TM1638低8段位码 [SEG1-SEG8]
unsigned char WeiL_tab[]={0xce,0xcc,0xca,0xc8,0xc6,0xc4,0xc2,0xc0};
//TM1638高2段位码 [SEG9-SEG10]
unsigned char WeiH_tab[]={0xcf,0xcd,0xcb,0xc9,0xc7,0xc5,0xc3,0xc1};
//TM1638键值
#define K1S1 1
#define K1S2 2
#define K1S3 3
#define K1S4 4
#define K1S5 5
#define K1S6 6
#define K1S7 7
#define K1S8 8
#define K2S1 9
#define K2S2 10
#define K2S3 11
#define K2S4 12
#define K2S5 13
#define K2S6 14
#define K2S7 15
#define K2S8 16
#define K3S1 17
#define K3S2 18
#define K3S3 19
#define K3S4 20
#define K3S5 21
#define K3S6 22
#define K3S7 23
#define K3S8 24
void TM1638_W_DATA(unsigned char DATA) //写数据函数
{
unsigned char i;
for(i=0;i<8;i++)
{
CLK_0();
if(DATA&0X01)
DIO_1();
else
DIO_0();
DATA>>=1;
CLK_1();
}
}
void TM1638_W_CMD(unsigned char cmd) //写命令函数
{
STB_0();
TM1638_W_DATA(cmd);
STB_1();
}
void Write_DATA(unsigned char add,unsigned char DATA) //指定地址写入数据
{
TM1638_W_CMD(0x44);
STB_0();
TM1638_W_DATA(add);
TM1638_W_DATA(DATA);
STB_1();
}
unsigned char TM1638_Read(void) //读数据函数
{
unsigned char i;
unsigned char temp=0;
DIO_1(); //设置为输入
for(i=0;i<8;i++)
{
temp>>=1;
CLK_0();
CLK_1(); //CLK上升沿读数据才有效
if(R_DIO)
temp|=0x80;
}
return temp;
}
unsigned char Read_Onekey(void) //读取按键键值 不支持组合键
{
unsigned char key_val[4],i,key=0;
STB_0();
TM1638_W_DATA(0x42); //读键扫数据命令,注意 这里要先读完4字节键值才能置STB为1,否则键值无效
//将从芯片读出的4字节数据存进数组
for(i=0;i<4;i++)
key_val[i]=TM1638_Read();
STB_1();
if(key_val[0]!=0) //按键在KS1或KS2
{
/*************************************************************************
B0 B1 B2 B3 B4 B5 B6 B7
K3(S1) K2(S1) K1(S1) (X) K3(S2) K2(S2) K1(S2) (X)
从芯片读出一字节数据有位,6位数据有效,其余两位用x表示
*************************************************************************/
switch(key_val[0])
{
case 0x01:
key=K3S1;
break;
case 0x02:
key=K2S1;
break;
case 0x04:
key=K1S1;
break;
case 0x10:
key=K3S2;
break;
case 0x20:
key=K2S2;
break;
case 0x40:
key=K1S2;
break;
}
}
else if(key_val[1]!=0) //按键在KS3或KS4
{
/*************************************************************************
B0 B1 B2 B3 B4 B5 B6 B7
K3(S3) K2(S3) K1(S3) (X) K3(S4) K2(S4) K1(S4) (X)
从芯片读出一字节数据有位,6位数据有效,其余两位用x表示
*************************************************************************/
switch(key_val[1])
{
case 0x01:
key=K3S3;
break;
case 0x02:
key=K2S3;
break;
case 0x04:
key=K1S3;
break;
case 0x10:
key=K3S4;
break;
case 0x20:
key=K2S4;
break;
case 0x40:
key=K1S4;
break;
}
}
else if(key_val[2]!=0) //按键在KS5或KS6
{
/*************************************************************************
B0 B1 B2 B3 B4 B5 B6 B7
K3(S5) K2(S5) K1(S5) (X) K3(S6) K2(S6) K1(S6) (X)
从芯片读出一字节数据有位,6位数据有效,其余两位用x表示
*************************************************************************/
switch(key_val[2])
{
case 0x01:
key=K3S5;
break;
case 0x02:
key=K2S5;
break;
case 0x04:
key=K1S5;
break;
case 0x10:
key=K3S6;
break;
case 0x20:
key=K2S6;
break;
case 0x40:
key=K1S6;
break;
}
}
else if(key_val[3]!=0) //按键在KS7或KS8
{
/*************************************************************************
B0 B1 B2 B3 B4 B5 B6 B7
K3(S7) K2(S7) K1(S7) (X) K3(S8) K2(S8) K1(S8) (X)
从芯片读出一字节数据有位,6位数据有效,其余两位用x表示
*************************************************************************/
switch(key_val[3])
{
case 0x01:
key=K3S7;
break;
case 0x02:
key=K2S7;
break;
case 0x04:
key=K1S7;
break;
case 0x10:
key=K3S8;
break;
case 0x20:
key=K2S8;
break;
case 0x40:
key=K1S8;
break;
}
}
return key;
}
void WriteSEG9_LED(unsigned char sta) //控制全部LEB函数,STA9 表示各个LED状态
{
unsigned char i;
for(i=0;i<8;i++)
{
if(sta&(1<<i))
Write_DATA(WeiH_tab[i],1);
else
Write_DATA(WeiH_tab[i],0);
}
}
void WriteSEG10_LED(unsigned char sta) //控制全部LEB函数,STA10 表示各个LED状态
{
unsigned char i;
for(i=0;i<8;i++)
{
if(sta&(1<<i))
Write_DATA(WeiH_tab[i],2);
else
Write_DATA(WeiH_tab[i],0);
}
}
void Write_LED(unsigned char sta9,unsigned char sta10) //控制全部LEB函数,STA9和STA10 表示各个LED状态
{
// 0b 1 0 0 0 0 0 0 0
// 0b 0 1 1 0 0 0 0 0
Write_DATA(WeiH_tab[7],((sta10&0x80)>>6)|((sta9&0x80)>>7));
Write_DATA(WeiH_tab[6],((sta10&0x40)>>5)|((sta9&0x40)>>6));
Write_DATA(WeiH_tab[5],((sta10&0x20)>>4)|((sta9&0x20)>>5));
Write_DATA(WeiH_tab[4],((sta10&0x10)>>3)|((sta9&0x10)>>4));
Write_DATA(WeiH_tab[3],((sta10&0x08)>>2)|((sta9&0x08)>>3));
Write_DATA(WeiH_tab[2],((sta10&0x04)>>1)|((sta9&0x04)>>2));
Write_DATA(WeiH_tab[1],(sta10&0x02)|((sta9&0x02)>>1));
Write_DATA(WeiH_tab[0],((sta10&0x01)<<1)|(sta9&0x01));
}
//TM1638初始化函数
void init_TM1638(void)
{
unsigned char i;
TM1638_W_CMD(0x89); //亮度(0x88-0x8f)8级亮度可调
TM1638_W_CMD(0x40); //采用地址自动加1
STB_0(); //
TM1638_W_DATA(0xc0); //设置起始地址
for(i=0;i<16;i++) //传送16个字节的数据
TM1638_W_DATA(0x00);
STB_1();
}
void sys_init(void)
{
unsigned char i;
IO_init(); //IO初始化
delay(1);
init_TM1638(); //TM1638初始化
for(i=0;i<8;i++)
Write_DATA(WeiL_tab[i],0x80|Num_tab[8]); //上电检查8位数码管 数码管全亮
Write_LED(0xff,0xff); //上电检查全部LED LED全亮
delay(500);
Write_LED(0,0); //检查完 所有LED关闭
for(i=0;i<8;i++)
Write_DATA(WeiL_tab[i],0x00); //检查完 所有数码管关闭
/*****************************显示数码管后两位位0*******************************/
Write_DATA(WeiL_tab[6],Num_tab[0]);
Write_DATA(WeiL_tab[7],Num_tab[0]);
}
void setup() {
// put your setup code here, to run once:
sys_init();
Serial.begin(115200);
}
unsigned char key=0;
void loop() {
// put your main code here, to run repeatedly:
key=Read_Onekey();
if(key>=1&&key<=24)
{
Write_DATA(WeiL_tab[6],Num_tab[key/10]);
Write_DATA(WeiL_tab[7],Num_tab[key%10]);
Serial.printf("KEY %d PRESS\n",key);
if(key==1)
{
Write_LED(0x60,0x80);
}
else if(key==2)
{
Write_LED(0xda,0x40);
}
else if(key==3)
{
Write_LED(0xf2,0x20);
}
else if(key==9)
{
Write_LED(0x66,0x10);
}
else if(key==10)
{
Write_LED(0xb6,0x08);
}
else if(key==11)
{
Write_LED(0xbe,0x04);
}
else if(key==17)
{
Write_LED(0xe0,0x02);
}
else if(key==18)
{
Write_LED(0xfe,0x01);
}
else if(key==19)
{
Write_LED(0xf6,0x01);
}
while(Read_Onekey()==key); //等待按键释放 消抖
}
}