TM1637四个数码管的驱动

TM1637数码模块

TM1637数码管
目 录
Contents
前言
实验测试
代码
总 结

01 TM1637数码管


一、前言

  手边这个LED数码管, 包括有四个七段数码管。 它的驱动芯片在电路板的背后。 芯片的型号为 TM1637。 下面对其进行测试。 它使用串口进行控制, 电源电压5V。  使用自制 STC32F 单片机进行测试。

GM1687947393_1280_800.MPG|_-5

二、实验测试

  根据TM1637数据手册的介绍, 可以知道它可以支持共阳七段数码管的驱动, 总共可以驱动 8 乘以 6 段。 同时还可以读取 16个按键的状态。  它的接口采用与 I2C 总结的形式,  可以完成双向数据的传送。  在数据手册后面, 给出了基于 51 单片机的应用范例。 下面就使用这个范例进行测试。

GM1687947959_1280_800.MPG|_-4

  下面, 将LED数码管模块通过面包板接入 STC32F 单片机。 利用它的 P1.0, P1.1 两个管脚 模拟 I2C 总线的 始终和数据端口。  由于STC32F 的端口可以有四种模式,  包括推拉输出、准双向输出、OC输出以及输入, 所以在模拟的 I2C 总线上就没有是踹死上拉 电阻。   通过软件测试可以知道数码管的每一段点亮与数据位之间的关系。  对应的位如果是 1 则相应的 LED 段点亮,  由此可以得到 0 到 9 各个数码对应的编码。 这个表格给出了 每个数字对应的编码。

GM1688007266_1280_800.MPG|_-9

▲ 图1.2.1 点亮的对应BIT

扫描二维码关注公众号,回复: 15490166 查看本文章
▲ 图1.2.1 点亮的对应BIT

▲ 图1.2.2 0-9数字编码

▲ 图1.2.2 0-9数字编码

  这里需要说明一下, 原来数据手册中给出的程序实例中存在的一个问题。  由于现在实验平台所使用的单片机 为 STC32F 单片机, 它的运行速度非常快。 所以在原来程序中, I2C 的 始终数据线变低之后, 紧接着改变数据位, 在STC32F 单片机下, 这其中时间延迟不够。  造成 数码管无法正确接收到数据位的状态。  因此,需要在 CLK 变成 0 之后,  增加一个延迟指令, 这样便可以正确实现 I2C 通讯协议。  经过修改之后,  数码管便可以正常进行显示了。  这里给出了测试结果。

GM1688008742_1280_800.MPG|_-9

三、代码

/*
**==============================================================================
** TM1637.C:             -- by Dr. ZhuoQing, 2023-06-28
**
**==============================================================================
*/

#include "STC32F.H"
#include "intrins.h"
#include "stdio.h"
#include "MAIN.H"
#include "c251basic.h"
#include "control.h"
#include "STC32FX.H"
//------------------------------------------------------------------------------
#define TM1637_GLOBALS        1              // Define the global variables
#include "TM1637.H"

//------------------------------------------------------------------------------

void TM1637Init(void) {
    
    
    ON(TM1637_CLK);
    ON(TM1637_DIO);
    PM_PP(TM1637_CLK);
    PM_PP(TM1637_DIO);
    
    g_ucTM1632DoubleDot = 0x0;
}

//------------------------------------------------------------------------------
void TM1637DelayUS(unsigned int i) {
    
    
    unsigned char j;
    for(; i > 0; i --) {
    
    
        for(j = 0; j < 20; j ++)
            _nop_();
    }
}

void TM1637I2CStart(void) {
    
    
    ON(TM1637_CLK);
    ON(TM1637_DIO);
    TM1637DelayUS(2);
    OFF(TM1637_DIO);
}

void TM1637I2CAsk(void) {
    
    
    unsigned int i;
    
    PM_BIDIR(TM1637_DIO);    
    ON(TM1637_DIO);
    
    OFF(TM1637_CLK);
    TM1637DelayUS(5);
        
    for(i = 0; i < 1000; i ++) {
    
    
        if(VAL(TM1637_DIO) == 0) break;
        TM1637DelayUS(10);
    }    
    
    ON(TM1637_CLK);
    TM1637DelayUS(2);
    OFF(TM1637_CLK);
    
    PM_PP(TM1637_DIO);
}

void TM1637I2CStop(void) {
    
    
    OFF(TM1637_CLK);
    TM1637DelayUS(2);
    OFF(TM1637_DIO);
    TM1637DelayUS(2);
    ON(TM1637_CLK);
    TM1637DelayUS(2);
    ON(TM1637_DIO);
}

//------------------------------------------------------------------------------
void TM1637I2CWriteByte(unsigned char oneByte) {
    
    
    unsigned char i;
    for(i = 0; i < 8; i ++) {
    
    
        OFF(TM1637_CLK);
        TM1637DelayUS(2);
        if(oneByte & 0x1) {
    
    
            ON(TM1637_DIO);            
        } else OFF(TM1637_DIO);
        
        TM1637DelayUS(1);
        oneByte = oneByte >> 1;
        ON(TM1637_CLK);
        TM1637DelayUS(3);
    }    
}

unsigned char TM1637ScanKey(void) {
    
    
    unsigned char rekey, i;
    
    TM1637I2CStart();
    TM1637I2CWriteByte(0x42);               // Read key command
    TM1637I2CAsk();
    
    ON(TM1637_DIO);
    PM_BIDIR(TM1637_DIO);
    
    for(i = 0; i < 8; i ++) {
    
    
        OFF(TM1637_CLK);
        rekey = rekey >> 1;
        TM1637DelayUS(30);
        ON(TM1637_CLK);
        if(VAL(TM1637_DIO)) {
    
    
            rekey = rekey | 0x80;
        }
        
        TM1637DelayUS(30);        
    }
    
    TM1637I2CAsk();
    TM1637I2CStop();
    
    PM_PP(TM1637_DIO);
    return rekey;
}

void TM1637Display(unsigned char * pSeg) {
    
    
    unsigned char i;
    
    TM1637I2CStart();
    TM1637I2CWriteByte(0x40);               //  40H : Address auto inc
    TM1637I2CAsk();
    TM1637I2CStop();
    
    TM1637I2CStart();
    TM1637I2CWriteByte(0xc0);
    TM1637I2CAsk();
    
    for(i = 0; i < 6; i ++) {
    
    
        TM1637I2CWriteByte(*(pSeg + i));
        TM1637I2CAsk();
    }
    
    TM1637I2CStop();
    TM1637I2CStart();
    TM1637I2CWriteByte(0x8f);               // Open display, maximum light
    TM1637I2CAsk();
    TM1637I2CStop();
    
}

//------------------------------------------------------------------------------
unsigned char Num2Seg(unsigned char ucNum) {
    
    
    if(ucNum == 0x0)            return 0x3f;
    else if(ucNum == 0x1)       return 0x06;
    else if(ucNum == 0x2)       return 0x5B;
    else if(ucNum == 0x3)       return 0x4F;
    else if(ucNum == 0x4)       return 0x66;
    else if(ucNum == 0x5)       return 0x6D;
    else if(ucNum == 0x6)       return 0x7D;
    else if(ucNum == 0x7)       return 0x07;
    else if(ucNum == 0x8)       return 0x7F;
    else if(ucNum == 0x9)       return 0x4F;
    else return 0;
}

//------------------------------------------------------------------------------
void TM1637ShowInt16(unsigned int nNumber) {
    
    
    unsigned char ucSeg[4];

    ucSeg[3] = Num2Seg((unsigned char)(nNumber % 10));
    nNumber /= 10;
    ucSeg[2] = Num2Seg((unsigned char)(nNumber % 10));
    nNumber /= 10;
    ucSeg[1] = Num2Seg((unsigned char)(nNumber % 10)) | g_ucTM1632DoubleDot;
    nNumber /= 10;
    ucSeg[0] = Num2Seg((unsigned char)(nNumber % 10));
    
    TM1637Display(ucSeg);
}

//------------------------------------------------------------------------------

//==============================================================================
//                END OF FILE : TM1637.C
//------------------------------------------------------------------------------
/*
**==============================================================================
** TM1637.H:            -- by Dr. ZhuoQing, 2023-06-28
**
**  Description:
**
**==============================================================================
*/
#ifndef __TM1637__
#define __TM1637__
//------------------------------------------------------------------------------
#ifdef TM1637_GLOBALS
   #define TM1637_EXT
#else
   #define TM1637_EXT extern
#endif // TM1637_GLOBALS
//------------------------------------------------------------------------------

#define TM1637_CLK      1,1
#define TM1637_DIO      1,0

//==============================================================================
void TM1637Init(void);

//------------------------------------------------------------------------------
void TM1637DelayUS(unsigned int i);
void TM1637I2CStart(void);
void TM1637I2CAsk(void);
void TM1637I2CStop(void);
void TM1637I2CWriteByte(unsigned char oneByte);
unsigned char TM1637ScanKey(void);
void TM1637Display(unsigned char * pSeg);

//------------------------------------------------------------------------------
unsigned char Num2Seg(unsigned char ucNum);
void TM1637ShowInt16(unsigned int nNumber);

TM1637_EXT unsigned char g_ucTM1632DoubleDot;

#define TM1637_DOUBLEDOT_SET        (g_ucTM1632DoubleDot = 0x80)
#define TM1637_DOUBLEDOT_CLEAR      (g_ucTM1632DoubleDot = 0x00)

//==============================================================================
//             END OF FILE : TM1637.H
//------------------------------------------------------------------------------
#endif // __TM1637__

  结 ※


  文测试了利用 STC32F 通过模拟 I2C 端口来驱动TM1637数码管功能。 根据STC32F运行速度快, 调整了 I2C模拟时序的长短, 完成了TM1637的控制命令的传输。

GM1688009586_1280_800.MPG|_-2


■ 相关文献链接:

● 相关图表链接:

猜你喜欢

转载自blog.csdn.net/zhuoqingjoking97298/article/details/131442665