共阳数码管段码表_从51单片机到Linux Linux操控数码管(教程6)

369dac94ac577927d53739295f51a394.png

大家好,我是兔子。

是一个嵌入式软硬件工程师。

正在从单片机开发转岗Linux开发。

这次,上一节,我们把流水灯点亮了。这一节,我们再来控制数码管,让数码管显示我们需要的数字。

1.操作大纲

1)使用上一节编写的gpio驱动,即gpio_driver.ko(i.MX283及i.MX287也一样,驱动配置稍微调整)。

加载驱动。

2)看原理图,知道如何得知数码管是共阳还是共阴。如何通过锁存器74HC595控制。

3)写数码管程序。

4)开发板运行数码管,观看效果。

2.调整驱动及驱动编译

使用上一节编译好的gpio驱动gpio_driver.ko,直接在开发板上加载驱动即可。

(如果对gpio驱动不清楚的,可以移步教程5)

兔子MCU:从51单片机到Linux Linux操控流水灯(教程5)​zhuanlan.zhihu.com
95ce8f52f9dd94d1f60caf1250586cef.png

需要通过NFS共享文件服务传输到开发板中加载。

(如果对NFS服务不清楚,可以移步教程3)

兔子MCU:从51单片机到Linux 开发板传文件利器-NFS(教程3)​zhuanlan.zhihu.com
95ce8f52f9dd94d1f60caf1250586cef.png

1)首先先开启NFS服务,将虚拟机的共享文件夹挂载在开发板的/mnt目录下

2)使用cd /mnt命令,进入/mnt目录

3)使用ls命令,看到是否有gpio驱动文件,即gpio_driver.ko。发现有的。

4)使用insmod gpio_driver.ko加载驱动。

5)可以看到后面打印了很多文件信息,表示驱动加载成功。

31fc6e0993699cac80ab9b30762e13d0.png

3.看原理图接线

首先看的是扩展板上的数码管部分的原理图。

可以看到是使用了3根线,通过控制2片74HC595锁存器芯片,来间接控制数码管。和很多的51开发板一样的电路。

483edff3f83b695029f6a6f2472ace7d.png

1)确认数码管是共阳还是共阴数码管。

原理图上已经注明数码管型号,是LN3461BS。

兔子我在搜索引擎上搜索一番,就有人告诉我是共阳的。

7e5e2d5f52a36c927f085aeec4f5bafe.png

共阳就是表示:数码管段选位给高电平,位选位给低电平。对应的数码管就能被点亮。

2)接入跳线

一共用到3根线。一个是数据线,一个是时钟线,还有一个是锁存线。

3d2d8441d0884a98b74ca535ae63f7a6.png

原理图上,实际的3根线通过跳线帽是这样接的。

可以得知:

<1>锁存线RCK,在扩展板内是接到了IO3.21电气网络上。

<2>数据线SPI_CLK,在扩展板内是接到了SCK电气网络上。

<3>时钟线SPI_DIN,在扩展板内是接到了MOSI电气网络上。

5c5712afe9f53134ae72109926d26f42.png

可以追根溯源,在扩展板上,最终和主控板相连的3个脚分别为。

IDC-B的4脚(即RCK,锁存线)。

IDC-A的15脚(即SPI_SCK,时钟线)。

IDC-A的16脚(即SPI_DIN,数据线)。

4d99e2ea5e575ed240c5b48093f07954.png

如下图所示,可以看到,最终接到ARM的为

PWM4(锁存线)。

RX2(时钟线)。

TX2(数据线)。

7779ab1fc7636010de3aee8932f9e08a.png

故接线已经分析完成。

(详细的接线分析,可以移步教程5,参考教程5的接线分析)

兔子MCU:从51单片机到Linux Linux操控流水灯(教程5)​zhuanlan.zhihu.com
95ce8f52f9dd94d1f60caf1250586cef.png

4.写数码管程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h> //个人添加,字符转数字
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <limits.h>
#include <asm/ioctls.h>
#include <time.h>
#include <pthread.h>
 
#include "gpio.h"
static int fd_RCK,fd_SPI_DIN,fd_SPI_CLK;
const char code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
 
static void show_help(void)
{
 printf("example:n");
 printf("./gpio_595 0 &n");
 //printf(" gpio_test /dev/gpio-xxx H #set gpio output higth n");
 //printf(" gpio_test /dev/gpio-xxx L #set gpio output low n");
 //printf(" gpio_test /dev/gpio-xxx R #read gpio input status(H/L) n");
}
 
static void data(uint CH,uint num)
{
 int i;
 char tmp_1,tmp_2; 
 ioctl(fd_RCK,SET_GPIO_LOW);
 tmp_1 = code[num];
 tmp_2 = tmp_1 & 0x80;
 for(i=0;i<8;i++)
 {
 if(tmp_2 == 0x80)
 {
  ioctl(fd_SPI_DIN,SET_GPIO_LOW);
  ioctl(fd_SPI_CLK,SET_GPIO_HIGHT);
  //usleep(500);
  ioctl(fd_SPI_CLK,SET_GPIO_LOW);
  //usleep(500);
 }
 else
 {
  ioctl(fd_SPI_DIN,SET_GPIO_HIGHT);
  ioctl(fd_SPI_CLK,SET_GPIO_HIGHT);
  //usleep(500);
  ioctl(fd_SPI_CLK,SET_GPIO_LOW);
  //usleep(500);
 }
 tmp_1 = tmp_1 << 1;
 tmp_2 = tmp_1 & 0x80;
 }
 
 for(i=0;i<8;i++)
 {
 if(i == (8 - CH))
 {
  ioctl(fd_SPI_DIN,SET_GPIO_HIGHT);
  ioctl(fd_SPI_CLK,SET_GPIO_HIGHT);
  //usleep(500);
  ioctl(fd_SPI_CLK,SET_GPIO_LOW);
  //usleep(500);
 }
 else
 {
  ioctl(fd_SPI_DIN,SET_GPIO_LOW);
  ioctl(fd_SPI_CLK,SET_GPIO_HIGHT);
  //usleep(500);
  ioctl(fd_SPI_CLK,SET_GPIO_LOW);
  //usleep(500);
 }
 
 }
 
 ioctl(fd_RCK,SET_GPIO_HIGHT);
}
 
int main(int argc, char *argv[])
{
 int cnt;
 if (argc != 2) {
 show_help();
 return -1;
 }
 
 fd_RCK = open("/dev/gpio-PWM4", O_RDWR);
 if (fd_RCK < 0) {
 printf("faile to open RCK,file :/dev/gpio-RCK n");
 return -1; 
 }
 
 fd_SPI_DIN = open("/dev/gpio-TX2", O_RDWR);
 if (fd_SPI_DIN < 0) {
 printf("faile to open SPI_DIN,file :/dev/gpio-TX2I n");
 return -1; 
 }
 
 fd_SPI_CLK = open("/dev/gpio-RX2", O_RDWR);
 if (fd_SPI_CLK < 0) {
 printf("faile to open SPI_CLK,file :/dev/gpio-RX2 n");
 return -1; 
 }
 
 cnt = atoi(argv[1]);
 
 while(1)
 {
 data(1,cnt / 1000);
 usleep(100);
 data(2,cnt /100 % 10);
 usleep(100);
 data(3,cnt /10 % 10);
 usleep(100);
 data(4,cnt % 10);
 usleep(100);
 } 
 
 return 0;
}

程序说明:

1)open("/dev/gpio-PWM4", O_RDWR);表示打开开发板的/dev目录下的gpio-PWM3文件。O_RDWR表示对这个文件是可读可写操作。

开发板的/dev/gpio-PWM3文件是操作ARM的IO管脚的文件。

(只有加载驱动才会在开发板生成这个文件,故运行数码管程序之前,需要首先加载第2步的驱动)

Linux操作,都是对文件的操作。所以在进行相关操作之前,都是需要open对应的文件。

2)const char code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

为兔子我验证过的数码管显示编码,从0开始到9.共10个编码。

即0x3F对应显示数字0。

3)if (argc != 2) {

show_help();

return -1;

}

表示验证传入程序的参数是否为2个。如果不为2个,则打印帮助信息。

即最终运行,会输入./gpio_595_cmd 2,第一个参数为./gpio_595_cmd。表示运行的程序名称。第二个参数为2,表示数码管显示的数字。范围可以使0~9999)

4)ioctl(fd_SPI_DIN,SET_GPIO_LOW);

Ioctl表示直接操作文件,具体操作需要和驱动对应。这里简单器件直接写明。

SET_GPIO_LOW表示对应的IO输出低电平

SET_GPIO_HIGHT表示对应的IO输出高电平

SET_GPIO_LOW和SET_GPIO_HIGHT是头文件gpio.h里的宏定义。

5)sleep(1);

表示延时1秒(在当前内核2.26.35.3里表示1秒,其他版本内核可能表示为毫秒)

如果想延时小于1秒,可以使用微秒延时函数。

usleep(500*1000);

表示延时500毫秒。

sleep();以及usleep();延时函数推荐使用。因为这不是软件延时,不会占用CPU的资源。

将数码管程序命名为gpio_595_cmd.c存到路径~/XW_Linux/ZLG/2、gpio_driver/test目录下。

同时修改该目录下的数码管应用程序的Makefile。调整如下图所示。

0dcf15ffc70401a9fbf3202486315687.png

然后使用终端,make一下,进行点灯应用程序的编译。

530d471e8377b68acb6c535aa8676178.png

可以看到,无报错。生成的数码管应用文件在bin文件夹里。

将生成的数码管程序和之前的gpio驱动拷贝到NFS共享目录里。

(如何使用NFS共享目录,请移步至教程3)

兔子MCU:从51单片机到Linux 开发板传文件利器-NFS(教程3)​zhuanlan.zhihu.com
95ce8f52f9dd94d1f60caf1250586cef.png

3aecfbfb19189172221139c8727cc854.png

至此,数码管程序编译完成。

5.运行程序

1)开发板上电,并挂载NFS共享目录。

(具体操作可移步教程3)

兔子MCU:从51单片机到Linux 开发板传文件利器-NFS(教程3)​zhuanlan.zhihu.com
95ce8f52f9dd94d1f60caf1250586cef.png

2)进入开发板的NFS挂载点/mnt文件夹下。通过ls命令能查看到我们编译好的点灯程序和驱动。

7e378c0433f8f2dc0a5a775402416f36.png

3)首先,先加载驱动。

使用insmod gpio_driver.ko指令。

11904b11a63eef49106c932a3962f2ae.png

可以看到,打印了很多生成的文件。表示驱动加载成功。

4)运行数码管程序

使用./gpio_595_cmd 234 表示让数码管显示234这个数字。

007c0ec6f1068a7ca4d3f8f81f1c5ff5.png

效果图:

b85331263cf4a8223ab1cdb8c4ba5739.png

至此,数码管程序已经成功使用IO口来控制。

6.效果视频

401b9ab2b165c48ebb4272df5c73659f.png
Linux控制数码管https://www.zhihu.com/video/1121007242144624640

736c821e718ea5b6a4b273275a6908c0.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值