STM32F103ZET6驱动TM1637数码管

本文详细介绍了如何使用STM32F103ZET6单片机通过GPIO控制TM1637数码管,包括I2C通信的头文件定义、TM1637驱动函数和主函数示例。还涉及了逻辑分析仪抓取I2C数据的解析以及演示效果。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

工作中会用到数码管,使用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数码管

三、源代码地址

gitee链接地址

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值