TM1637属于一种带键盘扫描接口的LED(发光二极管显示器)驱动控制专用电路。
本文主要使用MCU是STM32 ,CubeMX+Keil5进行开发,使用HAL库
简介:TM1637可以带动16个按键以及做数码管驱动
TM1637.C
#include "TM1637.h"
void gpio_out()
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = TM1637_DIO_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(TM1637_DIO_GPIO_Port, &GPIO_InitStruct);
}
void gpio_in()
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = TM1637_DIO_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(TM1637_DIO_GPIO_Port, &GPIO_InitStruct);
}
///======================================
void TM1637_I2CStart(void) //1637 开始
{
TM1637_CLK(1);
TM1637_DIO(1);
Delay_us(2);
TM1637_DIO(0);
}
void TM1637_I2CStop(void) // 1637 停止
{
TM1637_CLK(0);
Delay_us(2);
TM1637_DIO(0);
Delay_us(2);
TM1637_CLK(1);
Delay_us(2);
TM1637_DIO(1);
}
void TM1637_I2Cask(void) //1637 应答
{
TM1637_CLK(0);
Delay_us(5); //在第八个时钟下降沿之后延时 5us,开始判断 ACK 信号
gpio_in();
while(TM1637_DIO_State);
gpio_out();
TM1637_CLK(1);
Delay_us(2);
TM1637_CLK(0);
}
///=========================================
void TM1637_I2CWrByte(uint8_t oneByte) //写一个字节
{
uint8_t i;
for(i=0;i<8;i++)
{
TM1637_CLK(0);
if(oneByte&0x01) //低位在前
{
TM1637_DIO(1);
}
else
{
TM1637_DIO(0);
}
Delay_us(3);
oneByte=oneByte>>1;
TM1637_CLK(1);
Delay_us(3);
}
}
//-------------------------------------------------
uint8_t ScanKey(void) //读按键
{
uint8_t rekey = 0,i=0;
TM1637_I2CStart();
TM1637_I2CWrByte(0x42); //读按键命令
TM1637_I2Cask();
TM1637_DIO(1); // 在读按键前拉高数据线
gpio_in();
for(i=0;i<8;i++) //从低位开始读
{
TM1637_CLK(0);
rekey=rekey>>1;
Delay_us(30);
TM1637_CLK(1);
if(TM1637_DIO_State)
{
rekey=rekey|0x80;
}
else
{
rekey=rekey|0x00;
}
Delay_us(30);
}
gpio_out();
TM1637_I2Cask();
TM1637_I2CStop();
return (rekey);
}
//================================================
void SmgDisplay(uint8_t add, uint8_t data, uint8_t brightness) //写显示寄存器
{
TM1637_I2CStart();
TM1637_I2CWrByte(0x44); // 40H 地址自动加 1 模式,44H 固定地址模式
TM1637_I2Cask();
TM1637_I2CStop();
TM1637_I2CStart();
TM1637_I2CWrByte(add); //设置首地址,
TM1637_I2Cask();
TM1637_I2CWrByte(data); //送数据
TM1637_I2Cask();
TM1637_I2CStop();
TM1637_I2CStart();
TM1637_I2CWrByte(brightness); //开显示 ,设置亮度
TM1637_I2Cask();
TM1637_I2CStop();
}
//===========end==================================
TM1637.h
#ifndef __TM1637_H__
#define __TM1637_H__
#include "Delay.h"
#include "main.h"
/*定义端口*/
#define TM1637_CLK(x) do{ x ? \
HAL_GPIO_WritePin(TM1637_CLK_GPIO_Port, TM1637_CLK_Pin, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(TM1637_CLK_GPIO_Port, TM1637_CLK_Pin, GPIO_PIN_RESET); \
}while(0)
#define TM1637_DIO(x) do{ x ? \
HAL_GPIO_WritePin(TM1637_DIO_GPIO_Port, TM1637_DIO_Pin, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(TM1637_DIO_GPIO_Port, TM1637_DIO_Pin, GPIO_PIN_RESET); \
}while(0)
#define TM1637_DIO_State HAL_GPIO_ReadPin(TM1637_DIO_GPIO_Port, TM1637_DIO_Pin)
/*外部接口函数*/
void SmgDisplay(uint8_t add, uint8_t data, uint8_t brightness); //写显示寄存器
#endif /* __TM1637_H__ */
注意:TM1637在进行读写时需要应该应答信号反馈,当没有应答时容易则一直while循环,这是一个弊端。