TM1638按键数码管显示模块
实物图
原理图
tm1638.c文件
#include "tm1638.h"
#include "delay.h"
//
//
//共阴数码管显示代码
unsigned char tab[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
// **************************************** TM1638 ************************
//发送一个字节
void TM1638_Write(u8 DATA) //写字节
{
unsigned char i;
SDA_OUT();
delay_us(2);
for(i=0;i<8;i++)
{
TM1638_CLK=0;
delay_us(2);
if(DATA&0X01)
OUT_SDA=1;
else
OUT_SDA=0;
delay_us(2);
DATA>>=1;
TM1638_CLK=1;
delay_us(2);
}
}
u8 TM1638_Read(void) //读字节
{
unsigned char i;
unsigned char temp=0;
SDA_IN();//SDA设置为输入
delay_us(2);
for(i=0;i<8;i++)
{
temp>>=1;
TM1638_CLK=0;
delay_us(2);
if(READ_SDA)
temp|=0x80;
TM1638_CLK=1;
delay_us(2);
}
return temp;
}
void Write_COM(unsigned char cmd) //发送命令字
{
TM1638_STB=0;
TM1638_Write(cmd);
TM1638_STB=1;
}
void Write_DATA(unsigned char add,unsigned char DATA) //指定地址写入数据
{
TM1638_STB=0;
TM1638_Write(0xc0|add); //1100 0000
TM1638_Write(DATA);
TM1638_STB=1;
}
u8 Read_key(void) //读按键
{
unsigned char c[4],i,key_value=0;
TM1638_STB=0;
delay_us(2);
TM1638_Write(0x42); //读键扫数据 命令
for(i=0;i<4;i++)
c[i]=TM1638_Read();
TM1638_STB=1; //4个字节数据合成一个字节
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; //返回键值 无键值按下返回0x08
// 8键 col:K3 row:KS1~KS8
// if(c[0]==0x01) key_value=1;
// if(c[0]==0x10) key_value=5;
// if(c[1]==0x01) key_value=2;
// if(c[1]==0x10) key_value=6;
// if(c[2]==0x01) key_value=3;
// if(c[2]==0x10) key_value=7;
// if(c[3]==0x01) key_value=4;
// if(c[3]==0x10) key_value=8;
// return (key_value); // 返回键值
}
//单独控制一个LED函数
//num为需要控制的led序号,flag为0时熄灭,不为0时点亮
void Write_oneLED(unsigned char num,unsigned char flag) //控制一个LED
{
if(flag)
Write_DATA(2*num+1,1);
else
Write_DATA(2*num+1,0);
}
//控制全部LED函数
//LED_flag表示各个LED状态
void Write_allLED(unsigned char LED_flag) //控制全部LED
{
unsigned char i;
for(i=0;i<8;i++)
{
if(LED_flag&(1<<i))
//Write_DATA(2*i+1,3);
Write_DATA(2*i+1,1);
else
Write_DATA(2*i+1,0);
}
}
void TM1638_Clear(void) //清除显示
{
u8 i;
Write_COM(0x8f); //亮度 (0x88-0x8f)8级亮度可调
Write_COM(0x40); //自动地址
TM1638_STB=0;
TM1638_Write(0xc0); //设置起始地址
for(i=0;i<16;i++) //传送16个字节的数据
TM1638_Write(0x00);
TM1638_STB=1;
}
void NixieShow(void) //数码管显示01234567
{
u8 i;
Write_COM(0x8d); //亮度 (0x88-0x8f)8级亮度可调
Write_COM(0x44); //地址固定
for(i=0;i<8;i++)
Write_DATA(i<<1,tab[i]); //依次显示01234567
}
//num数码管序号 data显示的数字
void NixieShowOne(u8 num,u8 data) //单个数码管显示
{
Write_COM(0x8d); //亮度 (0x88-0x8f)8级亮度可调
Write_COM(0x44); //地址固定
Write_DATA(num<<1,tab[data]); //依次显示01234567
}
void NixieShowNum(u32 data) //数码管显示数字
{
NixieShowOne(0,data/10000000%10); //单个数码管显示
NixieShowOne(1,data/1000000%10); //单个数码管显示
NixieShowOne(2,data/100000%10); //单个数码管显示
NixieShowOne(3,data/10000%10); //单个数码管显示
NixieShowOne(4,data/1000%10); //单个数码管显示
NixieShowOne(5,data/100%10); //单个数码管显示
NixieShowOne(6,data/10%10); //单个数码管显示
NixieShowOne(7,data%10); //单个数码管显示
}
//初始化LED
void LED_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//使能GPIOC时钟
//GPIOB8,B9初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化
}
//初始化
void TM1638_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE时钟
//GPIOB8,B9初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化
TM1638_CLK=1;
OUT_SDA=1;
}
tm1638.h文件
#ifndef __TM1638_H
#define __TM1638_H
#include "sys.h"
//
//共阴数码管显示代码
extern unsigned char tab[16];
//DIO输入输出设置
#define SDA_IN() {GPIOE->MODER&=~(3<<(9*2));GPIOE->MODER|=0<<9*2;} //PE9输入模式
#define SDA_OUT() {GPIOE->MODER&=~(3<<(9*2));GPIOE->MODER|=1<<9*2;} //PE9输出模式
//IO操作函数
#define TM1638_CLK PEout(8) //CLK
#define OUT_SDA PEout(9) //DIO
#define READ_SDA PEin(9) //输入DIO
#define TM1638_STB PEout(10)//片选信号STB
#define LED PCout(4) //LED
//TM1638
void TM1638_Write(unsigned char DATA); //写数据函数
unsigned char TM1638_Read(void); //读数据函数
void Write_COM(unsigned char cmd);//发送命令字
unsigned char Read_key(void);
void Write_DATA(unsigned char add,unsigned char DATA); //指定地址写入数据
void Write_oneLED(unsigned char num,unsigned char flag); //单独控制一个LED函数,num为需要控制的led序号,flag为0时熄灭,不为0时点亮
void Write_allLED(unsigned char LED_flag); //控制全部LED函数,LED_flag表示各个LED状态
void TM1638_Clear(void); //清除显示
void NixieShow(void); //数码管显示
void NixieShowOne(u8 num,u8 data); //单个数码管显示
void NixieShowNum(u32 data); //数码管显示数字
void TM1638_init(void);
void LED_init(void);
#endif
第一种:显示数字
main.c主函数
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "tm1638.h"
unsigned char num[8]; //各个数码管显示的值
int main(void)
{
unsigned char i;
delay_init(168);
LED_init();
LED=1;
TM1638_init(); //初始化TM1638
NixieShow(); //数码管显示01234567 初始化必须加上
TM1638_Clear(); //清除显示
while(1)
{
NixieShow(); //数码管显示01234567
delay_ms(10);
}
}
实际显示
逻辑分析仪查看时序
0X44固定地址模式
跟着8个按键(地址+数据)
0X8F显示亮度
第二种:扫描键盘
按下按键,对应位置数码管显示数字并计数,对应位置LED点亮
main.c主函数
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "tm1638.h"
unsigned char num[8]; //各个数码管显示的值
int main(void)
{
unsigned char i;
delay_init(168);
LED_init();
LED=1;
TM1638_init(); //初始化TM1638
NixieShow(); //数码管显示01234567 初始化必须加上
TM1638_Clear(); //清除显示
while(1)
{
i=Read_key(); //读按键值
if(i<8)
{
num[i]++;
while(Read_key()==i); //等待按键释放
if(num[i]>15)
num[i]=0;
Write_DATA(i*2,tab[num[i]]); //数码管显示+1
Write_allLED(1<<i); //按键对应LED灯点亮
}
// NixieShow(); //数码管显示01234567
delay_ms(10);
}
}
无按键按下时的时序
0X42扫描键盘指令
后面四个字节表示返回键值
单片机源码已上传到我的资源
https://download.csdn.net/download/sgjiajia/13122172点击进入