提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
STM32F103ZET6驱动TM1637数码管
前言
工作中会用到数码管,使用stm32f103zet6驱动TM1637数码管
提示:以下是本篇文章正文内容,下面案例可供参考
一、TM1637规格
数码管TM1637驱动芯片规格
二、代码实现
数码管有4个引脚(GND,VCC,DIO,CLK),使用正点原子精英STM32F103ZET6 GPIOB6,GPIOB7分别解接数码管上的CLK,DIO 引脚,使用模拟I2C控制TM1637驱动芯片,也可以根据实际情况使用其他IO
1.头文件定义
代码如下(示例):
#define TM1637_CLK_PIN GPIO_Pin_6
#define TM1637_DIO_PIN GPIO_Pin_7
#define TM1637_CLK(x) x>0? GPIO_SetBits(GPIOB, TM1637_CLK_PIN):GPIO_ResetBits(GPIOB, TM1637_CLK_PIN)
#define TM1637_DIO(x) x>0? GPIO_SetBits(GPIOB, TM1637_DIO_PIN):GPIO_ResetBits(GPIOB, TM1637_DIO_PIN)
#define TM1637_READ_DIO GPIO_ReadInputDataBit(GPIOB, TM1637_DIO_PIN)
//IO方向设置
#define TM1637_DIO_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define TM1637_DIO_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}
2.TM1637.c 代码实现
代码如下(示例):
unsigned char temp=0xCF;//显示跳动的冒号
unsigned char SigNum[24]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0X6F,\
0x77,0x7C,0x39,0x5E,0x79,0x71,\
0x08,0x48,0x49,\
0x76,0x38,0x0E,0x50,0x37};//0123456789ABCDEF一二三HLJRS
void TM1637_Delay_us(unsigned int Nus)
{
for(;Nus>0;Nus--)
{
__nop();
}
}
void TM1637_Start(void)
{
TM1637_DIO_OUT();
TM1637_CLK(1);
TM1637_DIO(1);
TM1637_Delay_us(2);
TM1637_DIO(0);
TM1637_Delay_us(2);
TM1637_CLK(0);
}
void TM1637_Stop(void)
{
TM1637_DIO_OUT();
TM1637_CLK(0);
TM1637_Delay_us(2);
TM1637_DIO(0);
TM1637_Delay_us(2);
TM1637_CLK(1);
TM1637_Delay_us(2);
TM1637_DIO(1);
}
void TM1637_Ack(void)
{
TM1637_CLK(0);
TM1637_DIO_OUT();
TM1637_DIO(0);
TM1637_Delay_us(2);
TM1637_CLK(1);
TM1637_Delay_us(2);
TM1637_CLK(0);
}
void TM1637_WriteByte(unsigned char oneByte)
{
unsigned char i;
TM1637_DIO_OUT();
for(i=0;i<8;i++)
{
TM1637_CLK(0);
if(oneByte&0x01)
{
TM1637_DIO(1);
}
else
{
TM1637_DIO(0);
}
TM1637_Delay_us(3);
oneByte = oneByte>>1;
TM1637_CLK(1);
TM1637_Delay_us(3);
}
}
unsigned char TM1637_ScanKey(void)
{
unsigned char reKey,i;
TM1637_Start();
TM1637_WriteByte(0x42);
TM1637_Ack();
TM1637_DIO(1);
TM1637_DIO_IN();
for(i=0;i<8;i++)
{
TM1637_CLK(0);
reKey = reKey>>1;
TM1637_Delay_us(30);
TM1637_CLK(1);
if(TM1637_READ_DIO)
{
reKey=reKey|0x80;
}
else
{
reKey=reKey|0x00;
}
TM1637_Delay_us(30);
}
TM1637_Ack();
TM1637_Stop();
return(reKey);
}
void TM1637_Set_Bright(uint8_t state,uint8_t bright)
{
TM1637_Start();
TM1637_WriteByte(0x80 + (state ? 0x80:0x00) + bright);
TM1637_Ack();
TM1637_Stop();
}
void TM1637_NixieTubeDisplayChar(unsigned char ch,unsigned char p)
{
if(ch>23)ch=0;//防止数组越界
TM1637_Start();
TM1637_WriteByte(0x44);//0x44固定模式有利于控制显示位,0x40则采用显示地址自加模式这里不使用
TM1637_Ack();
TM1637_Stop();
TM1637_Start();
TM1637_WriteByte(0xC0+p);//0X00地址开始显示
TM1637_Ack();
TM1637_WriteByte(SigNum[ch]);//显示
TM1637_Ack();
}
void TM1637_NixieTubeDisplay(void)
{
TM1637_Start();
TM1637_WriteByte(0x40);//0x40则采用显示地址自加1模式
TM1637_Ack();
TM1637_Stop();
TM1637_Start();
TM1637_WriteByte(0xC0);//0X00地址开始显示
TM1637_Ack();
TM1637_WriteByte(0x06);//显示1
TM1637_Ack();
temp^=0x80;
TM1637_WriteByte(temp);//显示2和跳动的冒号
TM1637_Ack();
TM1637_WriteByte(0x06);//显示1
TM1637_Ack();
TM1637_WriteByte(0x66);//显示4
TM1637_Ack();
TM1637_WriteByte(0xFF);
TM1637_Ack();
TM1637_WriteByte(0xFF);
TM1637_Ack();
TM1637_Stop();
TM1637_Start();
TM1637_WriteByte(0x8f);
TM1637_Ack();
TM1637_Stop();
}
void TM1637_DisplayValue(unsigned int value)
{
uint8_t i = 0;
TM1637_Start();
TM1637_WriteByte(0x40);//0x40则采用显示地址自加1模式
TM1637_Ack();
TM1637_Stop();
TM1637_Start();
TM1637_WriteByte(0xC0);//0X00地址开始显示
TM1637_Ack();
for(i=0; i<6; i++)
{
TM1637_WriteByte(value);
TM1637_Ack();
}
TM1637_Stop();
TM1637_Start();
TM1637_WriteByte(0x8f);
TM1637_Ack();
TM1637_Stop();
}
void TM1637_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = TM1637_CLK_PIN|TM1637_DIO_PIN; //DIO CLK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
3.main函数代码示例:
代码如下(示例):
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "tm1637.h"
unsigned char i=0;
extern unsigned char SigNum[24];
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //初始化与LED连接的硬件接口
TM1637_Init();
while(1)
{
for(i = 0; i < 10; i++)
{
TM1637_DisplayValue(SigNum[i]);
LED0=!LED0;//提示系统正在运行
delay_ms(1000);
}
}
}
4.逻辑分析仪抓I2C数据解析
测试程序TM1637_DisplayValue(SigNum[4]) 显示I2C数据,
逻辑分析仪抓到的数据跟发的数据是反的,因为TM1637是低位先发,0x40 二进制(0100 0000),0xC0 二进制(1100 0000) ,I2C 最低位表示读写控制位,0表示写,1表示读
5.演示效果
TM1637数码管