-
2019-01-29 16:05:03
以下为.h文件:
#ifndef __TM1650_I2C_H #define __TM1650_I2C_H #include "stm8s.h" #include "stm8s_gpio.h" #include "tim1.h" #include "usart2.h" #include <iostm8s103f3.h> #include <intrinsics.h> /********************************** TM1650芯片控制20路灯函数 PB7为SCL口 PB6为SDA口 **********************************/ #define SCL_TM1650 PC_ODR_ODR7 #define SDA_TM1650 PC_ODR_ODR6 #define SDAM_TM1650 PC_IDR_IDR6 #define SET_SCL_OUT_TM1650() {PC_DDR_DDR7=1; PC_CR1_C17 = 1; PC_CR2_C27 = 0;} #define SET_SDA_OUT_TM1650() {PC_DDR_DDR6=1; PC_CR1_C16 = 1; PC_CR2_C26 = 0;} #define SET_SDA_IN_TM1650() {PC_DDR_DDR6=0; PC_CR1_C16 = 0; PC_CR2_C26 = 0;} void IIC_Init_TM1650(void); void TDelay_us(u8 z); void I2C_Start_TM1650(void); void I2C_Stop_TM1650(void); void IIC_Ack_TM1650(void); void IIC_NAck_TM1650(void); uint8_t IIC_Wait_Ack_TM1650(void); void IIC_WrByte_TM1650(uint8_t txd); //u8 Scan_Key(void); void TM1650_Set(u8 add,u8 dat); void Init_Tm1650(void); #endif
以下为.c文件:
#include "TM1650_I2C.h" //-------------------------------------------------------------- // Prototype : void IIC_Init_TM1650(void) // Calls : // Description : //-------------------------------------------------------------- void IIC_Init_TM1650(void) { SET_SCL_OUT_TM1650(); SET_SDA_OUT_TM1650(); SCL_TM1650 = 1; SDA_TM1650 = 1; } //-------------------------------------------------------------- // Prototype : void Delay_us(void) // Description : 大约延时 z us //-------------------------------------------------------------- void TDelay_us(u8 z) { //u8 i; //fcpu 8MHz 时 //for (i=50; i>0; i--); while(z--) { nop();nop();nop();nop(); } } //-------------------------------------------------------------- // Prototype : void I2C_Start(void) // Calls : Delay_5us() // Description : Start Singnal //-------------------------------------------------------------- void I2C_Start_TM1650(void) { // SDA 1->0 while SCL High //SCL高电平期间,SDA出现一个下降沿表示起始信号 SET_SDA_OUT_TM1650(); SDA_TM1650 = 1; //数据线先保持为高,起始信号要该口的下降沿 TDelay_us(4); SCL_TM1650 = 1; //时钟线保持为高 TDelay_us(40); //有一个大概5us的延时具体以器件而定 SDA_TM1650 = 0; //数据线拉低出现下降沿 TDelay_us(4); //延时 一小会,保证可靠的下降沿 SCL_TM1650 = 0; //拉低时钟线,保证接下来数据线允许改变 } //-------------------------------------------------------------- // Prototype : void I2C_Stop(void) // Calls : Delay_5us() // Description : Stop Singnal //-------------------------------------------------------------- void I2C_Stop_TM1650(void) { // SDA 0->1 while SCL High //SCL高电平期间,SDA产生一个上升沿 表示停止 SET_SDA_OUT_TM1650(); SCL_TM1650 = 0; TDelay_us(2); SDA_TM1650 = 0; //保证数据线为低电平 TDelay_us(40); SCL_TM1650 = 1; //先保证时钟线为高电平 TDelay_us(10); //延时 以得到一个可靠的电平信号 SDA_TM1650 = 1; //数据线出现上升沿 TDelay_us(40); //延时 保证一个可靠的高电平 } //应答函数 void IIC_Ack_TM1650(void) { //数据线一直保持为低电平,时钟线出现上升沿即为应答 SET_SDA_OUT_TM1650(); TDelay_us(10); SDA_TM1650 = 0; TDelay_us(10); SCL_TM1650 = 0; TDelay_us(40); SCL_TM1650 = 1; TDelay_us(40); //应答完成后 将时钟线拉低 允许数据修改 SCL_TM1650 = 0; } //非应答 void IIC_NAck_TM1650(void) { //非应答即相反 与应答区别即为数据线保持高电平即可 SET_SDA_OUT_TM1650(); TDelay_us(10); SDA_TM1650 = 1; TDelay_us(10); SCL_TM1650 = 0; TDelay_us(40); SCL_TM1650 = 1; TDelay_us(40); //最后要将时钟线拉低 允许数据变化 SCL_TM1650 = 0; } //等待应答 uint8_t IIC_Wait_Ack_TM1650(void)//0为有应答,1为无应答 { //应答等待计数 uint8_t ackTime = 0; //先将数据线要设置成输入模式本程序未体现,有应答则会出现下降沿 SCL_TM1650 = 0; SET_SDA_OUT_TM1650(); TDelay_us(10); SDA_TM1650 = 1;// TDelay_us(30); SET_SDA_IN_TM1650();//切换为输入模式 //时钟线拉高 SCL_TM1650 = 1; TDelay_us(30); //等待数据线拉低应答 while(SDAM_TM1650){ //如果在该时间内仍未拉低 ackTime ++; if(ackTime > 250) { //认为非应答 停止信号 I2C_Stop_TM1650(); return 1; } } SCL_TM1650 = 0; return 0 ; } void IIC_WrByte_TM1650(uint8_t txd) { //定义一个计数变量 uint8_t i; SET_SDA_OUT_TM1650(); //将时钟线拉低允许数据改变 // SCL = 0; //按位发送数据 for(i = 0;i < 8; i ++) { TDelay_us(2); if((txd&0x80)>>7) //0x80 1000 0000 SDA_TM1650=1; else SDA_TM1650=0; txd<<=1; TDelay_us(20); SCL_TM1650=1; TDelay_us(20); SCL_TM1650=0; TDelay_us(20); } } /*************************** u8 Scan_Key(void) //按键扫描 { u8 i; u8 rekey; I2C_Start_TM1650(); IIC_WrByte_TM1650(0x49);//读按键命令 IIC_Ack_TM1650(); //DIO_H; SET_SDA_IN_TM1650();//切换为输入模式 for(i=0;i<8;i++) { SCL_TM1650=1; rekey = rekey<<1; if(SDAM_TM1650) { rekey++; } TDelay_us(5); SCL_TM1650=0; } IIC_Ack_TM1650(); I2C_Stop_TM1650(); return(rekey); } ****************************/ void TM1650_Set(u8 add,u8 dat) //数码管显示 { //写显存必须从高地址开始写 I2C_Start_TM1650(); IIC_WrByte_TM1650(add); //第一个显存地址 IIC_Ack_TM1650(); IIC_WrByte_TM1650(dat); IIC_Ack_TM1650(); I2C_Stop_TM1650(); } void Init_Tm1650(void) { IIC_Init_TM1650(); delay_ms(50); //需要延时一小段时间,否则开显示会无响应 TM1650_Set(0x48,0x31);//初始化为5级灰度,开显示 }
注意:TM1650芯片启动可能需要一点时间,故发送开显示前应延时一小段时间,否则会收不到。
20200420更新:发现新版TM1650芯片按键部分遇到问题。
解决方法:新版本的晶圆有些因为方案设计会导致芯片振荡器打不开 所以要调一下指令。
更多相关内容 -
TM1650四位共阴数码管模块配套资料_tm1650驱动共阳_TM1650共阴_tm1650芯片资料_TM1650_共阴数码管_
2021-08-09 21:09:50TM1650芯片驱动四位共阴数码管。即模块配套资料。 -
TM1650-stm32_STM32TM1650_TM1650_TM1650.C_tm1650stm32
2021-09-11 15:28:43STM32中使用TM1650的.C文件,可以直接使用。 -
TM1650驱动程序
2019-09-04 16:59:45* 文 件 名:TM1650.c * 版 权: * 功能描述:显示驱动数码屏 * 修改日期 修改人 修改说明 * 2016-3-20 显示驱动数码屏 =========================================================*/ #include ".\head\intrins.h... -
tm1650_TM1650_TM1650驱动2835_TM1650串联_tm1650程序
2021-09-11 08:09:15多年使用的TM1650LED驱动程序,相当好用。 -
tm1650中文资料-数据手册-参数.pdf
2020-01-10 14:00:28TM1650 是一种带键盘扫描接口的 LED(发光二极管显示器)驱动控制专用电路。内部集成有 MCU 输入输出控制数字接口、数据锁存器、LED 驱动、键盘扫描、辉度调节等电路。TM1650 性能稳定、质 量可靠、抗干扰能力强,... -
TM1650手册
2018-01-16 16:14:40TM1650是一种带键盘扫描接口的LED(发光二极管显示器)驱动控制专用IC, 内部集成有MCU 数字接口、数据锁存器、 LED驱动、键盘扫描等电路。 本产品质量可靠、稳定性好、抗干扰能力强。 主要适用于机顶盒、 家电设备... -
tm1650 驱动
2018-08-29 09:18:20搭载在stm32上,已经测试通过的tm1650驱动。只需要添加进工程就能使用 -
stc8系列的 tm1650数码管驱动亲测可用
2021-07-24 18:31:34stc8系列的 tm1650数码管驱动亲测可用 -
TM1650官方文档
2018-08-29 15:35:42TM1650官方文档,主要描述芯片的原理和使用方法。对项目开发有一定的帮助。 -
TM7705驱动程序,tm1650驱动程序案例,C,C++
2021-09-10 18:17:028TM7705的c51 -
stm32-tm1650驱动程序带pdf文件
2018-10-24 14:41:05stm32-tm1650驱动程序带pdf文件,加入直接可用,可修改引脚接口 -
STM32的TM1650程序.zip
2019-11-25 14:34:05基于STM32F103的TM1650数码管驱动的程序,C语言文件,包含TM1650的技术文档(datasheet) -
STM32F030_TM1650.rar
2020-01-10 14:05:34使用STM32F030驱动TM1650,点亮4联数码管。 亲测好使,也是调整了好久终于点亮了。可以参考。 里面有TM1650中文使用手册,有4联数码管引脚图。 -
STM32_TM1650数码管显示代码
2018-08-31 15:14:39基于STM32F103的TM1650控制共阴极8段数码管,亲测可以正常使用 -
tm1650基于stm32f103的驱动程序
2018-04-27 11:35:29[tm1650] [stm32f103] LED 驱动、键盘扫描。该程序体现功能为,0-99计数。累计按键的时间,增加计数速度。 -
stm8S103控制TM1650
2019-04-28 09:47:48TM1650LED数码管驱动,STM8S103 通过模拟IIC控制TM1650显示,按键获取 -
基于stm32的TM1650驱动程序,
2017-11-02 17:58:31基于stm32的TM1650驱动程序,接口已经宏定义,方便移植。亲测可用 -
TM1650+DS3231+四位数码管时钟源码
2018-01-16 16:12:37基于TM1650,DS3231,STC51LE,四位数码管的小时钟,可以实现时间显示和设置、日期显示和设置、指定日期计数 -
TM1650_datasheet.pdf
2020-01-08 11:42:25TM1650 是一种带键盘扫描接口的 LED(发光二极管显示器)驱动控制专用电路。内部集成有 MCU 输入输出控制数字接口、数据锁存器、LED 驱动、键盘扫描、辉度调节等电路。TM1650 性能稳定、质 量可靠、抗干扰能力强,... -
tm1650.rar
2020-04-13 16:12:16TM1650真是一款性价比很高的芯片,一个芯片就能够驱动4位8段数码管以及按键扫描。本程序使用合泰单片机驱动,模拟IIC驱动,已在项目验证过 -
无锡中微AIP650原厂中文资料规格书引脚图兼容TM1650.PDF
2021-10-31 15:12:13无锡中微AIP650AIP650原厂中文资料规格书引脚图兼容TM1650 -
STM32_TM1650数码管显示代码,stm32数码管显示数字,C/C++
2018-08-31 15:14:39本例程基于STM32F103C8T6单片机,驱动了TM1637数码管进行0-9加点与不加点的数据显示。 -
tm1650_TM1650_TM1650驱动2835_TM1650串联_tm1650程序.zip
2021-10-11 23:19:21tm1650_TM1650_TM1650驱动2835_TM1650串联_tm1650程序.zip -
STM32的TM1650程序.rar
2021-12-30 10:28:32STM32的TM1650程序.rar -
数码管显示模块tm1650
2020-08-25 23:12:59提供按键与数码管显示的解决方案,使用tm1650,可以减少对单片机IO口资源的占用,有利于产品开发。数码管显示程序更加简化,代码移植性强。 -
TM1650LED数码管驱动
2019-04-28 09:48:53TM1650LED数码管驱动,STM8S105 通过模拟IIC控制TM1650显示,按键获取 -
tm1650_TM1650_TM1650驱动2835_TM1650串联_tm1650程序_源码.zip
2021-09-30 17:56:40tm1650_TM1650_TM1650驱动2835_TM1650串联_tm1650程序_源码.zip -
智能暖风机——6.利用TM1650实现显示功能
2021-05-20 11:14:28智能暖风机软件实现之利用TM1650实现显示功能前言一、智能暖风机的整体功能设定二、面板显示的方案制定1.面板显示原理2.软件方案设定三、功能实现1.代码实现技术支持 前言 前面我们已经实现了暖风机的外设驱动,...智能暖风机软件实现之利用TM1650实现显示功能
前言
前面我们已经实现了暖风机的外设驱动,本文主要内容是实现暖风机的面板显示功能,采用TM1650芯片作为数码管的驱动芯片。
一、智能暖风机的整体功能设定
- 智能暖风机的设定功能如下表,我们将整个暖风机拆分成几个模块,逐个实现功能;本文实现暖风机的面板显示功能,暖风机在工作时要显示当前室温以及亮起相应的状态灯,在进行设备定时和设备设温时面板要显示定时的时间和设定的温度值。
功能 说明 开关 触摸按键:1个
按键控制,app控制
控制暖风机开关。
目前开发的开启有三种方式:
1.App面板控制
2:按键控制
3:定时控制模式 触摸按键:1个
按键控制,app控制
1:风扇功能:只吹风,不制热。
2:1档加热:风扇+加热1
3:2档加热:风扇+加热2(档位更高)定时 触摸按键:1个
按键控制,app控制
倒计时默认枚举值有cancel, 1h, 2h, 3h, 4h, 5h, 6h,7h, 8h。
倒计时功能针对暖风机开关。
app暖风机倒计时剩余时间。灯光 触摸按键:1个
按键控制,app控制
4种照明模式:
1 rgb1
2 rgb2
3 rgb3
4 rgb4设温 触摸按键:1个
按键控制,app控制
默认温度设置区间为15-40℃,客户可以自行调整温度设定区间。温度显示 硬件:断码显示
按键控制,app控制
只是在设定的时候显示
设备上和当前温度显示复用,app单独显示
设备:温度设定时,显示设定温度,误操作3秒后显示当前室温摇头 触摸按键:1个
按键可控制,app可控制。
开/关待机记忆 按键,app,主动操作开关键关机为待机状态。
再开启后恢复上一次设置:
温度设置:上一次设置
温度显示:当前环境温度
灯光模式:上一次设置
设备定时关:默认关闭
app定时关:默认关闭。
app定时开:上一次设置。断电记忆 断电后为断电状态,再上电恢复上一次设置:
开关状态:默认关
温度设置:上一次设置
温度显示:当前环境温度
灯光模式:上一次设置
设备定时关:默认关闭
app定时关:默认关闭。
app定时开:上一次设置。二、面板显示的方案制定
1.面板显示原理
本案例中面板由两个数码管和7个LED状态灯组成,驱动芯片选择TM1650。
- 显示电路如下:
-
TM1650驱动模块说明
TM1650 是一种带键盘扫描接口的 LED(发光二极管显示器)驱动控制专用电路。
两种显示模式:8段×4位和7段×4位
段驱动电流大于25mA,位驱动电流大于150mA
提供8级亮度控制
IIC通信控制
寄存器名称 寄存器地址 显示设置寄存器(亮度设置、开关显示设置、7段/8段显示) 0x48 显存地址DIG1 0x68 显存地址DIG2 0x6A 显存地址DIG3 0x6C 显存地址DIG4 0x6E 其中显示设置寄存器的配置说明如下:
B7 B6 B5 B4 B3 B2 B1 B0 功能 说明 X 0 0 0 X X 亮度设置 8级 X 0 0 1 X X 亮度设置 1级 X 0 1 0 X X 亮度设置 2级 X 0 1 1 X X 亮度设置 3级 X 1 0 0 X X 亮度设置 4级 X 1 0 1 X X 亮度设置 5级 X 1 1 0 X X 亮度设置 6级 X 1 1 1 X X 亮度设置 7级 X 0 7/8段显示控制位 8段显示方式 X 1 7/8段显示控制位 7段显示方式 X 0 开启/关闭显示位 关显示 X 1 开启/关闭显示位 开显示 打×的位可以为1,也可以为0,建议写0。
- 对显存地址的写时序
控制流程是以IIC时序发送要写的寄存器地址,再发送要写的数据,例:
address : 0x48 //控制寄存器地址 data: 0x0a //8级亮度 开显示 7段显示方式 address : 0x68 //显存地址DIG1 data: 0x7f //7段全亮
完整的写时序:
2.软件方案设定
-
面板显示嵌入式方案设定
前面已经实现了暖风机的温度采集功能,现在要将采集的温度显示到面板上,SOC按照IIC时序向TM1650发送显示命令控制数码管亮起相应的数字控制状态指示灯LED亮起,实现面板显示功能。
通信引脚设定:SDA1 | P26 SCL1 | P24
三、功能实现
1.代码实现
- 在之前开发的基础上增加程序,增加tm1650.c文件和其头文件,目前整个工程的文件结构如下:
├── src | ├── tuya_drive | | └── b3950 | | └── b3950.c //温度传感器驱动相关 | | └── tm1650 | | └── tm1650.c | | └── gpio_control | | └── gpio_control.c | | └── timer | | └── timer.c //定时器相关 | ├── tuya_device.c //应用层入口文件 | ├── tuya_thread.c //主要线程处理文件 | └── tuya_dp_process.c //dp数据触发的主要应用文件 | ├── include //头文件目录 | ├── tuya_drive_h | | └── b3950_h | | └── b3950.h | | └── tm1650_h | | └── tm1650.h | | └── gpio_control_h | | └── gpio_control.h | | └── timer_h | | └── timer.h | ├── tuya_device.h | ├── tuya_thread.h | └── tuya_dp_process.h | └── output //编译产物
其中tm1650.c文件中的内容主要是驱动tm1650芯片的代码。
tm1650.c代码及说明如下:
#include "tm1650.h" typedef struct { tuya_i2c_t *i2c; } tm1650_dev_t; /*============================ PROTOTYPES ====================================*/ void tm1650_led_init(void); void tm1650_init(tm1650_dev_t *dev); void tm1650_close(void); void TM1650_Write(uint8_t addr, uint8_t data, tm1650_dev_t *dev); void TM1650_SetDisplay(uint8_t brightness, uint8_t mode, uint8_t state); void TM1650_SetNumber(uint8_t index, uint8_t mode,uint8_t num); /*============================ IMPLEMENTATION ================================*/ static tm1650_dev_t tm1650_dev; static uint8_t s_7number[10] = {0x5F,0x03,0x6E,0x6B,0x33,0x79,0x7D,0x0B,0x7F,0x7B}; // 7段显示方式0~9 static uint8_t s_8number[10] = {0xDF,0x83,0xEE,0xEB,0xB3,0xF9,0xFD,0x8B,0xFF,0xFB}; // 8段显示方式0~9 /*状态指示灯:cool hot1 hot2 cool+shake hot1+shake hot2+shake set_temperature set_time_hour close */ static uint8_t s_7status[10] = {0x23,0x32,0x2a,0x63,0x72,0x6a,0x02,0x04,0x00}; /** * @Function: tm1650_led_init * @Description: tm1650_led display init * @Input: none * @Output: none * @Return: none * @Others: */ void tm1650_led_init(void) { /*SCL_PIN:PA24 SDA_PIN:PA26*/ tuya_i2c_sw_cfg_t sw_cfg; TUYA_I2C_SW_CFG_INIT(&sw_cfg, TUYA_PA24, TUYA_PA26, 1); tuya_sw_i2c_register(TUYA_I2C0, &sw_cfg); tm1650_init(&tm1650_dev); } /** * @Function: tm1650 init * @Description: Equip with IIC equipment and set the gray level of digital tube * @Input: none * @Output: none * @Return: none * @Others: */ void tm1650_init(tm1650_dev_t *dev) { uint8_t buffer[2]; //! looking for IIC handle dev->i2c = tuya_driver_find(TUYA_DRV_I2C, TUYA_I2C0); //! no device addr TUYA_I2C_MASTER_CFG(dev->i2c, 0x00); tuya_i2c_init(dev->i2c); buffer[0] = 0x48; //! register addr buffer[1] = 0x71; //! power set tuya_i2c_master_send(dev->i2c, 0x00, TUYA_I2C_NO_START | TUYA_I2C_WR, buffer, 2); } /** * @Function: tm1650_close * @Description: Turn off the digital display * @Input: none * @Output: none * @Return: none * @Others: */ void tm1650_close(void) { TM1650_Write(0x68, 0x00, &tm1650_dev); TM1650_Write(0x6a, 0x00, &tm1650_dev); TM1650_Write(0x6e, 0x00, &tm1650_dev); } /** * @Function: TM1650_Write * @Description: Write data to TM1650 * @Input: addr:register addr data: * @Output: none * @Return: none * @Others: */ void TM1650_Write(uint8_t addr, uint8_t data, tm1650_dev_t *dev) { uint8_t buffer[2]; buffer[0] = addr; //! register addr buffer[1] = data; //! Transmitted data tuya_i2c_master_send(dev->i2c, 0x00, TUYA_I2C_NO_START | TUYA_I2C_WR, buffer, 2); } /** * @Function: TM1650_SetDisplay * @Description: Setting display parameters * @Input: brightness:1-8 mode: Paragraph 7/Paragraph 8 state :display on/off * @Output: none * @Return: none * @Others: */ void TM1650_SetDisplay(uint8_t brightness, uint8_t mode, uint8_t state) { if(state) { if(mode == 7) // 7段显示方式 { TM1650_Write(0x48, brightness*16 + 1*4 + 1, &tm1650_dev); } else if(mode == 8) // 8段显示方式 { TM1650_Write(0x48, brightness*16 + 1, &tm1650_dev); } } else { TM1650_Write(0x48, 0x00,&tm1650_dev); // 关闭显示 } } /** * @Function: TM1650_SetNumber * @Description: display num * @Input: index:Which number mode: Paragraph 7/Paragraph 8 num :Display number * @Output: none * @Return: none * @Others: */ void TM1650_SetNumber(uint8_t index, uint8_t mode, uint8_t num) { uint8_t indexAddr = 0; uint8_t numValue = 0; if(index == 1) { indexAddr = 0x68; } else if(index == 2) { indexAddr = 0x6A; } else if(index == 3) { indexAddr = 0x6C; } else if(index == 4) { indexAddr = 0x6E; } if(mode == 7) // 7段显示方式 { numValue = s_7number[num]; } else if(mode == 8) // 8段显示方式 { numValue = s_8number[num]; } TM1650_Write(indexAddr, numValue, &tm1650_dev); } /** * @Function: display_num * @Description: display num * @Input: num :Display number * @Output: none * @Return: none * @Others: */ void display_num(uint8_t num) { uint8_t num_1 = 0; uint8_t num_10 = 0; num_1 = num%10; num_10 = (num%100)/10; TM1650_SetNumber(1, 7, num_10); TM1650_SetNumber(2, 7, num_1); } /** * @Function: display_status * @Description: led_display_work_status * @Input: status :work_status * @Output: none * @Return: none * @Others: */ void display_status(uint8_t status) { TM1650_Write(0x6E, status, &tm1650_dev); }
- TM1650的驱动工作已经完成,tm1650_init()函数调用后就已经进行了数码管的亮度设置,后面在定时采集温度的线程中调用display_num(temperature)即可显示温度。
tuya_thread.c增加的代码及说明如下:上报温度信息的线程中每10秒采集一次温度信息并在显示面板进行显示
void update_temperature_thread(void) { static int last_temper = 0; while(1) { tuya_hal_semaphore_wait(g_temper_binsemap); last_temper = cur_temper_get(); if(last_temper > 50) { last_temper = 50; } else if(last_temper < -20) { last_temper = -20; } temper_s.value = last_temper; dp_memory_s.temperature_value = last_temper; PR_DEBUG("CURRENT TIME : %d",timercount); PR_DEBUG("last_time : %d",dev_key_s.last_time_count); //开关开启才会显示,dev_key_s.display_lock初始值为0,后面逻辑控制会用到 if((switch_s.power == 1) && (dev_key_s.display_lock == 0)){ display_num(dp_memory_s.temperature_value); //根据暖风机的工作状态,开启状态灯 display_status(dp_memory_s.status); report_one_dp_status(DP_TEMPER); //如果开启倒计时关闭,将会上传所剩的倒计时时间 report_one_dp_status(DP_SHUTDOWN_TIME); } } }
- 此时一个暖风机的显示功能就已经实现了,其他功能实现请见后续文章。
技术支持
您可以通过以下方法获得涂鸦的支持:
-
TM1650代码记录(基于51单片机)
2021-12-25 08:59:39TM1650代码记录(基于51单片机)一、TM1650
0、介绍
功能特点:
TM1650用于驱动共阴极显示器 两种显示模式:8段×4位和7段×4位 段驱动电流大于25mA,位驱动电流大于150mA 提供8级亮度控制 键盘扫描:7×4bit内部集成三极管驱动 高速两线式串行接口 内置时钟振荡电路 内置上电复位电路 支持2.8V-5.5V电源电压 提供DIP16及SOP16封装
1、典型应用电路
2、原理图
3、PCB
4、实物图
5、键盘扫描码
哔哩哔哩演示视频:TM1650数码管显示及按键扫描二、代码记录
1、C文件:
头文件引用、定义数组、定义引脚
#include "allhead.h" // ------------------------------------------------------------ // IO口模拟I2C通信 // SCL_T接P3^3 // SDA_T接P3^4 // ------------------------------------------------------------ sbit SCL_T = P3^3; //串行时钟 sbit SDA_T = P3^4; //串行数据 /*********************TM1650数码管显示数组************************************/ unsigned char code dig1[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //0、1、2、3、4、5、6、7、8、9、-//不带小数点 unsigned char code dig2[11]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xc0}; //0、1、2、3、4、5、6、7、8、9、-//带小数点 unsigned char key_data = 0; //键盘扫描码
IIC起始位:
/********************************************** //TM Start//起始位 **********************************************/ void TM_Start() { SCL_T = 1; SDA_T = 1; Delay5us_TM(); SDA_T = 0; }
IIC结束位:
/********************************************** //TM Stop//结束位 **********************************************/ void TM_Stop() { SCL_T = 1; SDA_T = 0; Delay5us_TM(); SDA_T = 1; }
ACK信号:
/********************************************** //TM Ack//ACK信号 **********************************************/ void TM_Ack() { unsigned char timeout = 1; SCL_T = 1; Delay5us_TM(); SCL_T = 0; while((SDA_T) && (timeout <= 100)) { timeout++; } Delay5us_TM(); SCL_T = 0; }
写一个字节:
/********************************************** // 通过总线写一个字节 **********************************************/ void Write_TM_Byte(unsigned char TM_Byte) { unsigned char i; SCL_T = 0; Delay1us_TM(); for(i=0;i<8;i++) { if(TM_Byte & 0x80) SDA_T = 1; else SDA_T = 0; SCL_T = 0; Delay5us_TM(); SCL_T = 1; Delay5us_TM(); SCL_T = 0; TM_Byte <<= 1; } }
读一个字节:
/********************************************** // 通过总线读一个字节 **********************************************/ unsigned char Read_TM_Byte() { unsigned char i; unsigned char j; unsigned char TM_Byte; for(i=0;i<8;i++) { SCL_T = 0; Delay5us_TM(); TM_Byte <<= 1; j = SDA_T; TM_Byte += j; SCL_T = 1; Delay5us_TM(); } SCL_T = 0; Delay1us_TM(); return TM_Byte; }
TM1650写数据:
/*********************TM1650写数据************************************/ void TM_WrDat(unsigned char add,unsigned char dat) { TM_Start(); Write_TM_Byte(add);//显存地址 TM_Ack(); Write_TM_Byte(dat);//显示数据 TM_Ack(); TM_Stop(); }
TM1650写命令:
/*********************TM1650写命令************************************/ void TM_WrCmd(unsigned char Bri) { TM_Start(); Write_TM_Byte(0x48);//显示模式 TM_Ack(); Write_TM_Byte(Bri); TM_Ack(); TM_Stop(); }
TM1650初始化:
/*********************TM1650初始化************************************/ void TM_Init() { TM_WrCmd(0x11);//1级亮度//8段显示//开显示 TM_WrDat(0x68,0xff);//DIG1 TM_WrDat(0x6a,0xff);//DIG2 TM_WrDat(0x6c,0xff);//DIG3 TM_WrDat(0x6e,0xff);//DIG4 }
TM1650显示(可自行修改):
/*********************TM1650显示**************************************/ void Dis_TM(unsigned char dig1,unsigned char dig2,unsigned char dig3,unsigned char dig4) { TM_WrDat(0x68,dig1);//DIG1 TM_WrDat(0x6a,dig2);//DIG2 TM_WrDat(0x6c,dig3);//DIG3 TM_WrDat(0x6e,dig4);//DIG4 }
TM1650读按键:
/*********************TM1650读按键************************************/ void TM_ReCmd() { TM_Start(); Write_TM_Byte(0x49);//读取模式 TM_Ack(); key_data = Read_TM_Byte();//读取键盘扫描码 TM_Ack(); TM_Stop(); }
TM1650读处理(显示键盘扫描码和显示按键位置二选一)
显示键盘扫描码:/*********************TM1650读处理************************************/ void Read_TM() { //数码管显示键盘扫描码 unsigned char a = 0; unsigned char b = 0; unsigned char c = 0; TM_ReCmd();//TM1650读按键 a = key_data/100; b = key_data/10%10; c = key_data%10; Dis_TM(dig1[0],dig1[a],dig1[b],dig2[c]); //数码管显示键盘扫描码 }
显示按键位置:
/*********************TM1650读处理************************************/ void Read_TM() { //数码管显示按键位置 unsigned char a = 0; unsigned char b = 0; TM_ReCmd();//TM1650读按键 switch(key_data) { //第一行 case 0x44: a = 1; b = 1; break; case 0x4c: a = 1; b = 2; break; case 0x54: a = 1; b = 3; break; case 0x5c: a = 1; b = 4; break; case 0x64: a = 1; b = 5; break; case 0x6c: a = 1; b = 6; break; case 0x74: a = 1; b = 7; break; //第二行 case 0x45: a = 2; b = 1; break; case 0x4d: a = 2; b = 2; break; case 0x55: a = 2; b = 3; break; case 0x5d: a = 2; b = 4; break; case 0x65: a = 2; b = 5; break; case 0x6d: a = 2; b = 6; break; case 0x75: a = 2; b = 7; break; //第三行 case 0x46: a = 3; b = 1; break; case 0x4e: a = 3; b = 2; break; case 0x56: a = 3; b = 3; break; case 0x5e: a = 3; b = 4; break; case 0x66: a = 3; b = 5; break; case 0x6e: a = 3; b = 6; break; case 0x76: a = 3; b = 7; break; //第四行 case 0x47: a = 4; b = 1; break; case 0x4f: a = 4; b = 2; break; case 0x57: a = 4; b = 3; break; case 0x5f: a = 4; b = 4; break; case 0x67: a = 4; b = 5; break; case 0x6f: a = 4; b = 6; break; case 0x77: a = 4; b = 7; break; default: a = 0; b = 0; break; } Dis_TM(0x00,dig1[a],dig1[10],dig2[b]); //数码管显示按键位置 }
TM1650延时函数:
/*********************TM1650驱动程序用的延时程序************************************/ void Delay1us_TM() //@24.000MHz { unsigned char i; i = 6; while (--i); } void Delay5us_TM() //@24.000MHz { unsigned char i; i = 38; while (--i); }
2、H文件
#ifndef _TM1650_H_ #define _TM1650_H_ /*************************************************/ //数码管显示数组 extern unsigned char code dig1[11]; //无小数点 extern unsigned char code dig2[11]; //有小数点 extern unsigned char key_data; //键盘扫描码 //TM1650延时函数 void Delay1us_TM(); //@24.000MHz void Delay5us_TM(); //@24.000MHz //TM1650外调函数 void TM_Init();//TM1650初始化 void Dis_TM(unsigned char dig1,unsigned char dig2,unsigned char dig3,unsigned char dig4);//TM1650四位显示 void Read_TM();//TM1650读处理 /*************************************************/ #endif
三、结束语
该代码测试运行环境:
基于51单片机
主控:STC8G1K17
晶振:24Mhz(内部晶振)
主板:控制板-2-20mm-V4.0哔哩哔哩演示视频:TM1650数码管显示及按键扫描
哔哩哔哩:风筝见证-雪夜
单片机QQ交流群:210560687
欢迎大家加入,一起交流学习,一起进步