1547|2

52

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【国民技术N32WB452测评】第四期、在RT-Thread中使用GPIO驱动数码管 [复制链接]

本帖最后由 yang8555u 于 2022-8-29 02:24 编辑

这阵子由于出差,帖子更新不及时,请见谅。

本期帖子,介绍的是TM1638数码管的经典应用,做一个小型的计数器。TM1638是天马微电子推出的一款芯片,主要用于矩阵键盘、数码管、多路LED灯等应用,在日常生活中应用非常普遍。

根据芯片手册,我使用普通GPIO模拟的方式,驱动TM1638。

代码如下:

TM1638.h

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-08-06     11618       the first version
 */

#ifndef APPLICATIONS_TM1638_H_
#define APPLICATIONS_TM1638_H_
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <stdint.h>
#define THREAD_PRIORITY         25
#define THREAD_STACK_SIZE       2048
#define THREAD_TIMESLICE        5
static rt_thread_t tid1 = RT_NULL;
#define DATA_COMMAND    0X40
#define DISP_COMMAND    0x80
#define ADDR_COMMAND    0XC0


#define    TM1638_DIO   GET_PIN(B, 10)
#define    TM1638_CLK   GET_PIN(E, 13)
#define    TM1638_CS    GET_PIN(B, 12)


//#define  TM1638_CLK_ENABLE()

#define  TM1638_DIO_SET()                   rt_pin_write(TM1638_DIO, PIN_HIGH)
#define  TM1638_DIO_RESET()                 rt_pin_write(TM1638_DIO, PIN_LOW)
#define  TM1638_DIO_READ()                  rt_pin_read(TM1638_DIO)

#define  TM1638_CLK_SET()                   rt_pin_write(TM1638_CLK, PIN_HIGH)
#define  TM1638_CLK_RESET()                 rt_pin_write(TM1638_CLK, PIN_LOW)

#define  TM1638_CS_SET()                    rt_pin_write(TM1638_CS, PIN_HIGH)
#define  TM1638_CS_RESET()                  rt_pin_write(TM1638_CS, PIN_LOW)


void TM1638_init(void);//TM1638初始化函数
void TM1638_Write(unsigned char DATA);  //写数据函数
unsigned char TM1638_Read(void) ;     //读数据函数
void Write_COM(unsigned char cmd);    //发送命令字
void Write_DATA(unsigned char add,unsigned char DATA);   //指定地址写入数据,按地址单独点亮数码内容
void Write_allLED(unsigned char LED_flag);     //控制全部LED函数,LED_flag表示各个LED状态
unsigned char Read_key(void);//读取按键值

#endif /* APPLICATIONS_TM1638_H_ */

TM1638.c


#include <tm1638.h>

#include <rtthread.h>
#include <rtdevice.h>
#include "n32g45x_rcc.h"


void TM1638_init(void)
{
    unsigned char i;
        /*CLK ENABLE*/

        /*GPIO MODE*/
        rt_pin_mode(TM1638_DIO,PIN_MODE_OUTPUT_OD);
        rt_pin_mode(TM1638_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(TM1638_CS,PIN_MODE_OUTPUT);

        Write_COM(0x89);       //亮度 (0x88-0x8f)8级亮度可调
        Write_COM(0x40);       //采用地址自动加1
        TM1638_CS_RESET() ;                 //
        TM1638_Write(0xc0);    //设置起始地址
        for(i=0;i<16;i++)      //传送16个字节的数据
        TM1638_Write(0x40);//数码管显示横杠
        TM1638_CS_SET() ;


}


void TM1638_Write(unsigned char DATA)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        TM1638_CLK_RESET() ;
        if(DATA&0X01)
        TM1638_DIO_SET() ;
        else
        TM1638_DIO_RESET() ;
        DATA>>=1;
        TM1638_CLK_SET() ;
    }
}

unsigned char TM1638_Read(void)
{
    unsigned char i;
    unsigned char temp=0;
    TM1638_DIO_SET() ;
    for(i=0;i<8;i++)
    {
        temp>>=1;
        TM1638_CLK_RESET() ;
        TM1638_DIO_SET() ;
        if(TM1638_DIO_READ())
            temp|=0x80;
        TM1638_CLK_SET() ;
    }
    return temp;
}



void Write_COM(unsigned char cmd)
{
    TM1638_CS_RESET()   ;
    TM1638_Write(cmd);
    TM1638_CS_SET() ;
    rt_thread_mdelay(1);
}


unsigned char Read_key(void)
{
    unsigned char c[4],i;
    unsigned char key_value=0;
    TM1638_CS_RESET()   ;
    TM1638_Write(0x42);
    rt_thread_mdelay(5);
    for(i=0;i<4;i++)
    c=TM1638_DIO_READ();
    TM1638_CS_SET() ;
                //K1
        if(c[0]==0x04) key_value=1;
        if(c[0]==0x40) key_value=2;
        if(c[1]==0x04) key_value=3;
        if(c[1]==0x40) key_value=4;
        if(c[2]==0x04) key_value=5;
        if(c[2]==0x40) key_value=6;
        if(c[3]==0x04) key_value=7;
        if(c[3]==0x40) key_value=8;
                //K2
        if(c[0]==0x02) key_value=9;
        if(c[0]==0x20) key_value=10;
        if(c[1]==0x02) key_value=11;
        if(c[1]==0x20) key_value=12;
        if(c[2]==0x02) key_value=13;
        if(c[2]==0x20) key_value=14;
        if(c[3]==0x02) key_value=15;
        if(c[3]==0x20) key_value=16;
                //K3
        if(c[0]==0x01) key_value=17;
        if(c[0]==0x10) key_value=18;
        if(c[1]==0x01) key_value=19;
        if(c[1]==0x10) key_value=20;
        if(c[2]==0x01) key_value=21;
        if(c[2]==0x10) key_value=22;
        if(c[3]==0x01) key_value=23;
        if(c[3]==0x10) key_value=24;
        return key_value;
}

void Write_DATA(unsigned char add,unsigned char DATA)
{
    Write_COM(0x44);
    TM1638_CS_RESET()   ;
    TM1638_Write(0xc0|add);
    TM1638_Write(DATA);
    TM1638_CS_SET() ;
}


void Write_allLED(unsigned char LED_flag)
{
    unsigned char i;
    for(i=0;i<8;i++)
        {
            if(LED_flag&(1<<i))
                //Write_DATA(2*i+1,3);
                Write_DATA(2*i+1,1);
            else
                Write_DATA(2*i+1,0);
        }
}
void show_data(uint32_t i)
{
    unsigned char shumaguan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
       //                      0    1     2    3    4   5    6     7
                              0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
   //                         8     9   A     B    C    D    E    F
                               0xff                              };


    Write_DATA(0x0,shumaguan[i/ 10000000 % 10]);
    Write_DATA(0x2,shumaguan[i/ 1000000 % 10]);

    Write_DATA(0x4,shumaguan[i/ 100000 % 10]);

    Write_DATA(0x6,shumaguan[i/ 10000 % 10]);
    Write_DATA(0x8,shumaguan[i/ 1000 % 10]);

    Write_DATA(0xa,shumaguan[i/ 100 % 10]);

    Write_DATA(0xc,shumaguan[i/ 10 % 10]);
    Write_DATA(0xe,shumaguan[i % 10]);


}
static void tm1638_collect_thread_entry(void *parameter)
{
    TM1638_init();
    uint32_t i=12345678;

    while(i++)
    {
        show_data(i);

        rt_thread_mdelay(100);
    }
}
int tm1638_send(void)
{
    /* 创建线程*/
    tid1 = rt_thread_create("tm1638_collect_thread", tm1638_collect_thread_entry, RT_NULL, THREAD_STACK_SIZE,
            THREAD_PRIORITY, THREAD_TIMESLICE);

    /* 如果获得线程控制块,启动这个线程 */
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);

    return 0;
}
MSH_CMD_EXPORT(tm1638_send,test)

由代码可见,我们使用gpio模拟的方式,驱动tm1638,并形成一个每0.1秒计数一次的计数器应用。程序下载后,在串口控制台,可以输入tm1638_send,启动tm1638线程,并运行计数器应用。

视频如下:

NS1

 在前面帖子中,有介绍I2C读取温湿度传感器,所以我们可以将其整合起来,便可以使用数码管显示N32WB452板载的温湿度传感器的数据,模拟真实应用场景。

改动代码如下:

//增加show_data函数,用于显示温湿度数据。
void hdc2010_get_data()
{
    read_regs(i2c_bus, HDC2010_TEMPERATURE_LOW, temperature_reg);
    temperature_raw = temperature_reg[0] + temperature_reg[1] * 256;
    temperature = (double) temperature_raw / 65536;
    temperature = temperature * 165 - 40;
    read_regs(i2c_bus, HDC2010_HUMIDITY_LOW, humidity_reg);
    humidity_raw = humidity_reg[0] + humidity_reg[1] * 256;
    humidity = (double) humidity_raw / 65536*100;
    LOG_I("temperature = %d.%d,humidity = %d.%d\n", (int )temperature, (int )(temperature * 10) % 10,(int )humidity, (int )(humidity * 10) % 10);
    show_data(temperature * 10,humidity*10);
}
//改造原来的show_data函数,并增加小数点显示。
void show_data(uint32_t i,uint32_t s)
{
    unsigned char shumaguan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
       //                      0    1     2    3    4   5    6     7
                              0x7f,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
   //                         8     9   A     B    C    D    E    F
                               0xff                              };
    unsigned char shumaguandian[]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,
          //                      0    1     2    3    4   5    6     7
                                 0xFF,0xEF};
      //                         8     9

    Write_DATA(0x0,shumaguan[i/ 100 % 10]);
    Write_DATA(0x2,shumaguandian[i/ 10 % 10]);

    Write_DATA(0x4,shumaguan[i % 10]);

    Write_DATA(0x6,0x40);
    Write_DATA(0x8,shumaguandian[s/ 100 % 10]);

    Write_DATA(0xa,shumaguandian[s/ 10 % 10]);

    Write_DATA(0xc,shumaguandian[s % 10]);
    Write_DATA(0xe,0x40);


}

温湿度显示如下:

NS2

 

此帖出自无线连接论坛

最新回复

感觉楼主的数码管,那真的牛!期待精彩继续!   详情 回复 发表于 2022-8-31 19:30
点赞 关注
 

回复
举报

6828

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

数码管显示还是挺行吧

 

此帖出自无线连接论坛
 
 

回复

7047

帖子

11

TA的资源

版主

板凳
 

感觉楼主的数码管,那真的牛!期待精彩继续!

此帖出自无线连接论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表