TM1638显示板(8数码管+8LED+8按键)驱动程序(显示功能)

26 篇文章 1 订阅
19 篇文章 2 订阅

TM1638驱动程序相关索引

1.TM1638显示板(8数码管+8LED+8按键)驱动程序(显示功能)
2.TM1638驱动显示板(8数码管+8LED+8按键)单片机C语言程序(按键功能)
3.TM1638数码管显示板(8数码管+16按键)单片机C语言驱动程序(显示功能)
4.TM1638数码管显示板(8数码管+16按键)单片机C语言驱动程序(按键功能)

一、概述

之前记录过TM637数码管显示模块的驱动C语言程序(详见4位数码管显示模块TM1637芯片C语言驱动程序),本文分享一下天微电子的另一款数码管按键驱动芯片TM1638的单片机C语言驱动程序。本文先记录显示功能驱动程序,按键驱动将在另一篇文章介绍。
模块如下图,8位共阴数码管,8个按键,8个led灯,某宝、某多价格10元以内。
在这里插入图片描述

笔者采用的MCU是STM32F103C8T6,IAR开发环境,使用了HAL库。

二、主要代码

2.1 端口设置函数

/*******************************************************************************
  * 函数名:Port_SetMode
  * 功  能:GPIO设置输入或输出模式
  * 参  数:*GPIOx 引脚组号
			GPIO_Pin引脚号
			u32Mode输入或输出模式
  * 返回值:无
  * 说  明:无
*******************************************************************************/
void Port_SetMode(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint32_t u32Mode)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = GPIO_Pin;
	GPIO_InitStruct.Mode = u32Mode;
	//GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
}

2.2 TM1638驱动函数

2.2.1 头文件TM1638.h

/*******************************************************************************
  * 文件:TM1638.h
  * 作者:https://blog.csdn.net/wanglong3713
  * 版本:v1.0
  * 日期:2021-11-20
  * 说明:TM1638驱动
*******************************************************************************/
#ifndef _TM1638_H_
#define _TM1638_H_

#include "Typedefine.h"
#include "Port.h"
/*******************************************************************************
Macro definitions
*******************************************************************************/
#define TUBE_DISPLAY_NULL					26
#define TUBE_DISPLAY_DECIMAL_PIONT_OFFSET	16
#define TM1638_STBSet()					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET)
#define TM1638_STBReset()				HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET)
#define TM1638_CLKSet()					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET)
#define TM1638_CLKReset()				HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET)
#define TM1638_DIOSet()					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET)
#define TM1638_DIOReset()				HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET)
#define TM1638_DIOModeOutput()			Port_SetMode(GPIOB, GPIO_PIN_9, GPIO_MODE_OUTPUT_PP)
#define TM1638_DIOModeInput()			Port_SetMode(GPIOB, GPIO_PIN_9, GPIO_MODE_INPUT)
#define TM1638_DIORead()				HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9)
/*******************************************************************************
Typedef definitions
*******************************************************************************/
typedef struct
{
	uint8_t tube0;
	uint8_t tube1;
	uint8_t tube2;
	uint8_t tube3;
	uint8_t tube4;
	uint8_t tube5;
	uint8_t tube6;
	uint8_t tube7;
}TM1638Tube_ts;
/*******************************************************************************
Global functions
*******************************************************************************/
void TM1638_Init(void);
void TM1638_TubeDisplay(TM1638Tube_ts data);
void TM1638_LedDisplay(uint8_t data);
uint8_t TM1638_ReadKey(void);
void TM1638_WriteCmd(uint8_t u8Cmd);
void TM1638_SetBrightness(uint8_t u8Brt);
void TM1638_Switch(bool bState);
#endif
/***********************************END OF FILE********************************/

2.2.2 TM638.c文件

/*******************************************************************************
  * 文件:TM1638.c
  * 作者:whttps://blog.csdn.net/wanglong3713
  * 版本:v1.0
  * 日期:2021-11-20
  * 说明:适用于TM1638驱动的8个数码管、8个LED、8个按键的显示板
			○		○		○		○		○		○		○		○
			LED1	LED2	LED3	LED4	LED5	LED6	LED7	LED8
			
			TUBE1	TUBE2	TUBE3	TUBE4	TUBE5	TUBE6	TUBE7	TUBE8
			
			KEY1	KEY2	KEY3	KEY4	KEY5	KEY6	KEY7	KEY8
  显示板按键顺序实际不一致:
			S1		S5		S2		S6		S3		S7		S4		S8	
*******************************************************************************/
#include "TM1638.h"
//共阴数码管数字段码表
const uint8_t TM1638_TubeNumTab[] =
{
	//0,	1,	2,	3,	4,	   5,	6,   7,  8,   9,    A,   b,  C,   d,   E,   F,  	
	0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
	//0., 1.,	2.,	3.,	 4.,  5.,   6.,  7.,  8.,  9. Null
	0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x00
};
//最左至最右数码管,依次为0-7号,对应的显示寄存器地址
const uint8_t TM1638_TubeAddrTab[] =
{
	0xC0,0xC2,0xC4,0xC6,0xC8,0xCA,0xCC,0xCE
};
//8个led的地址,依次为led1-led8
const uint8_t TM1638_LedAddrTab[] =
{
	0xC1,0xC3,0xC5,0xC7,0xC9,0xCB,0xCD,0xCF
};
/*******************************************************************************
  * 函数名:TM1638_WriteData
  * 功  能:TM1638写数据
  * 参  数:u8Data需要写入的数据
  * 返回值:无
  * 说  明:无
*******************************************************************************/
void TM1638_WriteData(uint8_t u8Data)
{
	uint8_t i;
	TM1638_DIOModeOutput();//DIO设置为输出
	for(i = 0; i < 8; i++)
	{
		TM1638_CLKReset();
		(u8Data & 0x01) ? (TM1638_DIOSet()):(TM1638_DIOReset());
		u8Data >>= 1;
		TM1638_CLKSet();
	}
}
/*******************************************************************************
  * 函数名:TM1638_WriteCmd
  * 功  能:TM1638写命令字
  * 参  数:u8Cmd需要写入的命令
  * 返回值:无
  * 说  明:发送命令字时STB置0,发送完置1
*******************************************************************************/
void TM1638_WriteCmd(uint8_t u8Cmd)
{
	TM1638_STBReset();
	TM1638_WriteData(u8Cmd);
	TM1638_STBSet();
}
/*******************************************************************************
  * 函数名:TM1638_ReadData
  * 功  能:TM1638读数据
  * 参  数:无
  * 返回值:读出的数据
  * 说  明:无
*******************************************************************************/
uint8_t TM1638_ReadData(void)
{
	uint8_t i;
	uint8_t temp=0;
	TM1638_DIOModeInput();//DIO设置为输入
	for(i = 0; i < 8; i++)
	{
		temp >>= 1;
		TM1638_CLKReset();
		if(TM1638_DIORead() == 1)
		{
			temp |= 0x80;			
		}
		TM1638_CLKSet();
	}
	return temp;
}
/*******************************************************************************
  * 函数名:TM1638_ReadKey
  * 功  能:TM1638读按键数据
  * 参  数:无
  * 返回值:读出的数据
  * 说  明:实际该显示板只有8个按键,返回值1~8分别为Key1~Key8;
			所有按键连接K3,无法实现组合按键,只允许一次按一个键;
*******************************************************************************/
uint8_t TM1638_ReadKey(void)
{
	uint8_t u8Data[4], i;
	uint8_t u8Key = 0;
	TM1638_STBReset();
	TM1638_WriteData(0x42);
	for (i = 0; i < 4; i++)
	{
		u8Data[i] = TM1638_ReadData();//读BYTE1~BYTE4的数据
	}
	TM1638_STBSet();
	for (i = 0; i < 4; i++)//取出4个BYTE中的键值
	{
		if (((u8Data[i] >> 0) & 0x01) == 0x01)//第0位,B0,对应按键为1、3、5、7,计算公式是i*2+1
		{
			u8Key = (i * 2 + 1);
			break;
		}else
		{
			if (((u8Data[i] >> 4) & 0x01) == 0x01)//第4位,B4,对应按键为2、4、6、8,计算公式是i*2+2
			{
				u8Key = (i * 2 + 2);
				break;
			}
		}
	}
	return u8Key;
}
/*******************************************************************************
  * 函数名:TM1638_LedDisplay
  * 功  能:8个LED显示
  * 参  数:u8Data每一位代表一个数码管,1亮0灭
  * 返回值:无
  * 说  明:u8Data最高位为最左侧数码管LED1
*******************************************************************************/
void TM1638_LedDisplay(uint8_t u8Data)
{
	uint8_t temp[8],i;	
	for(i = 0; i < 8; i++)
	{
		temp[i] = ((u8Data >> (7 - i)) & 0x01);
		TM1638_STBReset();
		TM1638_WriteData(TM1638_LedAddrTab[i]);//显示地址
		TM1638_WriteData(temp[i]);//显示数据	
		TM1638_STBSet();
	}	
}
/*******************************************************************************
  * 函数名:TM1638_TubeDisplay
  * 功  能:8个数码管显示
  * 参  数:sData显示数据结构体
  * 返回值:无
  * 说  明:共阴极数码管,数据为从右至左顺序
*******************************************************************************/
void TM1638_TubeDisplay(TM1638Tube_ts sData)
{
	uint8_t temp[8],i;
	temp[0] = TM1638_TubeNumTab[sData.tube0];
	temp[1] = TM1638_TubeNumTab[sData.tube1];
	temp[2] = TM1638_TubeNumTab[sData.tube2];
	temp[3] = TM1638_TubeNumTab[sData.tube3];
	temp[4] = TM1638_TubeNumTab[sData.tube4];
	temp[5] = TM1638_TubeNumTab[sData.tube5];
	temp[6] = TM1638_TubeNumTab[sData.tube6];
	temp[7] = TM1638_TubeNumTab[sData.tube7];
	
	for(i = 0; i < 8; i++)
	{
		TM1638_STBReset();
		TM1638_WriteData(TM1638_TubeAddrTab[i]);//地址
		TM1638_WriteData(temp[i]);//数据	
		TM1638_STBSet();
	}	
}
/*******************************************************************************
  * 函数名:TM1638_SetBrightness
  * 功  能:设置亮度
  * 参  数:u8Brt亮度,共8级,0~7
  * 返回值:无
  * 说  明:0x88为开显示
*******************************************************************************/
void TM1638_SetBrightness(uint8_t u8Brt)
{
	TM1638_WriteCmd(0x88 | u8Brt);
}
/*******************************************************************************
  * 函数名:TM1638_Switch
  * 功  能:显示开关
  * 参  数:0关,1开
  * 返回值:无
  * 说  明:0x88为开显示
*******************************************************************************/
void  TM1638_Switch(bool bState)
{
	bState ? TM1638_WriteCmd(0x88) : TM1638_WriteCmd(0x80);
}
/***********************************END OF FILE********************************/

2.3 应用层程序

数码管显示的内容,可以由结构体sDisplay_TubeData的8个成员(分别对应8个数码管)赋值实现,LED灯的亮灭由共用体uDisplay_LedData的值决定,共用体共8位,对应8个数码管。
实现以下功能:
数码管显示01234567,LED灯最右侧一位亮:

#include "TM1638.h"
#include "string.h"
static TM1638Tube_ts sDisplay_TubeData;//数码管显示的内容
static Byte_tu uDisplay_LedData;//Led显示的内容
/*******************************************************************************
  * 函数名:Display_Init
  * 功  能:初始化
  * 参  数:无
  * 返回值:无
  * 说  明:无
*******************************************************************************/
void Display_Init(void)
{
	TM1638_Switch(0);//关闭显示
	TM1638_SetBrightness(7);//开显示,设定亮度7级
	TM1638_WriteCmd(0x44);//固定地址模式
	uDisplay_LedData.byte = 0;
	memset(&sDisplay_TubeData, 0x00, sizeof(sDisplay_TubeData));
}
/*******************************************************************************
  * 函数名:Display_TubeDataProcess
  * 功  能:数码管显示内容处理
  * 参  数:无
  * 返回值:无
  * 说  明:无
*******************************************************************************/
void Display_TubeDataProcess(void)
{
	//memset(&sDisplay_TubeData, 0x00, sizeof(sDisplay_TubeData));
	sDisplay_TubeData.tube0 = 0;
	sDisplay_TubeData.tube1 = 1;
	sDisplay_TubeData.tube2 = 2;
	sDisplay_TubeData.tube3 = 3;
	sDisplay_TubeData.tube4 = 4;
	sDisplay_TubeData.tube5 = 5;
	sDisplay_TubeData.tube6 = 6;
	sDisplay_TubeData.tube7 = 7;
	
	TM1638_TubeDisplay(sDisplay_TubeData);
}
/*******************************************************************************
  * 函数名:Display_LedDataProcess
  * 功  能:Led显示内容处理
  * 参  数:无
  * 返回值:无
  * 说  明:无
*******************************************************************************/
void Display_LedDataProcess(void)
{
	uDisplay_LedData.byte = 0x01;//最右侧LED8亮
	TM1638_LedDisplay(uDisplay_LedData.byte);
}

运行以下两个函数即可:

Display_TubeDataProcess();
	Display_LedDataProcess();

显示效果:
在这里插入图片描述

  • 11
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值