STM32之TM1638数码管及键盘驱动

STM32之TM1638数码管及键盘驱动

  • [Chapter1 STM32之TM1638数码管及键盘驱动](#Chapter1 STM32之TM1638数码管及键盘驱动)
  • [Chapter2 TM1638芯片 LED数码管驱动器 详细介绍](#Chapter2 TM1638芯片 LED数码管驱动器 详细介绍)

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

c 复制代码
#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

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-9
                                            0x66,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=0
        delay_us(50);
        if(byte&0x01)
        {
            DIO_1(); //DIO=1
        }
        else
        {
            DIO_0(); //DIO=0
        }
        byte>>=1;
        CLK_1(); //CLK=1
        delay_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);//显示开,亮度1

    TM1638_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);//显示开,亮度1

    TM1638_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);//显示开,亮度1

    TM1638_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);//显示开,亮度1

    TM1638_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=0
        data = DIO_Read();  //读取DIO值
        if(data) temp|=0x80; //按位或:与0或不变、与1或置1
        CLK_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

Chapter2 TM1638芯片 LED数码管驱动器 详细介绍

https://blog.csdn.net/qq_39829913/article/details/104661381






相关推荐
π同学1 天前
基于RT-Thread的STM32开发第十二讲SD卡篇——DFS文件系统
stm32·dfs·rtthread·sdio
一路往蓝-Anbo1 天前
第37期:启动流程(二):C Runtime (CRT) 初始化与重定位
c语言·开发语言·网络·stm32·单片机·嵌入式硬件
三伏5221 天前
HAL_I2C_ER_IRQHandler函数解析
stm32·单片机·hal库
想放学的刺客1 天前
单片机嵌入式试题(第19期)嵌入式系统故障诊断与固件升级设计
c语言·stm32·嵌入式硬件·物联网·51单片机
一路往蓝-Anbo1 天前
第46期:低功耗设计:软硬件协奏曲
驱动开发·stm32·单片机·嵌入式硬件
不能跑的代码不是好代码1 天前
STM32 标准外设库中关于 GPIO(通用输入输出) 模块的函数声明
stm32·单片机·嵌入式硬件
Moonquakes5401 天前
嵌入式开发基础学习笔记(LED实验C语言实现、蜂鸣器实验、SDK裸机驱动、链接脚本、BSP工程管理)
stm32·单片机·嵌入式硬件
我是海飞1 天前
杰理 AC792N 使用 WebSocket 连接百度语音大模型,实现 AI 对话
c语言·单片机·嵌入式·ai对话·杰理·websockey
Zeku1 天前
Linux内核中SPI 子系统的整体架构
stm32·freertos·linux驱动开发·linux应用开发
不凉帅2 天前
NO.2计算机基础
网络·嵌入式·硬件·软件·计算机基础