05_基于wiringPi的数码管驱动编写

目的:

       通过数码管案例,熟悉TM1650芯片的使用方法,加深树莓派的IIC接口使用方法。

目录

1、基础知识

1.1、LED数码管基础知识

1.2、TM1650芯片介绍

 1.3、树莓派上IIC的接口使用方法

1.3.1、头文件

 1.3.2、初始化设备ID的函数

1.3.3、读取设备节点值的函数

1.3.4、给设备节点写值的函数

1.3.5、给设备节点的某一个寄存器写值

1.3.6、读取设备节点某一个寄存器的值

2、功能实现

2.1、原理图

2.2、代码实现

 2.2.1、头文件实现

2.2.2、宏定义

2.2.3、TM1650初始化

2.2.4、数码管显示函数

2.2.5、主函数

2.3、生成执行程序

2.4、功能实现


1、基础知识

1.1、LED数码管基础知识

LED数码管(LED Segment Displays)由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。数码管实际上是由七个发光管组成8字形构成的,加上小数点就是8个。这些段分别由字母a,b,c,d,e,f,g,dp来表示。

LED数码管根据LED的接法不同分为共阴和共阳两类,比如我们使用的共阴数码管原理图如下:

图1-1 共阴极数码管原理图

 另外的一种共阳极数码管原理图如图1-2 所示。

图1-2 共阳极数码管原理图

       无论是共阴极还是共阳极数码管,都拥有段引脚和位引脚,其中段引脚用于设定数码管要显示的内容,位引脚用于选择需要显示哪一位数字。如果要在不同的位显示不同的数字,则每次只能有一个位被选中,并在段引脚中送入相应的数据。那我们现在看到的数码管是如何做到在同一时间不同位显示不同的数字的呢?

       这就用到了数码管动态扫描显示的技术,该技术利用了人类视觉系统的暂留性,实际程序显示的时候,是先显示其中一位,然后关闭这位的显示,但由于刷新的频率太高,即使某位的显示关闭了,显示的图像还会在视觉系统中短暂停留,所以,如果数码管轮流以超过50Hz的刷新率显示,人眼是分辨不出来某一位数码管关闭了,这样看起来就像所有的数码管都在显示不同的内容。

1.2、TM1650芯片介绍

      TM1650 是一种带键盘扫描接口的 LED(发光二极管显示器)驱动控制专用电路。内部集成有 MCU,输入输出控制数字接口、数据锁存器、LED 驱动、键盘扫描、辉度调节等电路。

       本次案例使用的是TM1650的数码管驱动功能,原理图如下:

 图1-3 TM1650典型电路

        TM1650可以使用I2C的方式通信,本次案例的控制命令一共用到两条,一是进入模式设置,二是通过下表设定TM1650的模式,并注意要打开显示。

a、数据命令设置

数据命令设置
B7B6B5B4B3B2B1B0说明
01001000模式命令
01001xx1读按键数据命令

b、显示命令设置

MSBLSB
B7B6B5B4B3B2B1B0功能说明

0

000

无关项,

填0

辉度设置8级亮度
0011级亮度
0102级亮度
0113级亮度
1004级亮度
1015级亮度
1106级亮度
1117级亮度
07/8段显示控制位8段显示方式
17段显示方式
0开启/关闭显示位关显示
1开显示

c、显存地址

        在显示的时候,往相应的显存地址写入数据,数据格式参考上表,若要数码管的其中一段亮,就给这段置1.

 1.3、树莓派上IIC的接口使用方法

参考官方的链接:I2C Library | Wiring Pi

1.3.1、头文件

使用IIC接口的之前需要添加头文件

#include <wiringPiI2C.h>

 1.3.2、初始化设备ID的函数

 int wiringPiI2CSetup (int devId) ;

返回设备节点

1.3.3、读取设备节点值的函数

int wiringPiI2CRead (int fd) ;

1.3.4、给设备节点写值的函数

int wiringPiI2CWrite (int fd, int data) ;

1.3.5、给设备节点的某一个寄存器写值

写1个字节
int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;

写2个字节
int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;

1.3.6、读取设备节点某一个寄存器的值

读取一个字节数据
int wiringPiI2CReadReg8 (int fd, int reg) ;

读取两个字节数据
int wiringPiI2CReadReg16 (int fd, int reg) ;

2、功能实现

         通过树莓派实现数码管上的数字跳动。

2.1、原理图

 图2-1 数码管原理图

通过接线 数码管接在了树莓派的I2C-1端口上。

2.2、代码实现

     通过IIC工具的到TM1650的设备地址为0x24;0x34,0x35,0x36,0x37分别对应第1到4位数码管显示寄存器的地址。因此,编写代码的时候,首先往设备地址0x24中写入相应命令,然后往数码管显示寄存器写入要显示的内容即可。

i2cdetect -y 1

 图2-2 TM1650IIC地址

 2.2.1、头文件实现

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <wiringPiI2C.h>

2.2.2、宏定义

#define u8 unsigned char
#define uint16_t unsigned short
#define u32 unsigned int

//# TM1650 分开的地址,分别对应一个指令地址和4个4位数字的显示地址
#define  COMMAND_I2C_ADDRESS     0x24
#define  DISPLAY_I2C_ADDRESS_1   0x34
#define  DISPLAY_I2C_ADDRESS_2   0x35
#define  DISPLAY_I2C_ADDRESS_3   0x36
#define  DISPLAY_I2C_ADDRESS_4   0x37

#define  TIM_COMMAND					0x24 //数据命令
#define  TIM_START					    0x01 //默认开启显示位

#define  data_dp 						0x80 //小数点的段码
#define  data_null					    0x00 //不显示
#define  data_neg						0x40 //负号的段码

2.2.3、TM1650初始化

int tm1650init(void)
{
    wiringPiSetup();
    fd = wiringPiI2CSetup (COMMAND_I2C_ADDRESS);
    if(fd < 0)
    {
        printf("COMMAND_I2C_ADDRESS IIC初始化失败\r\n");
        return fd;
    }
    fd1 = wiringPiI2CSetup (DISPLAY_I2C_ADDRESS_1);
    if(fd1 < 0)
    {
        printf("DISPLAY_I2C_ADDRESS_1 IIC初始化失败\r\n");
        return fd1;
    }
    
    fd2 = wiringPiI2CSetup (DISPLAY_I2C_ADDRESS_2);
    if(fd2 < 0)
    {
        printf("DISPLAY_I2C_ADDRESS_2 IIC初始化失败\r\n");
        return fd2;
    }
        
    fd3 = wiringPiI2CSetup (DISPLAY_I2C_ADDRESS_3);
    if(fd3 < 0)
    {
        printf("DISPLAY_I2C_ADDRESS_3 IIC初始化失败\r\n");
        return fd3;
    }
    
    fd4 = wiringPiI2CSetup (DISPLAY_I2C_ADDRESS_4);
    if(fd4 < 0)
    {
        printf("DISPLAY_I2C_ADDRESS_4 IIC初始化失败\r\n");
        return fd4;
    }

    wiringPiI2CWrite (fd,display_brightness[6]);
    wiringPiI2CWrite (fd1,data_null);
    wiringPiI2CWrite (fd2,data_null);
    wiringPiI2CWrite (fd3,data_null);
    wiringPiI2CWrite (fd4,data_null);
    return 0;
}

2.2.4、数码管显示函数

int showDigit(u8 d1, u8 d2,u8  d3, u8 d4)
{
    wiringPiI2CWrite (fd1,digitCode[d1]);
    wiringPiI2CWrite (fd2,digitCode[d2]);
    wiringPiI2CWrite (fd3,digitCode[d3]);
    wiringPiI2CWrite (fd4,digitCode[d4]);
    return 0;
}

2.2.5、主函数

int main(void)
{
    u8 d1,d2,d3,d4;
    u8 ret;
    u32 i=0;

    ret = tm1650init();
    if(ret != 0)
    {
        printf("tm1650init init error \r\n");
        return -1;
    }

    for(;;)
    {
         d4 = i % 10;
         d3 = (i/10) % 10;
         d2 = (i/100) % 10;
         d1 = (i/1000) % 10;
         showDigit(d1, d2, d3, d4);
         delay(1000);
         i += 1;
     }

    return 0;
}

2.3、生成执行程序

      编译的时候需要添加wiringPi库,编译步骤如下所示:

gcc -Wall -o tm1650 tm1650.c -lwiringPi

图2-3 编译过程

2.4、功能实现

执行程序

./tm1650

 实现数码管的数字跳变。

 图2-4-1 数码管数字变化

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值