ESP32 Arduino TM1638 数码管 按键 LED

 如图所示 验证成功

这是厂家给的原理图

 可以看到只用了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);		       //等待按键释放 消抖
    }
}

串口打印键值

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值