【RTT-Studio】详细使用教程十:TM1638驱动数码管

news2024/9/27 19:24:43

文章目录

    • 一、简介
    • 二、TM1638地址组
    • 三、TM1638的两种数码管使用方式
    • 四、TM1638数据格式
    • 五、按键扫描和键扫复用
    • 六、完整代码

一、简介

TM1638是深圳市天微电子有限公司设计的一款带键盘扫描接口的LED(发光二极管显示器)驱动控制专用芯片,内部集成有MCU数字接口、数据锁存器、LED高压驱动、键盘扫描等电路。主要应用于冰箱、空调 、家庭影院等产品的高段位显示屏驱动。
器件手册:TM1638芯片手册

器件特性

  • 采用功率CMOS 工艺,串行接口(CLK,STB,DIO)
  • 显示模式 10 段×8 位
  • 键扫描(8×3bit)
  • 8级辉度可调,内置上电复位电路
  • 振荡方式:RC 振荡(450KHz+5%)

引脚功能说明

  • STB:片选端;在上升或下降沿初始化串行接口,随后等待接收指令。当STB 为高时,CLK被忽略
  • DIO:数据端;在时钟上升沿输入/输出串行数据
  • CLK:时钟端;输入时钟信号
  • K1~K3:键扫输入;输入该脚的数据在显示周期结束后被锁存。
  • SEG1/KS1~SEG8/KS8:段输出;P管开漏输出,也用作键扫描
  • SEG9,SEG10:段输出;P管开漏输出
  • GRID1~GRID8:位输出;N管开漏输出

二、TM1638地址组

1.显存地址中,如果GRIDn和SEGn对应的地址里数据为1,则连接到GRIDn和SEGn上的LED段落将会被点亮。 例如00H的数据为0X0F,则连到GIRD1和SEG1、SEG2、SEG3、SEG4上的LED段落将会被点亮。
在这里插入图片描述

2.每个Byte里储存6个键值数据,相对应的位置为1则代表对应位置有键按下。
在这里插入图片描述

3.指令分类
TM1638通过传送的8位指令的B7,B6两位来区分指令类型:

B7 B6指令类型
0 1数据命令
1 1地址命令
1 0显示控制命令

在这里插入图片描述
在这里插入图片描述

4.地址命令用来设置要写入的数据的地址。数据写入有自增址和固定址两种,固定址每次写入数据需要指定要写入数据的地址。
在这里插入图片描述
显示控制命令主要是用来设置LED的亮度,以及显示开关。


三、TM1638的两种数码管使用方式

TM1638的一个优点是:不区分共阴/共阳,两种数码管都可以使用,但是使用方法有所不同。
  这里涉及到TM1638的显示原理:TM1638的GRIDn端是始终保持低电平的,当显存地址里对应的数据为1时,TM1638令与其对应的SEGn端为高电平来使LED导通发光。

(1)共阴方式
  共阴数码管使用同一个阴极和多个阳极,因为GRID始终为低电平,所以只能由1个GRIDn端作为共阴极,而8个SEG端作为阳极。在这里插入图片描述
  在这里插入图片描述

这时每个数码管的显示数据由8个SEGn对应1个GRIDn端组成,由显存地址关系图可知每个非奇数地址便储存着1个数码管的显示数据。
  共阴数码管的显存数据写入比共阳方便很多,只用向一个地址写入8位数据即可。例如GRID1和SEG1~SEG8对应共阴LED1,要让其显示 0 则只用向 00H 地址写入 0X3F;
在这里插入图片描述
  共阴方式的不足则是无法使用SEG9和SEG10来组成共阴数码管,所以共阴方式最多可以使用8个数码管。多余的SEG9和SEG10仍可以使用,但必须采用共阳方式。

(2)共阳方式
  共阴数码管使用同一个阳极和多个阴极,因为GRID始终为低电平,所以只能由8个GRIDn端作为阴极,1个SEG端作为共阳极。
  在这里插入图片描述

这时每个数码管的显示数据由8个GRIDn对应1个SEGn端组成,由显存地址关系图可知:由8个偶数/奇数地址的共同一位组成一个数码管的8位显示数据。
  共阳数码管的数据写入比较麻烦,每为一个数码管写入一次数据都要向8个地址分别写入1位数据。例如GRID1~GRID8和SEG1对应共阴LED1,要让其显示0则要00H,02H,04H,06H,08H,0AH都写入1,向0CH和0EH中写入0
  在这里插入图片描述
  共阳方式的优点是可以使用多至10个数码管;缺点啧是数据的写入方式比较繁琐,并且需要额外增加数据转换。


四、TM1638数据格式

  • TM1638的数据读取和发送都在CLK的上升沿进行,因为DIO在时钟的下降沿控制N管动作,此时读数不稳定。
  • TM1638采取低位在前的数据格式,每次发送和读取都是1byte长度,即8位二进制数据
  • 每次STB拉低之后的第一个字节作为指令,处理指令时当前其它处理被终止。

串行数据传输格式
在这里插入图片描述

自增址模式下,只用写入一次地址即首地址,之后依次写入数据,每次写入数据,地址自动增加0X01。数据全部写入之后,上拉STB来作为结束的信号。
在这里插入图片描述

固定址模式下,每次写入数据需要先写入一次地址,为要写入的数据指定写入的地址,之后写入数据,然后上拉STB结束一次写入。
在这里插入图片描述

读数据以拉低STB写入读键值指令(0X42)作为开始,之后TM1638会依次按从低到高的顺序传送4byte的键值数据。读取4byte数据之后上拉STB结束读取。
在这里插入图片描述


五、按键扫描和键扫复用

按键扫描电路
  电路的连接方式如下图,Kn端作为列线,KSn端作为行线,当有键按下被扫描到,数据被存入键值寄存器。
在这里插入图片描述

按键扫描时在端口上的波形:
在这里插入图片描述

按键复用
  SEG1/KS1~SEG8/KS8是复用的端口,作为显示输出同时作为键扫输出端口。当存在按钮同时按下时,如S1,S2,SEG1和SEG2相当于被短路,此时D1,2D两个LED都会被点亮,从而造成显示错误。
  解决方法之一是在每个按键上串联一个二极管,如下图所示,也可以换成510Ω大小的电阻。
  在这里插入图片描述


六、完整代码

1.tm1638.c

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-05-09     IBM       the first version
 */
#include "tm1638.h"
#include "gpio.h"

/*=====================================================### 全局变量定义 ####=================================================*/
uint8_t  segmented[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};       // 段码值
uint16_t buffer[8] = {0};            // 数据缓冲器
uint8_t  sendData[16] = {0};         // 发送数据缓冲区
/*=====================================================#######  END  #######=================================================*/

/*=====================================================### 静态函数调用 ###==================================================*/
/**
 * @brief TM1638发送数据
 * @param DATA:数据
 */
static void TM1638_Write(uint8_t DATA)
{
    uint8_t i;

    for (i = 0; i < 8; i++)     // 1Byte 8位数据
    {
        TM1638_CLK_LOW;         // 拉低时钟线

        if (DATA & 0x01)        // 发送数据
        {
            TM1638_DIO_HIGH;
        }
        else
        {
            TM1638_DIO_LOW;
        }

        DATA >>= 1;             // 数据格式:低位在前
        TM1638_CLK_HIGH;        // 拉高时钟线,写入数据
    }
}

/**
 * @brief TM1638发送命令
 * @param cmd
 */
static void TM1638_WriteCOM(uint8_t cmd)
{
    TM1638_STB_LOW;             // 拉低片选线
    TM1638_Write(cmd);          // 写命令
    TM1638_STB_HIGH;            // 拉高片选线
}

/**
 * @brief 单个数码管显示值
 * @param lednum :数码管编号 1 - 9
 * @param value  :显示的值 0 - 9
 * @param decimal:是否带小数点  0 - 不带  1 - 带
 */
static void LED_Display_value(uint8_t lednum, uint8_t value, uint8_t decimal)
{
    uint8_t i;

    for (i = 0; i < 8; i++)
    {
        if (segmented[value] & (0x01 << i))
        {
            buffer[i] |= (0x01 << (lednum - 1));
        }
    }

    if (decimal == 1)
    {
        buffer[7] |= (0x01 << (lednum - 1));
    }
}

/**
 * @brief u16数据转成u8数据
 */
static void Data_U16_To_U8(void)
{
    for (int i = 0; i < 16; i += 2)
    {
        sendData[i] = buffer[i / 2];
        sendData[i + 1] = buffer[i / 2] >> 8;
    }
}

/**
 * @brief 发送数据到数码管
 */
static void Send_Data_To_LED(void)
{
    TM1638_STB_LOW;                          // 拉低片选线,开始写数据
    TM1638_Write(REG_FIRST_ADDR);            // 写首地址
    for (int i = 0; i < 16; ++i)             // 发数据
    {
        TM1638_Write(sendData[i]);
    }
    TM1638_STB_HIGH;
}

/**
 * @brief 关闭LED数码管显示
 */
static void LED_Close_Display(void)
{
    memset(buffer, 0, sizeof(buffer));
    Data_U16_To_U8();
    Send_Data_To_LED();
}
/*=====================================================#######  END  #######=================================================*/

/*=====================================================##### 外部调用 #####==================================================*/
/**
 * @brief TM1638初始化设置
 */
void TM1638_Init(void)
{
    TM1638_WriteCOM(DATA_CMD_ADDR);          // 设置地址自增
    TM1638_WriteCOM(LED_DISPLAY_ADDR);       // LED亮度设置
}

/**
 * @brief LED数码管显示
 * @param pwr: 输出功率
 * @param pt :输出脉宽
 * @param it :输出时间间隔
 */
void LED_Display_Value(uint16_t pwr, uint16_t pt, uint16_t it)
{
    LED_Close_Display();
    LED_Display_value(1, pwr / 100, 0);
    LED_Display_value(2, pwr % 100 / 10, 0);
    LED_Display_value(3, pwr % 10, 0);
    LED_Display_value(4, pt / 100, 0);
    LED_Display_value(5, pt % 100 / 10, 0);
    LED_Display_value(6, pt % 10, 0);
    LED_Display_value(7, it / 100, 0);
    LED_Display_value(8, it % 100 / 10, 0);
    LED_Display_value(9, it % 10, 0);

    Data_U16_To_U8();       // u16数据转成u8数据
    Send_Data_To_LED();     // 发送数据到数码管
}

/**
 * @brief 测试demo程序
 */
void Test_Demo(void)
{
    LED_Close_Display();
    LED_Display_value(1, 1, 1);
    LED_Display_value(2, 2, 1);
    LED_Display_value(3, 3, 1);
    LED_Display_value(4, 4, 1);
    LED_Display_value(5, 5, 1);
    LED_Display_value(6, 6, 1);
    LED_Display_value(7, 7, 1);
    LED_Display_value(8, 8, 1);
    LED_Display_value(9, 9, 1);

    Data_U16_To_U8();       // u16数据转成u8数据
    Send_Data_To_LED();     // 发送数据到数码管

    for (int i = 0; i < 8; i++)
    {
        printf("buffer[%d]: 0x%x\n", i, buffer[i]);
    }

    for (int i = 0; i < 16; i++)
    {
        printf("sendData[%d]: 0x%x\n", i, sendData[i]);
    }
}
/*=====================================================#######  END  #######=================================================*/

2.tm1638.h

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-05-09     IBM       the first version
 */
#ifndef APPLICATIONS_HARDWARE_INC_TM1638_H_
#define APPLICATIONS_HARDWARE_INC_TM1638_H_

#include <rtthread.h>
#include <drv_common.h>
#include <string.h>

/**====================================================###### 宏定义 ######==================================================*/
#define DATA_CMD_ADDR           0x40               // 写数据、地址自增、普通模式
#define REG_FIRST_ADDR          0xc0               // 寄存器首地址
#define LED_DISPLAY_ADDR        0x8F               // 显示开、亮度8级
#define LED_CLOSE_ADDR          0x80               // 显示关、亮度0级

#define TM1638_STB_HIGH         rt_pin_write(TM1638_STB, SET);      // 片选引脚拉高
#define TM1638_STB_LOW          rt_pin_write(TM1638_STB, RESET);    // 片选引脚拉低
#define TM1638_CLK_HIGH         rt_pin_write(TM1638_CLK, SET);      // 时钟引脚拉高
#define TM1638_CLK_LOW          rt_pin_write(TM1638_CLK, RESET);    // 时钟引脚拉低
#define TM1638_DIO_HIGH         rt_pin_write(TM1638_DIO, SET);      // 数据引脚拉高
#define TM1638_DIO_LOW          rt_pin_write(TM1638_DIO, RESET);    // 数据引脚拉低
/**====================================================#######  END  #######=================================================*/

/**=================================================##### 函数及变量声明 #####===============================================*/
extern void TM1638_Init(void);                                                  // TM1638初始化设置
extern void LED_Display_Value(uint16_t pwr, uint16_t pt, uint16_t it);          // LED数码管显示
extern void Test_Demo(void);                                                    // 测试demo程序
/**====================================================#######  END  #######=================================================*/

#endif /* APPLICATIONS_HARDWARE_INC_TM1638_H_ */


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1988664.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React18+Vite+Eectron从入门到实战系列之一环境安装篇

如果我们的技术栈是react&#xff0c;也想要用electron来开发一个桌面的多端应用该怎么做呢&#xff1f;这篇文章选择了react的技术栈&#xff0c;讲解了环境的初始化步骤 实现效果 步骤 创建 react 项目 npm create vitelatest my-react-app安装依赖 cd my-react-app npm i…

勒索软件、供应链攻击等带来的思考!

2023年勒索软件、供应链攻击、地缘政治冲突与黑客活动主义、国家黑客间谍与APT组织活动成为网络安全的热点话题&#xff0c;生成式人工智能技术的武器化更是给动荡的全球网络安全威胁态势增加了不确定性、不对称性和复杂性。 即将到来的2024年&#xff0c;随着网络犯罪的规模化…

基于卷积神经网络ResUnet 多模态融合实验、BraTS 3d数据集(nii.gz)4模态融合分割

1、前言 之前介绍了unet对BraTS 3d数据集的2d图片分割&#xff0c;实现思路如下&#xff1a; 1、对BraTS 3d数据集进行切片&#xff0c;沿着某个模态的横断面切割 2、划分数据集、包括训练集、验证集等等 3、网络训练 4、评估模型性能等等 具体的可以参考本文&#xff1a;…

黑丝或者白丝,都可以用LoRA(Stable Diffusion进阶篇:ComfyUI 附加网络)

前言 在学习WebUI的那些基础知识点的时候&#xff0c;有一个东西是每一个初学者都绕不开的大山-附加网络。 这个东西对于每一个接触Stable Diffusion的小伙伴来说就像是小学门口小卖部卖的辣条、初中课本上的涂鸦、高中数学卷解不开的最后一道大题。 学习过WebUI里Stable Di…

基础岛 - 8G显存验证书生·浦语大模型的Demo

因为以前用过LMDeploy&#xff0c;所以本章的内容相对熟悉。 另外&#xff0c;因为教程写的很详细保姆级&#xff0c;所以大多数情况直接复制执行命令即可。开发机的创建略过。 总体验证结论&#xff1a; LMDeploy的模型加载有点慢&#xff0c;但推理速度快&#xff0c;符合预…

将tsx引入vue

按钮 vue <cl-batch-btn >新增批量</cl-batch-btn> import batch from "//modules/ad/components/ uploading/batch.vue" import ClBatchBtn from "/~/crud/src/components/batch-btn"; tsx

从困境到突破,EasyMR 集群迁移助力大数据底座信创国产化

在大数据时代&#xff0c;企业对数据的依赖程度越来越高。然而&#xff0c;随着业务的不断发展和技术的快速迭代&#xff0c;大数据平台的集群迁移已成为企业数据中台发展途中无法回避的需求。在大数据平台发展初期&#xff0c;国内数据中台市场主要以国外开源 CDH、商业化 CDP…

JVM(十二)细谈JVM类加载的各个过程以及如何修改Java原生API

本文深入探讨了Java虚拟机&#xff08;JVM&#xff09;的类加载机制&#xff0c;包括类的加载、验证、准备、解析和初始化等过程。文章首先通过几个高级面试问题引入主题&#xff0c;然后详细解释了JVM类加载的五个阶段及其重要性。接着&#xff0c;介绍了Java的三个主要类加载…

普通话测试前如何抱佛脚拿高分

全国普通话水平测试对很多大学生而言是最好拿证的考试&#xff0c;当然了对于某些专业的考生也会有更高的拿证要求&#xff0c;例如对于需要考教师资格证的同学而言。希望这篇文章可以帮助到各位考生在普通话水平测试中取得高分。 首先我们需要知道考试考什么 一、测试内容 …

M.2接口

接口分类 key-a key-b key-e key-m接口图片

图吧工具箱:硬件检测的一站式解决方案,好用到让同行都点赞!

前言 嘿&#xff0c;各位硬件迷们&#xff0c;小江湖又来啦&#xff01;今天&#xff0c;我手里可是攥着个宝贝&#xff0c;一个能让你们眼前一亮的神秘工具箱&#xff1b;别急着问是啥&#xff0c;我先卖个关子&#xff0c;就说这工具箱啊&#xff0c;简直是硬件界的“八卦炉”…

8.C基础_指针基础

指针概述 指针存放的都是首地址。 1、定义与初始化 形式&#xff1a;<数据类型>* <变量名> <地址>; int a 10; int *p &a; 指针的类型不同&#xff0c;p时的偏移地址量不同&#xff0c;偏移地址 sizeof(类型)Byte 注意点&#xff1a; 指针的…

LMS4124R-13000S01激光测距仪使用方法【sick LMS4124R-13000S01】

1、下载SOPAS&#xff1a; 点击下载SOPAS 1 SOPAS 自动搜索设备 正常上电及网络连接&#xff0c;打开 SOPAS 自动搜索到 LMS41XXX&#xff0c;并且可以看到其版本号&#xff0c; SN,IP 信息&#xff0c;产品默认 IP 为 192.168.0.1. 2 搜索设备 鼠标双击“LMS41XXX(SN 18460…

15.DMDIS 工具优化

文章目录 前言一、安装部署安装数据源转换作业监控 二、性能优化问题 1 &#xff1a;DMETL 卡顿问题问题 2 &#xff1a;DM -> HIVE 的迁移速度慢问题 3 &#xff1a;ORACLE -> DM 的迁移速度慢问题 4 &#xff1a;GP -> DM 的迁移速度慢问题 5 &#xff1a;DM -> …

AI芯片成本压力影响利润

Supermicro&#xff08;SMCI&#xff09;近日公布的季度业绩低于预期&#xff0c;主要因其生产的最新人工智能&#xff08;AI&#xff09;芯片服务器成本高企&#xff0c;导致经调整后的毛利率未能达到分析师的预期水平。这一消息使得其股价在盘后交易中急剧下跌14%&#xff0c…

江科大/江协科技 STM32学习笔记P19

文章目录 TIM编码器接口编码器接口简介正交编码器编码器接口电路、基本结构工作模式 TIM编码器接口 改写旋转编码器计次程序&#xff0c;通过定时器的编码器接口自动计次&#xff0c;与之前触发外部中断手动计次相比&#xff0c;节约软件资源&#xff0c;当有电机高速旋转时&a…

邮件推送接口如何集成以提升用户通知效率?

邮件推送接口的优化策略有哪些&#xff1f;如何设计邮件API接口&#xff1f; 邮件推送接口的集成在这一过程中发挥了重要作用&#xff0c;能够显著提升用户通知效率。AokSend将探讨如何通过集成邮件推送接口来优化用户通知机制&#xff0c;从而为企业和用户带来更高的价值。 …

Java并发—ReetrantLock详解

目录 一、ReetrantLock的特性 1、非阻塞获取锁 2、带超时的锁获取: 3、锁的公平性 4、锁的可中断性 5、Condition条件变量 6、锁的可重入性 可重入锁 不可重入锁 7、性能优化 二、ReentrantLock和Synchronized的区别 1、语法和使用方式 2、锁的获取和释放 3、高级…

量化方法介绍

一、定义 分类模型量化接口进阶量化支持的模式/流/硬件 二、实现 分类 模型量化接口进阶 https://pytorch.org/docs/stable/quantization-support.html 2.1 算子融合 定义&#xff1a; 将多个算子融合到一起&#xff0c;运算时可以加快运行速度。 import torch # define a…

三星和Nvidia在HBM3E芯片领域的竞争与合作

引言 近期&#xff0c;全球半导体市场的焦点逐渐聚焦在了高带宽内存&#xff08;HBM&#xff09;芯片领域&#xff0c;尤其是三星电子和Nvidia之间的竞争与合作。这两家科技巨头正在为下一代人工智能&#xff08;AI&#xff09;处理器的高性能需求而竞相研发先进的HBM3E存储解决…