《ESP32从0到1》之数码管显示(TM1640)

目录

文章内容

硬件

TM1640介绍

TM1640模块介绍

基于sample_project示例创建工程

编写程序

1)新建两线总线驱动文件夹

2)编写soft_2wire_master.h文件

3)编写soft_2wire_master.c文件

4)编写main.c文件

编译下载程序

🌹欢迎关注、订阅、收藏🌹

本专辑最终会以“wifi版温湿度蓝牙网关项目”结案,敬请关注、订阅、收藏

欢迎关注并下载源码


文章内容

        基于sample_project示例创建一个空工程,实现与TM1640通信,点亮LED数码管。

硬件

  • 一款 ESP32 开发板(本专辑中均使用ESP32-LyraT-Mini V1.2开发板)

  • USB 数据线 (A 转 Micro-B)

  • 电脑(Windows)

  • 在开发板上人为增加TM1640显示模块

TM1640介绍

        TM1640 是一种LED(发光二极管显示器)驱动控制专用电路,内部集成有MCU 数字接口、数据锁存器、LED 驱动等电路。显示模式为8段×16位,主要应用于电子产品LED显示屏驱动。

        微处理器的数据通过两线总线接口和 TM1640 通信,在输入数据时当 CLK 是高电平时,DIN 上的信号必须保持不变;只有 CLK 上的时钟信号为低电平时,DIN 上的信号才能改变。数据的输入总是低位在前,高位在后传输.数据输入的开始条件是 CLK 为高电平时,DIN 由高变低;结束条件是 CLK 为高时,DIN 由低电平变为高电平。

        指令数据传输过程如下图:

        写 SRAM 数据地址自动加 1 模式:

        写 SRAM 数据固定地址模式:

ESP32需要通过软件模拟的方式实现两线总线接口与TM1640通信。

TM1640模块介绍

        本实验使用的显示模块为之前的自有项目模块,使用的是共阴极数码管。

        4位共阴极数码管电路原理图如下图所示。

        3位共阴极数码管电路原理图如下图所示。

        当前模块使用TM1640连接3个数码管,SEG并接3个数码管的段位,GRID按照顺序连接数码管的DIG位。

        根据TM1640的"显示数据、地址、芯片管脚之间的对应关系"可确定4位段码管显存地址起始为0xC0H,3位段码管显存地址起始分别0xC4H和0xC7H。

        当要点亮某段位时对应SEG写入1,熄灭某段位时对应SEG写入0。段码编码如下图所示。

基于sample_project示例创建工程

        ctrl+alt+P,输入ESP-IDF show,选择“ESP-IDF: Show Examples Projects” ,找到“sample_project”,选择“Create Project using example sample_project”,在跳出的保存框中,选择某一文件夹,新建Project文件夹,保存。用于存放新建的sample_project工程。

        注意:文件夹名称和路径中最好不要有中文且路径尽量短;

编写程序

1)新建两线总线驱动文件夹

        在项目文件夹下新建"components"文件夹,"soft_2wire_master"子文件夹。子文件夹中新建4个文件"CMakeLists.txt"、"linker.lf"、"soft_2wire_master.c"、"soft_2wire_master.h"。

 

        单击打开新建的"CMakeLists.txt"文件,填充内容:


idf_component_register(SRCS "soft_2wire_master.c"
                       INCLUDE_DIRS "."
                       PRIV_REQUIRES driver
                       LDFRAGMENTS linker.lf)

        单击打开新建的"linker.lf"文件,填充内容:


[mapping:main_default]
archive: libsoft_i2c_master.a
entries:
    * (noflash)

        打开"main"文件夹下的"CMakeLists.txt",添加如下内容:

2)编写soft_2wire_master.h文件

/*
 * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: CC0-1.0
 */

#pragma once

#include <stdint.h>
#include "esp_err.h"
//#include "soc/gpio_num.h"

#ifdef __cplusplus
extern "C" {
#endif


void InitLED(void); //初始化TM1640
void ClearAllShow(void);//清屏(3个数码屏均不显示)
void ClearShow(uint8_t ledindex);//选择指定数码屏清屏
void ShowMearData(uint8_t ledindex,uint16_t datavalue);//选择指定数码屏显示数据


#ifdef __cplusplus
}
#endif

3)编写soft_2wire_master.c文件

        添加头文件:

#include "freertos/FreeRTOS.h"  //所有文件基本都要包含,数据类型定义
#include "esp_rom_sys.h" //需要用us延迟函数
#include "driver/gpio.h" //对管脚进行相关定义
#include "soft_2wire_master.h"

        定义管脚名称并绑定管脚号:


//GPIO管脚号
#define DIO     12
#define CLK     13

        用宏定义定义3个数码管的显存起始地址、显示长度、小数点位数,为程序中指定某数码管做准备(可以用结构体数组,当前案例用的数组实现的)。

        定义编码数组,用于存放数字编码。数字0对应数组索引0位,数字1对应数组索引1位,以此类体。

//显示内容正好对应0123456789abcdef
uint8_t typeTable[] = {
    0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c,
    0x39, 0x5e, 0x79, 0x71
};

        编写起始、结束、发送数据的函数。

//TM1640数据的输入总是低位在前,高位在后传输.在输入数据时当 CLK 是高电平时,DIN 上的信号必须保持不变
void Send(uint8_t bytedata)
{
  for (uint8_t i = 0; i <= 7; i++) {     
         gpio_set_level(CLK,0);
         uint8_t bit = (bytedata >> i) & 0x01;
         gpio_set_level(DIO,bit);
         gpio_set_level(CLK,1);
    }
     gpio_set_level(CLK,0); 
}

//数据输入的开始条件是 CLK 为高电平时,DIN 由高变低
void Start(void)
{
    gpio_set_level(DIO,0);
    esp_rom_delay_us(5);
}

//结束条件是 CLK 为高时,DIN 由低电平变为高电平
void Stop(void)
{
    gpio_set_level(DIO,0);
    gpio_set_level(CLK,1);
    gpio_set_level(DIO,1);
}

        初始化TM1640并清屏

void InitLED(void)
{
    gpio_reset_pin(CLK);
    gpio_reset_pin(DIO);
    
    gpio_set_direction(CLK, GPIO_MODE_OUTPUT);//sclk配置为输出模式
    gpio_set_direction(DIO, GPIO_MODE_OUTPUT);//din配置为只输出模式
    
    gpio_set_pull_mode(CLK, GPIO_PULLUP_ONLY);//线路图有外部上拉的    
    gpio_set_pull_mode(DIO, GPIO_PULLUP_ONLY);//线路图有外部上拉的
  
    //设置两个管脚为默认为高电平
    gpio_set_level(DIO,1);
    gpio_set_level(CLK,1);

    ClearAllShow();
}

//清屏//可当初始化函数用
void ClearAllShow(void)
{
    portENTER_CRITICAL(&g_lock);//进入临界段        
    Start();
    Send(0x40); // 数据命令,写数据到寄存器,自动地址增加,普通模式
    Stop();

    Start();
    Send(0xc0); //地址命令设置,显示地址00H --设置起始地址
    for(uint8_t i = 0; i <= 10; i++) {     
         Send(0x00);
    }
    Stop();

    Start();
    Send(0x8f);//显示控制设置,脉冲宽度14/16,显示开
    Stop(); 
    portEXIT_CRITICAL(&g_lock);//退出临界段
}

        写数据到指定的数码屏


//当前假设3位数码管显示1位小数点数据*10传递,4位数码管显示2位小数点数据*100进行传递
void ShowMearData(uint8_t ledindex,uint16_t datavalue)
{
    uint8_t t[maxDigLen];
    uint8_t showdataindex=0;
    if(ledindex==0)//4位数码管
    {
        t[0]= datavalue/1000;
        t[1]= (datavalue%1000)/100;
        t[2]= (datavalue%100)/10;
        t[3]= datavalue%10;
    }
    else
    {
        t[0]= datavalue/100;
        t[1]= (datavalue%100)/10;
        t[2]= datavalue%10;
    }
    
    portENTER_CRITICAL(&g_lock);//进入临界段        
    /*Start();
    Send(0x40); // 数据命令,写数据到寄存器,自动地址增加,普通模式
    Stop();*/

    Start();
    Send(ledgroupaddr[ledindex]); //地址命令设置,显示地址00H --设置起始地址
    for(uint8_t i = 0; i <= ledgrouplen[ledindex]; i++) {  
        showdataindex = t[i];
        //在指定位后面显示小数点
        if(i==ledgrouppoint[ledindex]) 
        {
            Send(typeTable[showdataindex]|0x80);//该位显示小数点
        }
        else
        {
            Send(typeTable[showdataindex]);
        }         
    }
    Stop();

    Start();
    Send(0x8f);//显示控制设置,脉冲宽度14/16,显示开
    Stop(); 
    portEXIT_CRITICAL(&g_lock);//退出临界段
}

4)编写main.c文件

#include <stdio.h>
#include "esp_log.h"
#include "soft_2wire_master.h"

const char* EXAMPLE_TAG = "soft_2wire_master";
void app_main(void)
{
    InitLED();//初始化LED
    ShowMearData(0,(12.34*100));
    ShowMearData(1,(56.7*10));
   ShowMearData(2,(89.0*10));
    while(1)
    {        
         // Add your main loop handling code here.        
    }
}

编译下载程序

        点击左下角编译按钮。成功编译后打开开发板并连接开发板UART烧录口,选择正确的串口号,点击下载,选择UART,下载程序。

🌹欢迎关注、订阅、收藏🌹

文章中有不清晰或者有疑问、错误的地方,请务必留言提醒、讨论。非常感谢!!!

本专辑最终会以“wifi版温湿度蓝牙网关项目”结案,敬请关注、订阅、收藏

欢迎关注并下载源码

文章同步发表于公众号"IT搬砖客",可免费下载源码。
欢迎关注并留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT搬砖客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值