自己学着写的,手上没硬件,没法测试,请各位自行测试,不懂的问
芯片时钟手册
地址自动加1模式的数据发送格式
地址模式选择的寄存器值
字符存储寄存器地址
亮度寄存器的值
TM1640.c
/*
* TM1640.c
*
* Created on: Sep 28, 2022
* Author: 79482
*/
#include "stm32l4xx_hal.h"
#include "TM1640.h"
void DelayUs(uint8_t Us)
{
uint8_t n = SystemCoreClock/1000000/8*Us;
do
{
__NOP();
}
while(n--);
}
void TM1640_GPIO_INIT(void)
{
GPIO_InitTypeDef gpioinit;
gpioinit.Pin = GPIO_PIN_0|GPIO_PIN_1;//GPIO_PIN_0 是连接 DIN 引脚、GPIO_PIN_1 是连接 SCLK 引脚
gpioinit.Mode = GPIO_MODE_OUTPUT_OD; //选择开漏输出模式
// gpioinit.Pull = GPIO_PULLUP;
gpioinit.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_Init(GPIOA,&gpioinit);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0|GPIO_PIN_1,GPIO_PIN_SET);
}
/*
* 数据发送函数
* 由 GPIOA 的 GPIO_PIN_1 模拟发送时钟,由 GPIOA 的 GPIO_PIN_0 发送数据
* *pData:要发送的8位16进制数的指针或数组
* Len: 要发送的8位16进制数的数组长度
*/
void TM1640_SendFrame(uint8_t *pData,uint8_t Len)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
DelayUs(1);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
DelayUs(1);
for(uint8_t Byte = 0;Byte < Len;Byte++)
{
for(uint8_t Bit = 0;Bit < 8;Bit++)
{
if((pData[Byte]&(0x01<<Bit))!=0)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
}
DelayUs(1);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
DelayUs(1);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
DelayUs(1);
}
}
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
DelayUs(1);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);
}
/*
* 地址模式选择函数
* Addr:指要发送的命令数据
* TM1640_ADDR_MODE_AUTO_INC 地址自动加1模式
* TM1640_ADDR_MODE_FIXED 固定地址模式
*/
void TM1640_SendCommand1(uint8_t Addr)
{
uint8_t SendAdd[1];
SendAdd[0] = Addr;
TM1640_SendFrame(SendAdd,sizeof(Addr));
}
/*
* 数据首地址以及字符数据发送函数
* Addr: 数码管显示字符的首地址
* *pData:数字的8位16进制数据指针或数组
* Len: 数字数组的长度
*/
void TM1640_SendCommand2(uint8_t Addr,uint8_t *pData,uint8_t Len)
{
uint8_t Buffer[17];
Buffer[0] = Addr|0xc0;
for(uint8_t Byte = 0;Byte < Len;Byte++)
{
Buffer[Byte+1] = pData[Byte];
}
TM1640_SendFrame(Buffer,Len+1);
}
/*
* 数码管亮度调节函数
* BrightNess:亮度值
* 填写0~7,数字越大越亮
* TM1640_PULSE_WIDTH_OFF关闭数码管
*/
void TM1640_SendCommand3(uint8_t BrightNess)
{
uint8_t Buffer[1];
if(BrightNess == TM1640_PULSE_WIDTH_OFF)
{
Buffer[0] = BrightNess;
TM1640_SendFrame(Buffer,1);
}
else
{
Buffer[0] = BrightNess|0x88;
TM1640_SendFrame(Buffer,1);
}
}
/*
* 数字显示函数
* Number:要显示的10进制数范围(0~65535)
* 例如显示65:TM1640_ShowNumber(65);
*/
void TM1640_ShowNumber(uint8_t Number)
{
uint8_t NUM;
uint8_t pData[5];
uint8_t Buffer[10] =
{
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};
for(uint8_t i=0;i<5;i++)
{
NUM = Number%10;
Number /= 10;
pData[5-i] = Buffer[NUM];
}
TM1640_SendCommand1(TM1640_ADDR_MODE_AUTO_INC);
TM1640_SendCommand2(0x00,pData,5);
TM1640_SendCommand3(4);
}
TM1640.h
/*
* TM1640.h
*
* Created on: Sep 28, 2022
* Author: 79482
*/
#ifndef INC_TM1640_H_
#define INC_TM1640_H_
#define TM1640_ADDR_MODE_AUTO_INC 0X40 //TM1640地址自动加1模式
#define TM1640_ADDR_MODE_FIXED 0x44 //TM1640固定地址模式
#define TM1640_PULSE_WIDTH_OFF 0x80 //TM1640亮度关
void TM1640_GPIO_INIT(void); //DIN引脚初始化;CLK引脚初始化
void DelayUs(uint8_t Us); //1us延时函数
void TM1640_SendFrame(uint8_t *pData,uint8_t Len); //数据发送函数
void TM1640_SendCommand1(uint8_t Addr); //第一部分数据发送函数(地址模式选择)
void TM1640_SendCommand2(uint8_t Addr,uint8_t *pData,uint8_t Len);//第二部分数据发送函数(显示数字的数据)
void TM1640_SendCommand3(uint8_t BrightNess); //第三部分数据发送函数(亮度控制)
void TM1640_ShowNumber(uint8_t Number); //显示函数,显示范围0~65535
#endif /* INC_TM1640_H_ */