涂鸦智能暖风机软件实现之利用TM1650实现显示功能
Posted 三明治开发社区
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了涂鸦智能暖风机软件实现之利用TM1650实现显示功能相关的知识,希望对你有一定的参考价值。
智能暖风机软件实现之利用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实现显示功能的主要内容,如果未能解决你的问题,请参考以下文章