目录
一、TM1650简介
1、特性描述
2、功能特点
二、IIC(Inter-Integrated Circuit BUS)结构解析
1、IIC协议介绍
2、多主机IIC总线结构
3、信号概念
三、TM1650数码管的工作
四、编写代码
一、TM1650简介
1、特性描述
TM1650 是一种带键盘扫描接口的 LED(发光二极管显示器)驱动控制专用电路。内部集成有 MCU 输入输出控制数字接口、数据锁存器、LED 驱动、键盘扫描、辉度调节等电路。TM1650 性能稳定、质 量可靠、抗干扰能力强,可适用于 24 小时长期连续工作的应用场合。
2、功能特点
a:支持2.8V-5.5V电源电压
b:键盘扫描:7×4bit内部集成三极管驱动
c:提供8级亮度控制
d:两种显示模式:8段×4位和7段×4位
e:类IIC通信机制,使用相同时序,没有从机地址
二、IIC(Inter-Integrated Circuit BUS)结构解析
1、IIC协议介绍
I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。
软件IIC:软件IIC通信指的是用单片机的两个I/O端口模拟出来的IIC,用软件控制管脚状态以模拟I2C通信波形,软件模拟寄存器的工作方式。
硬件IIC:一块硬件电路,硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,硬件(固件)I2C是直接调用内部寄存器进行配置。
2、多主机IIC总线结构
每个主机都有7bit地址,最后一位是读写位(1或0),而TM1650数码管使用的是类IIC通信,所以不带从机地址。
3、信号概念
a:起始信号
b:应答信号(低位有效)
c:停止信号
SDA时序图
上图主机向从机发送一个起始条件,然后主机进行一个写访问,ACK作为从机向主机发送一个应答信号,低位有效,WORD ADDRESS表示主机告诉从机我待会要访问哪块存储地址,从机再给出应答,然后向从机发送数据,每发送一个字节,从机给出应答。最后在发送一个停止信号。
开始信号和停止信号
ACK应答信号(ACK处在第九时钟周期,也可以看作为第九位)
数据有效性(SCL为高电平时,SDA只能有一种状态,要么高电平,要么低电平)
三、TM1650数码管的工作
可以看到,上面的时序图和iic来讲是一样的,包含一个开始信号,停止信号和ACK应答机制。
起始信号>>地址码(1字节)>>ACK应答信号>>数码管段数据(1字节)>>ACK应答信号>>结束信号
上面是设置亮度的发送的数据格式:前四位(B7-B4)是设置亮度的级别的。B3(设置数码管的段位),B0设置显示的开关。
68HL===68 H:16进制 L:低位 68HU===68 H:16进制 U:高位
通过数据手册得知
0x68 //第一个数码管的地址
0x6a //第二个数码管的地址
0x6c //第三个数码管的地址
0x6e //第四个数码管的地址
T0x48 //设置亮度地址
四、编写代码
编程环境:keil5 STM32f103c8t6
numTM1650.c
/*
此模块是数码管模块
共阴数码管
TM1650是一个用IIC协议驱动的模块
此模块SDA接PB13,SCL接PB12,由于PB12,PB13口没有IIC外设复用,因此需要通过GPIO口模拟出IIC的通 信协议驱动
*/
#include "delay.h"
#include "numTM1650.c"
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 TM1650_Init(void)//TM1650模块端口GPIO初始化
{
GPIO_InitTypeDef GPIO_InitStruct;//定义一个GPIO结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//打开GPIO B组时钟
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13; //引脚12,引脚13
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //速度
GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void Iic_Mode(GPIOMode_TypeDef Mode)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13; //引脚13
GPIO_InitStruct.GPIO_Mode = Mode; //输出模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //50MHZ
GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void TM1650_start(void) //开始信号
{
Iic_Mode(GPIO_Mode_OUT);
TM1650_SCL_1;
TM1650_SDA_1;
delay_us(5);
TM1650_SDA_0;
delay_us(5);
TM1650_SCL_0;
delay_us(5);
}
void TM1650_stop(void) //停止信号
{
Iic_Mode(GPIO_Mode_OUT);
TM1650_SCL_1;
TM1650_SDA_0;
delay_us(5);
TM1650_SDA_1;
delay_us(5);
}
void TM1650_send(uint8_t data) //传输数据
{
Iic_Mode(GPIO_Mode_OUT);
uint8_t i;
TM1650_SCL_0;
TM1650_SDA_0;
delay_us(5);
for(i=7; i>=0; i--)
{
if(data&(1<<i)) //根据图判断SDA为高电平还是低电平,高位到低位操作
TM1650_SDA_1;
else
TM1650_SDA_0;
delay_us(5);
TM1650_SCL_1;
delay_us(5);
TM1650_SCL_0;
delay_us(5);
}
}
uint5_t TM1650_ack(void)
{
Iic_Mode(GPIO_Mode_IN);
uint ack = 0;
TM1650_SCL_0;
delay_us(5);
TM1650_SCL_1;
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)) //读取引脚(SDA)当前状态是高还是低
ack = 1; //无应答
TM1650_SCL_0;
delay_us(5);
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 Display_Init(void) //显示设备的初始化
{
delay_ms(500); //需要延时400ms等待芯片的启动
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 Show_Num(uint16_t num,uint8_t dp)
{
uint8_t buff = 0;
uint8_t 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 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]); //默认为最大亮度
}
}
numTM1650.h
#ifndef NUMTM1650_H
#define NUMTM1650_H
#include "stm32f10x.h"
#define TM1650_SCL_1 GPIO_SetBits(GPIOB,GPIO_Pin_12)
#define TM1650_SCL_0 GPIO_ResetBits(GPIOB,GPIO_Pin_12)
#define TM1650_SDA_1 GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define TM1650_SDA_0 GPIO_ResetBits(GPIOB,GPIO_Pin_13)
#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 TM1650_Init(void);//TM1650模块端口GPIO初始化
void Iic_Mode(GPIOMode_TypeDef Mode);
void TM1650_start(void);
void TM1650_stop(void);
void TM1650_ack(void);
void TM1650_send(uint8_t data);
void Write_DATA(unsigned char add,unsigned char DATA);
void Display_Init(void);
void Show_Num(uint16_t num,uint8_t dp);
void Display_Change_Brightness(uint8_t num)
#endif
以上就是我的理解,作为初学者,容易疏忽遗漏,希望各位大佬对我多多指教,互相学习 文章来源:https://www.toymoban.com/news/detail-559085.html
文章来源地址https://www.toymoban.com/news/detail-559085.html
到了这里,关于TM1650数码管(类IIC驱动)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!