前面发过一篇合宙AIR001的tm1650数码管用类iic的方式控制,那份代码用的是hal库自带的1ms的延迟函数来等待iic的应答,这样子会导致屏幕的刷新率特别的慢,肉眼可见的一个一个数字点亮,实时刷新率并不高,为了提高屏幕刷新率,我去查看了tm1650芯片的手册,芯片手册中写了tm1650这款芯片的最大通信能到4Mhz,hal库的1ms的延迟对它来说真的太慢了,所以我改用了for循环来代替hal库的1ms延迟,在对于时间精确延迟要求不高的场景一般都可以用for循环来延迟,但是缺点也比较明显,延迟时间精确度不高,延迟时一直在做无用的操作有点资源浪费,如果这些缺点可以接受,那就可以使用简单的for循环来做大致时间的延迟函数,通常是us级别。
下面是我的延迟函数
void delay(void)
{
for(uint16_t i=0;i<100;i++)
{}
}
下面是改良过后的tm1650.c的代码
#include "air001xx_hal.h"
#include "TM1650.h"
#include "air001xx_hal_def.h"
uint8_t data_num[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uint8_t data_alphabet[6]={0x77,0x7c,0x39,0x5e,0x79,0x71}; //??a-f???
uint8_t display_address[4]={0x6e,0x6c,0x6a,0x68}; //???????
uint8_t display_brightness[8]={0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x01}; //????,?????0-7?????
void delay(void)
{
for(uint16_t i=0;i<100;i++)
{}
}
void TM1650_Init(void)
{
GPIO_InitTypeDef GPIO_key = {.Pin = GPIO_PIN_1|GPIO_PIN_0,.Mode = GPIO_MODE_OUTPUT_PP,.Speed=GPIO_SPEED_FREQ_HIGH};
__HAL_RCC_GPIOF_CLK_ENABLE();
HAL_GPIO_Init(GPIOF, &GPIO_key);
}
void TM1650_Init_2(void)
{
GPIO_InitTypeDef GPIO_key = {.Pin = GPIO_PIN_2|GPIO_PIN_3,.Mode = GPIO_MODE_OUTPUT_PP,.Speed=GPIO_SPEED_FREQ_HIGH};
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_Init(GPIOA, &GPIO_key);
}
void TM1650_Init_3(void)
{
GPIO_InitTypeDef GPIO_key = {.Pin = GPIO_PIN_7|GPIO_PIN_6,.Mode = GPIO_MODE_OUTPUT_PP,.Speed=GPIO_SPEED_FREQ_HIGH};
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_Init(GPIOA, &GPIO_key);
}
void Iic_Mode(uint32_t Mode)
{
GPIO_InitTypeDef GPIO_key = {.Pin = GPIO_PIN_0,.Mode = Mode,.Speed=GPIO_SPEED_FREQ_HIGH};
__HAL_RCC_GPIOF_CLK_ENABLE();
HAL_GPIO_Init(GPIOF, &GPIO_key);
}
void Iic_Mode_2(uint32_t Mode)
{
GPIO_InitTypeDef GPIO_key = {.Pin = GPIO_PIN_3,.Mode = Mode,.Speed=GPIO_SPEED_FREQ_HIGH};
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_Init(GPIOA, &GPIO_key);
}
void Iic_Mode_3(uint32_t Mode)
{
GPIO_InitTypeDef GPIO_key = {.Pin = GPIO_PIN_6,.Mode = Mode,.Speed=GPIO_SPEED_FREQ_HIGH};
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_Init(GPIOA, &GPIO_key);
}
void TM1650_start(void) //????
{
Iic_Mode(GPIO_MODE_OUTPUT_PP);
TM1650_SCL_1;
TM1650_SDA_1;
delay();
TM1650_SDA_0;
delay();
TM1650_SCL_0;
delay();
}
void TM1650_start_2(void) //????
{
Iic_Mode_2(GPIO_MODE_OUTPUT_PP);
TM1650_SCL2_1;
TM1650_SDA2_1;
delay();
TM1650_SDA2_0;
delay();
TM1650_SCL2_0;
delay();
}
void TM1650_start_3(void) //????
{
Iic_Mode_3(GPIO_MODE_OUTPUT_PP);
TM1650_SCL3_1;
TM1650_SDA3_1;
delay();
TM1650_SDA3_0;
delay();
TM1650_SCL3_0;
delay();
}
void TM1650_stop(void) //????
{
Iic_Mode(GPIO_MODE_OUTPUT_PP);
TM1650_SCL_1;
TM1650_SDA_0;
delay();
TM1650_SDA_1;
delay();
}
void TM1650_stop_2(void) //????
{
Iic_Mode_2(GPIO_MODE_OUTPUT_PP);
TM1650_SCL2_1;
TM1650_SDA2_0;
delay();
TM1650_SDA2_1;
delay();
}
void TM1650_stop_3(void) //????
{
Iic_Mode_3(GPIO_MODE_OUTPUT_PP);
TM1650_SCL3_1;
TM1650_SDA3_0;
delay();
TM1650_SDA3_1;
delay();
}
void TM1650_send(uint8_t data) //????
{
Iic_Mode(GPIO_MODE_OUTPUT_PP);
int i;
TM1650_SCL_0;
TM1650_SDA_0;
delay();
for(i=7;i>=0;i--)
{
if(data&(1<<i)) //?????SDA?????????,???????
TM1650_SDA_1;
else
TM1650_SDA_0;
delay();
TM1650_SCL_1;
delay();
TM1650_SCL_0;
delay();
}
}
void TM1650_send_2(uint8_t data) //????
{
Iic_Mode_2(GPIO_MODE_OUTPUT_PP);
int i;
TM1650_SCL2_0;
TM1650_SDA2_0;
delay();
for(i=7;i>=0;i--)
{
if(data&(1<<i)) //?????SDA?????????,???????
TM1650_SDA2_1;
else
TM1650_SDA2_0;
delay();
TM1650_SCL2_1;
delay();
TM1650_SCL2_0;
delay();
}
}void TM1650_send_3(uint8_t data) //????
{
Iic_Mode_3(GPIO_MODE_OUTPUT_PP);
int i;
TM1650_SCL3_0;
TM1650_SDA3_0;
delay();
for(i=7;i>=0;i--)
{
if(data&(1<<i)) //?????SDA?????????,???????
TM1650_SDA3_1;
else
TM1650_SDA3_0;
delay();
TM1650_SCL3_1;
delay();
TM1650_SCL3_0;
delay();
}
}
int TM1650_ack(void)
{
Iic_Mode(GPIO_MODE_INPUT);
int ack = 0;
TM1650_SCL_0;
delay();
TM1650_SCL_1;
if(HAL_GPIO_ReadPin(GPIOF,GPIO_PIN_0)) //????(SDA)?????????
ack = 1; //???
TM1650_SCL_0;
delay();
return ack;
}
int TM1650_ack_2(void)
{
Iic_Mode_2(GPIO_MODE_INPUT);
int ack = 0;
TM1650_SCL2_0;
delay();
TM1650_SCL2_1;
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3)) //????(SDA)?????????
ack = 1; //???
TM1650_SCL2_0;
delay();
return ack;
}
int TM1650_ack_3(void)
{
Iic_Mode_3(GPIO_MODE_INPUT);
int ack = 0;
TM1650_SCL3_0;
delay();
TM1650_SCL3_1;
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6)) //????(SDA)?????????
ack = 1; //???
TM1650_SCL3_0;
delay();
return ack;
}
void Write_DATA(unsigned char add,unsigned char DATA) //????????
{
TM1650_start();//????
TM1650_send(add);//????
TM1650_ack(); //????
TM1650_send(DATA);//????
TM1650_ack(); //????
TM1650_stop(); //????
}
void Write_DATA_2(unsigned char add,unsigned char DATA) //????????
{
TM1650_start_2();//????
TM1650_send_2(add);//????
TM1650_ack_2(); //????
TM1650_send_2(DATA);//????
TM1650_ack_2(); //????
TM1650_stop_2(); //????
}
void Write_DATA_3(unsigned char add,unsigned char DATA) //????????
{
TM1650_start_3();//????
TM1650_send_3(add);//????
TM1650_ack_3(); //????
TM1650_send_3(DATA);//????
TM1650_ack_3(); //????
TM1650_stop_3(); //????
}
void Display_Init(void) //????????
{
delay();
Write_DATA(TIM_COMMAND,display_brightness[7]); //??????
Write_DATA(DIS_ADD_1,data_null); //???
Write_DATA(DIS_ADD_2,data_null);
Write_DATA(DIS_ADD_3,data_null);
Write_DATA(DIS_ADD_4,data_null);
}
void Display_Init_2(void) //????????
{
delay();
Write_DATA_2(TIM_COMMAND,display_brightness[7]); //??????
Write_DATA_2(DIS_ADD_1,data_null); //???
Write_DATA_2(DIS_ADD_2,data_null);
Write_DATA_2(DIS_ADD_3,data_null);
Write_DATA_2(DIS_ADD_4,data_null);
}
void Display_Init_3(void) //????????
{
delay();
Write_DATA_3(TIM_COMMAND,display_brightness[7]); //??????
Write_DATA_3(DIS_ADD_1,data_null); //???
Write_DATA_3(DIS_ADD_2,data_null);
Write_DATA_3(DIS_ADD_3,data_null);
Write_DATA_3(DIS_ADD_4,data_null);
}
void Show_Num(int num,uint8_t dp)
{
uint8_t buff = 0;
int i;
if(num <= 9999) //???????
{
for(i = 0;i <4; i++)
{
buff = num % 10;
if((dp&0x01) == 1) //???1????????
{
Write_DATA(display_address[i],data_num[buff]|data_dp);
}
else
{
Write_DATA(display_address[i],data_num[buff]);
}
num /= 10;
dp = dp >> 1;
}
}
}
void Show_Num_2(int num,uint8_t dp)
{
uint8_t buff = 0;
int i;
if(num <= 9999) //???????
{
for(i = 0;i <4; i++)
{
buff = num % 10;
if((dp&0x01) == 1) //???1????????
{
Write_DATA_2(display_address[i],data_num[buff]|data_dp);
}
else
{
Write_DATA_2(display_address[i],data_num[buff]);
}
num /= 10;
dp = dp >> 1;
}
}
}
void Show_Num_3(int num,uint8_t dp)
{
uint8_t buff = 0;
int i;
if(num <= 9999) //???????
{
for(i = 0;i <4; i++)
{
buff = num % 10;
if((dp&0x01) == 1) //???1????????
{
Write_DATA_3(display_address[i],data_num[buff]|data_dp);
}
else
{
Write_DATA_3(display_address[i],data_num[buff]);
}
num /= 10;
dp = dp >> 1;
}
}
}
void Display_Change_Brightness(uint8_t num) //????,????0-7,0??????,7??????
{
if(num < 8)
{
//TIM_COMMAND(.h????) 0x48 //????
//display_brightness ??
Write_DATA(TIM_COMMAND,display_brightness[num]); //???????
}
}
void Display_Change_Brightness_2(uint8_t num) //????,????0-7,0??????,7??????
{
if(num < 8)
{
//TIM_COMMAND(.h????) 0x48 //????
//display_brightness ??
Write_DATA_2(TIM_COMMAND,display_brightness[num]); //???????
}
}
void Display_Change_Brightness_3(uint8_t num) //????,????0-7,0??????,7??????
{
if(num < 8)
{
//TIM_COMMAND(.h????) 0x48 //????
//display_brightness ??
Write_DATA_3(TIM_COMMAND,display_brightness[num]); //???????
}
}
下面是改良过后的tm1650.h的代码
#ifndef _TM1650_H
#define _TM1650_H
#include "air001xx_hal_def.h"
#define TM1650_SCL_1 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1,1)
#define TM1650_SCL_0 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1,0)
#define TM1650_SDA_1 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0,1)
#define TM1650_SDA_0 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0,0)
#define TM1650_SCL2_1 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2,1)
#define TM1650_SCL2_0 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2,0)
#define TM1650_SDA2_1 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,1)
#define TM1650_SDA2_0 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,0)
#define TM1650_SCL3_1 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7,1)
#define TM1650_SCL3_0 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7,0)
#define TM1650_SDA3_1 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6,1)
#define TM1650_SDA3_0 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6,0)
#define data_dp 0x80
#define DIS_ADD_1 0x68 //?????????
#define DIS_ADD_2 0x6a //?????????
#define DIS_ADD_3 0x6c //?????????
#define DIS_ADD_4 0x6e //?????????
#define TIM_COMMAND 0x48 //????
#define data_null 0x00 //???
void delay(void);
void TM1650_Init(void);//TM1650????GPIO???
void TM1650_Init_2(void);
void TM1650_Init_3(void);
void Iic_Mode(uint32_t Mode);
void Iic_Mode_2(uint32_t Mode);
void Iic_Mode_3(uint32_t Mode);
void TM1650_start(void);
void TM1650_start_2(void);
void TM1650_start_3(void);
void TM1650_stop(void);
void TM1650_stop_2(void);
void TM1650_stop_3(void);
int TM1650_ack(void);
int TM1650_ack_2(void);
int TM1650_ack_3(void);
void TM1650_send(uint8_t data);
void TM1650_send_2(uint8_t data);
void TM1650_send_3(uint8_t data);
void Write_DATA(unsigned char add,unsigned char DATA);
void Write_DATA_2(unsigned char add,unsigned char DATA);
void Write_DATA_3(unsigned char add,unsigned char DATA);
void Display_Init(void);
void Display_Init_2(void);
void Display_Init_3(void);
void Show_Num(int num,uint8_t dp);
void Show_Num_2(int num,uint8_t dp);
void Show_Num_3(int num,uint8_t dp);
void Display_Change_Brightness(uint8_t num);
void Display_Change_Brightness_2(uint8_t num);
void Display_Change_Brightness_3(uint8_t num);
#endif
改良后屏幕初始化和屏幕刷新都是特别的快,我用的3路模拟iic控制3个不同的tm1650数码管,改良后肉眼来看是3个数码管同时刷新,实时性大大的提高了。
新手小白,若有错误之处,大家可以批评指正。希望对大家有所帮助!
我最近发了一篇文章里面包含了常用的功能函数以及常用的模块底层驱动函数封装库,大家感兴趣的可以收藏一下,需要的时候就不用到处找代码,一篇就够用,我会持续更新。