名奢网 名表 最新资讯 查看内容

【细说STM32】【十一】I2C控制4位数码管

2022-11-28 13:18| 发布者: 挖安琥| 查看: 147| 评论: 1

放大 缩小
简介:本期将引见一款TM1637驱动的四位数码管,经过软件模仿时序的措施中止I2C通讯完成数码管的显现功用。一、IIC通讯I2C(IIC,Inter-Integrated Circuit),两线式串行总线,由PHILIPS公司开发用于衔接微控制器及其外围设备 ...

本期将引见一款TM1637驱动的四位数码管,经过软件模仿时序的措施中止I2C通讯完成数码管的显现功用。


一、IIC通讯


I2C(IIC,InterIntegrated Circuit),两线式串行总线,PHILIPS公司开发用于衔接微控制器及其外围设备。它是由数据线SDA和时钟SCL构成的串行总线,可发送和接纳数据。在CPU与被控IC之间、ICIC之间中止双向传送,高速IIC总线普通可达400kbps以上。IIC是半双工通讯方式。


I2C通讯


【细说STM32】【十一】I2C控制4位数码管


I2C总线的通讯过程主要包含三个主要阶段:起始阶段、数据传输阶段和终止阶段。


1.起始阶段:


闲暇状态I2C总线总线的SDASCL两条信号线同时处于高电平常,规则为总线的闲暇状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。


开端信号:SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。


2.数据传输阶段


数据传输:I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发。I2C总线中止数据传送时,时钟信号为高电平期间,数据线上的数据必须坚持稳定,只需在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变更。


应对信号ACK发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接纳器反响一个应对信号。应对信号为低电平常,规则为有效应对位(ACK简称应对位),表示接纳器曾经胜利地接纳了该字节;应对信号为高电平常,规则为非应对位(NACK),普通表示接纳器接纳该字节没有胜利。


3.终止阶段


中止信号:SCL为高期间,SDA由低到高的跳变;中止信号也是一种电平跳变时序信号,而不是一个电平信号。


二、TM1637驱动电路引见


TM1637采用功率CMOS工艺,显现方式(8×6),支持共阳数码管输出,键扫描(8×2bit),增强型抗干扰按键辨认电路,辉度调理电路(占空比8级可调),两线串行接口(CLK,DIO),振荡方式:内置RC振荡(450Khz+-5%),内置上电复位电路,内置自动消隐电路。


【细说STM32】【十一】I2C控制4位数码管


显现寄存器地址和显现方式


该寄存器存储经过串行接口从外部器件传送到TM1637 的数据,地址00H-05H共6个字节单元,分别与芯片SGE和GRID管脚所接的LED灯对应,分配如下图:写LED显现数据的时分,依照从显现地址从低位到高位,从数据字节的低位到高位操作。


【细说STM32】【十一】I2C控制4位数码管


接口阐明


微处置器的数据经过两线总线接口和 TM1637 通讯,在输入数据时当 CLK 是高电平常,DIO 上的信号必须坚持不变;只需 CLK 上的时钟信号为低电平常,DIO 上的信号才干改动。数据输入的开端条件是 CLK为高电平常,DIO 由高变低;终了条件是 CLK 为高时,DIO 由低电平变为高电平。


TM1637 的数据传输带有应对信号 ACK,当传输数据正确时,会在第八个时钟的降落沿,芯片内部会产生一个应对信号 ACK 将 DIO 管脚拉低,在第九个时钟终了之后释放 DIO 口线。


1.指令数据传输过程如下图(读按键数据时序)


【细说STM32】【十一】I2C控制4位数码管


Command:读按键指令;S0、S1、S2、K1、K2 组成按键信息编码,S0、S1、S2 为 SGn 的编码,K1、K2 为 K1 和 K2 键的编码,读按键时,时钟频率应小于 250K,先读低位,后读高位。在数码管显现这里未用到读数据功用,这里暂时不作细致引见。


2.SRAM 数据地址自动加1 方式


【细说STM32】【十一】I2C控制4位数码管


Command1:设置数据


Command2:设置地址


Data1~N:传输显现数据


Command3:控制显现


3.写 SRAM 数据固定地址方式


【细说STM32】【十一】I2C控制4位数码管


Command1:设置数据


Command2:设置地址


Data1~N:传输显现数据


Command3:控制显现


数据指令


指令用来设置显现方式和LED 驱动器的状态。


在CLK降落沿后由DIO输入的第一个字节作为一条指令。经过译码,取最高B7、B6两位比特位以区别不同的指令。


B7


B6


指令


0


1


数据命令设置


1


0


显现控制命令设置


1


1


地址命令设置


1)数据命令设置


该指令用来设置数据写和读,B1和B0位不允许设置01或11。


【细说STM32】【十一】I2C控制4位数码管


2)地址命令设设置


该指令用来设置显现寄存器的地址;假如地址设为0C6H 或更高,数据被疏忽,直到有效地址被设定;上电时,地址默许设为00H。


【细说STM32】【十一】I2C控制4位数码管


3)显现控制


将数据写0x8f,翻开显现开关,数码管显现数据


【细说STM32】【十一】I2C控制4位数码管


三、数码管模块原理图


【细说STM32】【十一】I2C控制4位数码管


数码管按段数可分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显现);按能显现多少个“8”可分为1位、2位、3位、4位、5位、6位、7位等数码管;


按发光二极管单元衔接方式可分为共阳极数码管和共阴极数码管。共阳数码管是指将一切发光二极管的阳极接到一同构成公共阳极(COM)的数码管,共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平常,相应字段就点亮,当某一字段的阴极为高电平常,相应字段就不亮。共阴数码管是指将一切发光二极管的阴极接到一同构成公共阴极(COM)的数码管,共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平常,相应字段就点亮,当某一字段的阳极为低电平常,相应字段就不亮。


【细说STM32】【十一】I2C控制4位数码管


四、程序设计一


依据TM1637通讯时序图能够看出要完成数码管显现能够分红4部分,分别为数据命令设置、地址命令设置、数据显现、显现控制。每个命令的设置都有起始、数据传输和终止三个过程。


1.数据命令设置


//开端信号


TM1637_Start();


//数据传输


TM1637_WriteByte(0x44);//0x44固定方式有利于控制显现位,,0x40则采用显现地址自加方式


TM1637_Ack();


//中止信号


TM1637_Stop();


2.地址命令设置及数据显现


//开端信号


TM1637_Start();


//数据传输


TM1637_WriteByte(0xC0+p);//0X00地址开端显现


TM1637_Ack();


TM1637_WriteByte(NumDis[ch]);//显现数据


TM1637_Ack();


//中止信号


TM1637_Stop();


3.显现控制


//开端信号


TM1637_Start();


//数据传输


TM1637_WriteByte(0x8f);//显现开启


TM1637_Ack();


//中止信号


TM1637_Stop();


细致代码:


在"driver_delay.h"文件中定义了


#define TM1637_CLK_Low GPIO_ResetBits(GPIOB,GPIO_Pin_10)


#define TM1637_CLK_High GPIO_SetBits(GPIOB,GPIO_Pin_10)


#define TM1637_DIO_Low GPIO_ResetBits(GPIOB,GPIO_Pin_11)


#define TM1637_DIO_High GPIO_SetBits(GPIOB,GPIO_Pin_11)


#define TM1637_DIO_IN GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)


//单个数码管数组显现0123456789


unsigned charNumDis[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0X6F};//0123456789


//开端信号;数据输入的开端条件是CLK为高电平常,DIO 由高变低


void TM1637_Start(void)


{


TM1637_CLK_High;


TM1637_DIO_High;


delay_us(2);


TM1637_DIO_Low;


}


//应对信号;当传输数据正确时,会在第八个时钟的降落沿,芯片内部会产生一个应对信号ACK DIO 管脚拉低,在第九个时钟终了之后释放DIO 口线


void TM1637_Ack(void)


{


TM1637_CLK_Low;


delay_us(5);


while(TM1637_DIO_IN);//读取DIO口的状态,0为有应对信号


TM1637_CLK_High;


delay_us(2);


TM1637_CLK_Low;


}


//中止信号;终了条件是CLK 为高时,DIO 由低电平变为高电平


void TM1637_Stop(void)


{


TM1637_CLK_Low;


delay_us(2);


TM1637_DIO_Low;


delay_us(2);


TM1637_CLK_High;


delay_us(2);


TM1637_DIO_High;


}


//写数据


void TM1637_WriteByte(unsigned charoneByte)


{


unsigned int i;


//发送8位的数据


for(i=0;i<8;i++)


{


TM1637_CLK_Low;


//从最低位开端发送


if(oneByte&0x01)


{


TM1637_DIO_High;


}


else


{


TM1637_DIO_Low;


}


delay_us(3);


oneByte=oneByte>>1;//右移一位


TM1637_CLK_High;


delay_us(3);


}


}


//初始值显现0000


void TM1637_Display(void)


{


//数据命令设置


TM1637_Start();


TM1637_WriteByte(0x40);//0x40则采用显现地址自加1方式


TM1637_Ack();


TM1637_Stop();


//地址设置


TM1637_Start();


TM1637_WriteByte(0xC0);//0X00地址开端显现


TM1637_Ack();


//数据显现


TM1637_WriteByte(0x3f);//显现0


TM1637_Ack();


TM1637_WriteByte(0x3f);//显现0


TM1637_Ack();


TM1637_WriteByte(0x3f);//显现0


TM1637_Ack();


TM1637_WriteByte(0x3f);//显现0


TM1637_Ack();


TM1637_Stop();


//显现控制


TM1637_Start();


TM1637_WriteByte(0x8f);//开启显现


TM1637_Ack();


TM1637_Stop();


}


//显现变量值


void TM1637_DisplayChar(unsigned intch,unsigned int p)


{


if(ch>10)ch=0;//避免数组越界


//数据命令设置


TM1637_Start();


TM1637_WriteByte(0x44);//0x44固定方式有利于控制显现位,0x40则采用显现地址自加方式这里不运用


TM1637_Ack();


TM1637_Stop();


//地址设置


TM1637_Start();


TM1637_WriteByte(0xC0+p);//0X00地址开端显现


TM1637_Ack();


//数据显现


TM1637_WriteByte(NumDis[ch]);//显现


TM1637_Ack();


TM1637_Stop();


//显现控制


TM1637_Start();


TM1637_WriteByte(0x8f);


TM1637_Ack();


TM1637_Stop();


}


//GPIO初始化


void TM1637_Init(void)


{


GPIO_InitTypeDef GPIO_InitStructure;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);


GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11;


GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;


GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;


GPIO_Init(GPIOB, &GPIO_InitStructure);


}


主函数代码


int main(void)


{


inti,j;


TM1637_Init();


TM1637_Display();//显现初始值0000


delay_ms(5000);//延时5s


while(1)


{


//每个数码管依次循环加到9


for(i=3;i>=0;i--)


{


for(j=0;j<10;j++)


{


delay_ms(300);


TM1637_DisplayChar(j,i);


}


if(i==0)i=4;


}


}


}


效果显现:初始值显现0000,持续5S后,从右到左,每个数码管依次循环加到9


【细说STM32】【十一】I2C控制4位数码管


【细说STM32】【十一】I2C控制4位数码管


五、程序设计二


Mixly依据这个流程,也能够很方便的写出对数码管模块的显现控制


子函数模块


【细说STM32】【十一】I2C控制4位数码管


【细说STM32】【十一】I2C控制4位数码管


【细说STM32】【十一】I2C控制4位数码管


【细说STM32】【十一】I2C控制4位数码管


转译的代码:


//开端信号


void start() {


pinMode(2, OUTPUT);


digitalWrite(3,HIGH);


digitalWrite(2,HIGH);


delayMicroseconds(2);


digitalWrite(2,LOW);


}


//应对信号


void ack() {


digitalWrite(3,LOW);


delayMicroseconds(5);


if(digitalRead(2) == 1) {


}else {


digitalWrite(3,HIGH);


delayMicroseconds(2);


digitalWrite(3,LOW);


}


}


//中止信号


void stop() {


pinMode(2, OUTPUT);


digitalWrite(3,LOW);


delayMicroseconds(2);


digitalWrite(2,LOW);


delayMicroseconds(2);


digitalWrite(3,HIGH);


delayMicroseconds(2);


digitalWrite(2,HIGH);


}


//写数据


void write(byte x) {


digitalWrite(2,HIGH);


for(int i = 1; i <= 8; i = i + (1)) {


digitalWrite(3,LOW);


if ((x&0x01)) {


digitalWrite(2,HIGH);


}else {


digitalWrite(2,LOW);


}


delayMicroseconds(3);


x= (x>>1);


digitalWrite(3,HIGH);


delayMicroseconds(3);


}


}


//显现0000


void display_starter() {


//数据命令设置


start();


write(0x40);


ack();


stop();


//地址设置


start();


write(0xC0);


ack();


//数据显现


write(0x3F);


ack();


write(0x3F);


ack();


write(0x3F);


ack();


write(0x3F);


ack();


stop();


//显现控制


start();


write(0x8F);


ack();


stop();


}


int NUM[]={0X06, 0X5B, 0X4F, 0X66, 0X6D,0X7D, 0X07, 0X7F, 0X6F, 0X3F};


//显现变量


void display_char(int ch, int p) {


if(ch > 10) {


ch = 0;


}


p =p - 1;


start();


write(0X44);


ack();


stop();


start();


write(0xC0 + p);


ack();


write(NUM[(int)(ch - 1)]);


ack();


stop();


start();


write(0x8F);


ack();


stop();


}


主函数模块


【细说STM32】【十一】I2C控制4位数码管


转译的代码


void setup(){


pinMode(3, OUTPUT);


pinMode(2, OUTPUT);


display_starter();//设置初始值0000


delay(5000);//延时5S


}


void loop(){


display_char(1, 4);//第四个数码管显现1


delay(1000);


}


效果显现:初始值显现0000,持续5S后第四个数码管显现1


【细说STM32】【十一】I2C控制4位数码管


【细说STM32】【十一】I2C控制4位数码管


作者:冯美文


点击原文链接,能够下载代码。


假如你觉得有用,欢送点击 赞扬



路过

雷人

握手

鲜花

鸡蛋
已有 1 人参与

会员评论

  • wanhuLee 2022-11-28 13:19 引用
    感激楼主分享~楼主其他文章为什么不能查看呢?

最新文章

文章列表

 名表回收网手机版

官网微博:名表回收网服务平台

今日头条二维码 1 微信公众号二维码 1 抖音小程序二维码 1
浙江速典奢贸易有限公司 网站经营许可证 备案号:浙ICP备19051835号2012-2022
名表回收网主要专注于手表回收,二手名表回收/销售业务,可免费鉴定(手表真假),评估手表回收价格,正规手表回收公司,浙江实体店,支持全国范围上门回收手表
返回顶部