STM32之TM1638数码管及键盘驱动
STM32之TM1638数码管及键盘驱动
- Chapter1 STM32之TM1638数码管及键盘驱动
- 一.芯片简介
- tm1638.h
- tm1638.c
Chapter1 STM32之TM1638数码管及键盘驱动
原文链接:https://blog.csdn.net/qq_44764316/article/details/114154830
一.芯片简介
TM1638是带键盘扫描接口的LED(发光二极管显示器)驱动控制专用电路,内部集成有MCU 数字接口、数据锁存器、LED 高压驱动、键盘扫描等电路。主要应用于冰箱、空调 、家庭影院等产品的高段位显示屏驱动。
• 采用功率CMOS 工艺 • 显示模式 10 段×8 位 • 键扫描(8×3bit)• 辉度调节电路(占空比8 级可调)
• 串行接口(CLK,STB,DIO) • 振荡方式:RC 振荡(450KHz+5%) • 内置上电复位电路 • 采用SOP28封装
tm1638.h
#ifndef __TM1638_H
#define __TM1638_H#define MODULE_TM1638_ENABLED#ifdef MODULE_TM1638_ENABLED#include "spi.h"
#include "gpio.h"
#include "stm32f4xx_hal.h"
#include "main.h"/****************************************************************************************** TM1638模块功能实现源文件* 硬件连接:PA5--STB,PA6--CLK,PA7--DIO* 创建人:* 最后修改时间:2025-10-08***************************************************************************************
**/typedef enum {N = 0x00, Y = 0x80} PointState; //是否带小数点 Y:带,N:不带typedef enum {OFF = 0x00, ON = 0x01} LightState; //灯开关状态 On:开,Off:关//TM1638模块相关引脚定义
#define STB GPIO_PIN_7
#define CLK GPIO_PIN_8
#define DIO GPIO_PIN_9
#define GPIO_TM1638 GPIOE
#define GPIO_Pin_TM1638 STB|CLK|DIO
//#define RCC_TM1638 RCC_APB2Periph_GPIOA//引脚高低电平设置
#define STB_0() HAL_GPIO_WritePin(GPIO_TM1638, STB, GPIO_PIN_RESET)
#define STB_1() HAL_GPIO_WritePin(GPIO_TM1638, STB, GPIO_PIN_SET)#define CLK_0() HAL_GPIO_WritePin(GPIO_TM1638, CLK, GPIO_PIN_RESET)
#define CLK_1() HAL_GPIO_WritePin(GPIO_TM1638, CLK, GPIO_PIN_SET)#define DIO_0() HAL_GPIO_WritePin(GPIO_TM1638, DIO, GPIO_PIN_RESET)
#define DIO_1() HAL_GPIO_WritePin(GPIO_TM1638, DIO, GPIO_PIN_SET)//#define DIO_Read() GPIO_ReadInputDataBit(GPIO_TM1638,DIO)
#define DIO_Read() HAL_GPIO_ReadPin(GPIO_TM1638, DIO)//用户层函数
void TM1638_Init(void); //TM1638初始化函数
void TM1638_Display_Num(uint32_t data); //显示数字
void TM1638_Display_SEG(unsigned int num,unsigned char seg,PointState p); //选择数码管显示0-F
void TM1638_Display_LED(unsigned int num,LightState light); //指定led亮灭unsigned char TM1638_ReadKey(void); //TM1638读键扫数据函数
void TM1638_SEG_Off(unsigned char num); //TM1638关闭指定数码管函数
void TM1638_Clear(void); //TM1638全清//底层函数
void TM1638_Write_Byte(uint8_t byte); //TM1638单写数据,需要在函数外对STB操作
void TM1638_Write_Data(uint8_t data); //TM1638一个完整数据写入
void TM1638_Write_Addr_Bond(uint8_t addr,uint8_t data); //TM1638指定地址写入数据
unsigned char TM1638_Read(void); //TM1638读数据函数
void TM1638_GPIO_Init(void); //TM1638引脚初始化函数#endif //MODULE_TM1638_ENABLED#endif //__TM1638_H
tm1638.c
#include "tm1638.h"#ifdef MODULE_TM1638_ENABLED#include "delay_timer.h"
#include "FreeRTOS.h"
#include "task.h"/****************************************************************************************** TM1638模块功能实现源文件* 硬件连接:PA5--STB,PA6--CLK,PA7--DIO* 创建人:* 最后修改时间:2025-10-08***************************************************************************************
**/
#include "TM1638.h" //tm1638模块实现头文件unsigned char TM1638_Arr_SEG[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07, //共阴极数码管段码,不带小数点0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87, //共阴极数码管段码,带小数点0xFF,0xEF,0xF7,0xFC,0xB9,0xDE,0xF9,0xF1}; //0~F,1亮0灭//共阴极数码管段码,不带小数点,display函数用
unsigned char TM1638_Arr_SEG_Display[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0,0x3F,0x06,0x5B,0x4F,//0-90x66,0x6D,0x7D,0x07,0x7F,0x6F, 0, 0, 0, 0,0, 0, 0,0x77,0x7C,0x39,0x5E,0x79,0x71, 0};uint8_t TM1638_Addr_SEG[8]= {0xC0,0xC2,0xC4,0xC6,0xC8,0xCA,0xCC,0xCE}; //模块从右到左的八个数码管
uint8_t TM1638_Addr_LED[8]= {0xC1,0xC3,0xC5,0xC7,0xC9,0xCB,0xCD,0xCF}; //模块从右到左的八个发光二极管void TM1638_Write_Byte(uint8_t byte) //TM1638单写数据
{uint8_t i;for(i=0; i<8; i++){CLK_0(); //CLK=0delay_us(50);if(byte&0x01){DIO_1(); //DIO=1}else{DIO_0(); //DIO=0}byte>>=1;CLK_1(); //CLK=1delay_us(50);}
}
/***************************************************************************************/
/*** TM1638写数据/命令函数* 参数:data:要写入的8位数据* 返回值:无*/
void TM1638_Write_Data(uint8_t data) //TM1638写数据函数
{STB_0();delay_us(50);TM1638_Write_Byte(data);STB_1();delay_us(50);
}void (*TM1638_Write_Cmd)(uint8_t)=TM1638_Write_Data;//给函数起一个别名,函数指针
/***************************************************************************************//***************************************************************************************/
/*** TM1638写地址+数码组合函数,用于固定地址显示* 参数:cmd:要写入的8位数据* 返回值:无*/
void TM1638_Write_Addr_Bond(uint8_t addr,uint8_t data) //TM1638写数据函数
{STB_0();delay_us(50);TM1638_Write_Byte(addr);TM1638_Write_Byte(data);STB_1();delay_us(50);
}
/***************************************************************************************//***************************************************************************************/
/*** TM1638固定地址显示函数* 参数1:data:写入的数字,长度八位* 返回值:无*/
void TM1638_Display_Num(uint32_t data)
{unsigned int dataL=0,dataR=0;dataL=data/10000;dataR=data%10000;TM1638_Write_Cmd(0x44);//固定地址,写数据TM1638_Write_Cmd(0x88);//显示开,亮度1TM1638_Write_Addr_Bond(TM1638_Addr_SEG[0],TM1638_Arr_SEG[dataL/1000]);TM1638_Write_Addr_Bond(TM1638_Addr_SEG[1],TM1638_Arr_SEG[dataL%1000/100]);TM1638_Write_Addr_Bond(TM1638_Addr_SEG[2],TM1638_Arr_SEG[dataL%100/10]);TM1638_Write_Addr_Bond(TM1638_Addr_SEG[3],TM1638_Arr_SEG[dataL%10]);TM1638_Write_Addr_Bond(TM1638_Addr_SEG[4],TM1638_Arr_SEG[dataR/1000]);TM1638_Write_Addr_Bond(TM1638_Addr_SEG[5],TM1638_Arr_SEG[dataR%1000/100]);TM1638_Write_Addr_Bond(TM1638_Addr_SEG[6],TM1638_Arr_SEG[dataR%100/10]);TM1638_Write_Addr_Bond(TM1638_Addr_SEG[7],TM1638_Arr_SEG[dataR%10]);
}
/***************************************************************************************//***************************************************************************************/
/*** TM1638指定地址显示数码,0-F* 参数1:num:数码管位置12345678* 参数2:seg:字符0-F* 参数3:p:N/Y* 返回值:无*/
void TM1638_Display_SEG(unsigned int num,unsigned char seg,PointState p)
{TM1638_Write_Cmd(0x44);//固定地址,写数据TM1638_Write_Cmd(0x88);//显示开,亮度1TM1638_Write_Addr_Bond(TM1638_Addr_SEG[num-1],TM1638_Arr_SEG_Display[seg-32]|p);
}
/***************************************************************************************//***************************************************************************************/
/*** TM1638指定LED亮灭* 参数1:num:LED位置* 参数2:light:OFF/ON* 返回值:无*/
void TM1638_Display_LED(unsigned int num,LightState light)
{TM1638_Write_Cmd(0x44);//固定地址,写数据TM1638_Write_Cmd(0x88);//显示开,亮度1TM1638_Write_Addr_Bond(TM1638_Addr_LED[num],light);
}
/***************************************************************************************//***************************************************************************************/
/*** TM1638全清* 参数1:无* 返回值:无*/
void TM1638_Clear(void)
{uint8_t i;TM1638_Write_Data(0x44); //普通模式,固定地址,写数据到显示寄存器TM1638_Write_Data(0x88); //显示开,亮度第1级for(i=0; i<16; i++){TM1638_Write_Addr_Bond(0XC0+i,0X00); //全地址写入0X00}
}
/***************************************************************************************//***************************************************************************************/
/*** TM1638关闭指定数码管函数* 参数:serial:数码管序号1-8* 返回值:无*/
void TM1638_SEG_Off(unsigned char num) //TM1638关闭指定数码管函数
{TM1638_Write_Cmd(0x44);//固定地址,写数据TM1638_Write_Cmd(0x88);//显示开,亮度1TM1638_Write_Addr_Bond(TM1638_Addr_SEG[num-1],0x80);
}
/***************************************************************************************//***************************************************************************************/
/*** TM1638读数据函数* 参数:无* 返回值:读取的8位数据*/
unsigned char TM1638_Read(void) //读数据函数
{unsigned char i,data,temp=0;DIO_1(); //DIO=1,设置为输入for(i=0; i<8; i++){temp>>=1;CLK_0(); //CLK=0data = DIO_Read(); //读取DIO值if(data) temp|=0x80; //按位或:与0或不变、与1或置1CLK_1(); //CLK=1}return temp;
}
/***************************************************************************************//***************************************************************************************/
/*** TM1638读键扫数据函数* 参数:无* 返回值:读取的按键号,1~8*/
unsigned char TM1638_ReadKey(void) //TM1638读键扫数据函数
{unsigned char c[4],i,key_value=0;STB_0(); //STB=0,开始写命令TM1638_Write_Byte(0x42); //普通模式,地址自动增加,读键扫数据for(i=0; i<4; i++) c[i]=TM1638_Read(); //读取键值STB_1(); //STB=1,读键值结束//数据处理for(i=0; i<4; i++)key_value|=c[i]<<i;for(i=0; i<8; i++)if((0x01<<i)==key_value) break;return (i+1);//返回按键值,与模块上的相对应
}
/***************************************************************************************//***************************************************************************************/
/*** TM1638-GPIO初始化函数* 参数:无* 返回值:无*/
void TM1638_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0}; //GPIO参数设置结构体__HAL_RCC_GPIOE_CLK_ENABLE(); //APB2外设时钟使能:GPIOA/*Configure GPIO pins : */GPIO_InitStruct.Pin = STB|CLK|DIO;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIO_TM1638, &GPIO_InitStruct);}
/***************************************************************************************//***************************************************************************************/
/*** TM1638初始化函数* 参数:无* 返回值:无*/
void TM1638_Init(void) //TM1638初始化函数
{TM1638_GPIO_Init();//GPIO初始化TM1638_Clear();
}
/***************************************************************************************/#endif //MODULE_TM1638_ENABLED
