本人使用的TM1638模块为:Risym TM1638按键数码管LED显示模块。
驱动程序主要由tm1638.h和tm1638.c两个文件组成,现分享自己写的代码,供大家参考。
1)、tm1638.h头文件:
/**
***************************************************************************************
* TM1638模块初始化头文件
* 硬件连接:PA5--STB,PA6--CLK,PA7--DIO
* TubePoint:数码管显示数字是否带小数点
* LightState:LED灯亮灭状态
* TM1638_Init():TM1638初始化函数
* TM1638_WriteData():TM1638写数据函数
* TM1638_WriteAddressData():TM1638指定地址写数据函数
* TM1638_Tube():TM1638指定数码管序号与显示数字函数
* TM1638_TubeOff():TM1638关闭指定数码管函数
* TM1638_Light():TM1638指定LED灯序号num与亮灭state函数
* TM1638_Read():TM1638读数据函数
* TM1638_ReadKey():TM1638读键扫数据函数
* 创建人:hug567
* 最后修改时间:2018-4-5
***************************************************************************************
*/
typedef enum {NoPoint = 0, Point = !NoPoint} TubePoint; //是否带小数点,Point:带,NoPoint:不带
typedef enum {LightOff = 0, LightOn = !LightOff} LightState; //灯开关状态,LightOn:开,LightOff:关
void TM1638_Init(void); //TM1638初始化函数
void TM1638_WriteData(unsigned char data); //TM1638写数据函数
void TM1638_WriteAddressData(unsigned char addr,unsigned char data); //TM1638指定地址写数据函数
void TM1638_Tube(unsigned char serial, unsigned char num, TubePoint point); //TM1638指定数码管序号与显示数字函数
void TM1638_TubeOff(unsigned char serial); //TM1638关闭指定数码管函数
void TM1638_Light(unsigned char num, LightState state); //TM1638指定LED灯序号num与亮灭state函数
unsigned char TM1638_Read(void); //TM1638读数据函数
unsigned char TM1638_ReadKey(void); //TM1638读键扫数据函数
2)、tm1638.c源文件:
/**
***************************************************************************************
* TM1638模块功能实现源文件
* 硬件连接:PA5--STB,PA6--CLK,PA7--DIO
* TubePoint:数码管显示数字是否带小数点
* LightState:LED灯亮灭状态
* TM1638_Init():TM1638初始化函数
* TM1638_WriteData():TM1638写数据函数
* TM1638_WriteAddressData():TM1638指定地址写数据函数
* TM1638_Tube():TM1638指定数码管序号与显示数字函数
* TM1638_TubeOff():TM1638关闭指定数码管函数
* TM1638_Light():TM1638指定LED灯序号num与亮灭state函数
* TM1638_Read():TM1638读数据函数
* TM1638_ReadKey():TM1638读键扫数据函数
* 创建人:hug567
* 最后修改时间:2018-4-5
***************************************************************************************
*/
#include "stm32f10x.h" //stm32f10x系列芯片头文件
#include "tm1638.h" //tm1638模块实现头文件
unsigned char TM1638_LED[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07, //共阴极数码管段码,不带小数点
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; //0~F,1亮0灭
unsigned char TM1638_LED_P[]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87, //共阴极数码管段码,带小数点
0xFF,0xEF,0xF7,0xFC,0xB9,0xDE,0xF9,0xF1}; //0~F,1亮0灭
/***************************************************************************************/
/**
* TM1638写数据函数
* 参数:data:要写入的8位数据
* 返回值:无
*/
void TM1638_WriteData(unsigned char data) //TM1638写数据函数
{
unsigned char i;
for(i=0;i<8;i++)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_6); //CLK=0
if(data&0x01)
{
GPIO_SetBits(GPIOA,GPIO_Pin_7); //DIO=1
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_7); //DIO=0
}
data>>=1;
GPIO_SetBits(GPIOA,GPIO_Pin_6); //CLK=1
}
}
/***************************************************************************************/
/***************************************************************************************/
/**
* TM1638指定地址写数据函数
* 参数1:addr:要写入数据的地址
* 参数2:data:要写入的8位数据
* 返回值:无
*/
void TM1638_WriteAddressData(unsigned char addr,unsigned char data) //TM1638指定地址写数据函数
{
GPIO_ResetBits(GPIOA,GPIO_Pin_5); //STB=0
TM1638_WriteData(addr); //地址
TM1638_WriteData(data); //数据
GPIO_SetBits(GPIOA,GPIO_Pin_5); //STB=1
}
/***************************************************************************************/
/***************************************************************************************/
/**
* TM1638指定数码管序号与显示数字函数
* 参数1:serial:数码管序号,1-8
* 参数2:num:要显示的数字,0-F
* 参数3:point:是否带小数点,Point:带,NoPoint:不带
* 返回值:无
*/
void TM1638_Tube(unsigned char serial, unsigned char num, TubePoint point) //TM1638指定数码管序号与显示数字函数
{
GPIO_ResetBits(GPIOA,GPIO_Pin_5); //STB=0
TM1638_WriteData(0x44); //普通模式,固定地址,写数据到显示寄存器
GPIO_SetBits(GPIOA,GPIO_Pin_5); //STB=1
GPIO_ResetBits(GPIOA,GPIO_Pin_5); //STB=0
TM1638_WriteData(0x88); //显示开,亮度第1级
GPIO_SetBits(GPIOA,GPIO_Pin_5); //STB=1
if(point == Point) //带小数点
{
TM1638_WriteAddressData(0XC0+2*(serial-1),TM1638_LED_P[num]); //第serial个数码管显示num,带小数点
}
else if(point == NoPoint) //不带小数点
{
TM1638_WriteAddressData(0XC0+2*(serial-1),TM1638_LED[num]); //第serial个数码管显示num,不带小数点
}
}
/***************************************************************************************/
/***************************************************************************************/
/**
* TM1638关闭指定数码管函数
* 参数:serial:数码管序号
* 返回值:无
*/
void TM1638_TubeOff(unsigned char serial) //TM1638关闭指定数码管函数
{
GPIO_ResetBits(GPIOA,GPIO_Pin_5); //STB=0
TM1638_WriteData(0x44); //普通模式,固定地址,写数据到显示寄存器
GPIO_SetBits(GPIOA,GPIO_Pin_5); //STB=1
GPIO_ResetBits(GPIOA,GPIO_Pin_5); //STB=0
TM1638_WriteData(0x88); //显示开,亮度第1级
GPIO_SetBits(GPIOA,GPIO_Pin_5); //STB=1
TM1638_WriteAddressData(0XC0+2*(serial-1),0x00); //第serial个数码管灭
}
/***************************************************************************************/
/***************************************************************************************/
/**
* TM1638指定LED灯序号num与亮灭state函数
* 参数1:num:LED灯序号
* 参数2:state:LED灯状态,LightOn:开,LightOff:关
* 返回值:无
*/
void TM1638_Light(unsigned char num, LightState state) //TM1638指定LED灯序号num与亮灭state函数
{
GPIO_ResetBits(GPIOA,GPIO_Pin_5); //STB=0
TM1638_WriteData(0x44); //普通模式,固定地址,写数据到显示寄存器
GPIO_SetBits(GPIOA,GPIO_Pin_5); //STB=1
GPIO_ResetBits(GPIOA,GPIO_Pin_5); //STB=0
TM1638_WriteData(0x88); //显示开,亮度第1级
GPIO_SetBits(GPIOA,GPIO_Pin_5); //STB=1
if(state == LightOn)
{
TM1638_WriteAddressData(0XC0+2*(num-1)+1,0X01); //第num个灯亮
}
else if(state == LightOff)
{
TM1638_WriteAddressData(0XC0+2*(num-1)+1,0X00); //第num个灯灭
}
}
/***************************************************************************************/
/***************************************************************************************/
/**
* TM1638读数据函数
* 参数:无
* 返回值:读取的8位数据
*/
unsigned char TM1638_Read(void) //读数据函数
{
unsigned char i,DIO,temp=0;
GPIO_SetBits(GPIOA,GPIO_Pin_7); //DIO=1,设置为输入
for(i=0;i<8;i++)
{
temp>>=1;
GPIO_ResetBits(GPIOA,GPIO_Pin_6); //CLK=0
DIO = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7); //读取DIO值
if(DIO)
temp|=0x80; //按位或:与0或不变、与1或置1
GPIO_SetBits(GPIOA,GPIO_Pin_6); //CLK=1
}
return temp;
}
/***************************************************************************************/
/***************************************************************************************/
/**
* TM1638读键扫数据函数
* 参数:无
* 返回值:读取的按键号,1~8
*/
unsigned char TM1638_ReadKey(void) //TM1638读键扫数据函数
{
unsigned char c[4],i,key_value=0;
GPIO_ResetBits(GPIOA,GPIO_Pin_5); //STB=0,开始写命令
TM1638_WriteData(0x42); //普通模式,地址自动增加,读键扫数据
for(i=0;i<4;i++)
c[i]=TM1638_Read(); //读取键值
GPIO_SetBits(GPIOA,GPIO_Pin_5); //STB=1,读键值结束
for(i=0;i<4;i++)
{
if(c[i]!=0)
{
key_value = 2*i+(c[i]+14)/15;
key_value = (key_value+7*(1-key_value%2)+1)/2; //获取按键值(1-8)
break;
}
}
return key_value;
}
/***************************************************************************************/
/***************************************************************************************/
/**
* TM1638初始化函数
* 参数:无
* 返回值:无
*/
void TM1638_Init(void) //TM1638初始化函数
{
unsigned char i; //临时变量
GPIO_InitTypeDef GPIO_InitStructure; //GPIO参数设置结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //APB2外设时钟使能:GPIOA
//接TM1638引脚: PA5--STB,PA6--CLK,PA7--DIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; //选定引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //工作方式:推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最大速度50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化引脚
GPIO_ResetBits(GPIOA,GPIO_Pin_5); //STB=0
TM1638_WriteData(0x44); //普通模式,固定地址,写数据到显示寄存器
GPIO_SetBits(GPIOA,GPIO_Pin_5); //STB=1
GPIO_ResetBits(GPIOA,GPIO_Pin_5); //STB=0
TM1638_WriteData(0x88); //显示开,亮度第1级
GPIO_SetBits(GPIOA,GPIO_Pin_5); //STB=1
for(i=0;i<16;i++)
{
TM1638_WriteAddressData(0XC0+i,0X00); //全地址写入0X00
}
}
/***************************************************************************************/