TM1638测试程序STM8S
2020-01-13 来源:eefocus
//适用于STM8S003F3
//main.c 文件
//实验现象:刚开始上电时,所有数码管亮且显示0;按下按键其对应的数码管数字加一,对应的LED灯亮
#include'stm8s.h'
#include'tm1638.h'
unsigned char num[8]; //各个数码管显示的值
int main(void)
{
u8 i;
init_TM1638(); //初始化TM1638
for(i=0;i<8;i++)
Write_DATA(i<<1,tab[0]); //初始化寄存器(所有数码管上电时均显示0)
while(1)
{
i=Read_key(); //读按键值
if(i<8)
{
num[i]++;
while(Read_key()==i); //等待按键释放
if(num[i]>15)
num[i]=0; //显示值从0到F
Write_DATA(i*2,tab[num[i]]);
Write_allLED(1< }
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(u8* file,u32 line)
{
while(1)
{
}
}
#endif
//tm1638.h文件
//PD4引脚连DIO //数据输出输入
//PD5引脚连CLK //时钟
//PD6引脚连STB
#ifndef _TM1638_H
#define _TM1638_H
#include'stm8s.h'
#define DATA_COMMAND 0X40
#define DISP_COMMAND 0x80
#define ADDR_COMMAND 0XC0
//共阴数码管显示代码
unsigned char tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; //1~f
void TM1638_Write(unsigned char DATA) //写数据函数
{
u8 i;
for(i=0;i<8;i++)
{
GPIO_WriteLow(GPIOD,GPIO_PIN_5);//CLK=0
if(DATA&0X01)
GPIO_WriteHigh(GPIOD,GPIO_PIN_4); //DIO=1
else
GPIO_WriteLow(GPIOD,GPIO_PIN_4); //DIO=0
DATA>>=1;
GPIO_WriteHigh(GPIOD,GPIO_PIN_5);//CLK=1
}
}
unsigned char TM1638_Read(void) //读数据函数
{
u8 i;
u8 temp=0;//存放读取的值
GPIO_WriteHigh(GPIOD,GPIO_PIN_4); //设置为输入(DIO=1)
for(i=0;i<8;i++)
{
temp>>=1;
GPIO_WriteLow(GPIOD,GPIO_PIN_5);//CLK=0
if(GPIO_ReadInputPin(GPIOD,GPIO_PIN_4))//DIO==1?
temp|=0x80;
GPIO_WriteHigh(GPIOD,GPIO_PIN_5);//CLK=1
}
return temp;
}
void Write_COM(unsigned char cmd) //发送命令字
{
/*
在上升或下降沿初始化串行接口,随后等待接收 指令。STB 为低后的第一个字节作为指令,当处
理指令时,当前其它处理被终止。当STB 为高时, CLK 被忽略。
*/
GPIO_WriteLow(GPIOD,GPIO_PIN_6);//STB=0
TM1638_Write(cmd);
GPIO_WriteHigh(GPIOD,GPIO_PIN_6);//STB=1
}
unsigned char Read_key(void)
{
u8 c[4],i,key_value=0;
GPIO_WriteLow(GPIOD,GPIO_PIN_6);//STB=0
TM1638_Write(0x42); //读键扫数据 命令
for(i=0;i<4;i++)
c[i]=TM1638_Read(); //需要连续读4个字节,不能跳读
GPIO_WriteHigh(GPIOD,GPIO_PIN_6); //4个字节数据合成一个字节
for(i=0;i<4;i++)
key_value|=c[i]< for(i=0;i<8;i++)
if((0x01< break;
return i;//返回读取到的键序号
}
void Write_DATA(unsigned char add,unsignedchar DATA) //指定地址写入数据
{
Write_COM(0x44);
GPIO_WriteLow(GPIOD,GPIO_PIN_6);//STB=0
TM1638_Write(0xc0|add);//STB为低的第一个字节作为指令
TM1638_Write(DATA);//第二个字节及之后作为数据
GPIO_WriteHigh(GPIOD,GPIO_PIN_6);//STB=1
}
/*
void Write_oneLED(unsigned char num,unsigned char flag) //单独控制一个LED函数,num为需要控制的led序号,flag为0时熄灭,不为0时点亮
{
if(flag)
Write_DATA(2*num+1,1);
else
Write_DATA(2*num+1,0);
} */
void Write_allLED(unsigned char LED_flag) //控制全部LED函数,LED_flag表示各个LED状态
{
u8 i;
for(i=0;i<8;i++)
{
if(LED_flag&(1< //Write_DATA(2*i+1,3);
Write_DATA(2*i+1,1);
else
Write_DATA(2*i+1,0);
}
}
//TM1638初始化函数
void init_TM1638(void)
{
u8 i;
GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_SLOW);//初始化相关的GPIO口
GPIO_Init(GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_SLOW);
GPIO_Init(GPIOD, GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_SLOW);
Write_COM(0x8b); //亮度 (0x88-0x8f)8级亮度可调
Write_COM(0x40); //采用地址自动加1
GPIO_WriteLow(GPIOD,GPIO_PIN_6); //STB=0
TM1638_Write(0xc0); //设置起始地址
for(i=0;i<16;i++) //传送16个字节的数据
TM1638_Write(0x00);
GPIO_WriteHigh(GPIOD,GPIO_PIN_6); //STB=1
}
#endif