dmm666 发表于 2015-11-27 11:18:48

【分享】做个4位数码管显示系统时间的小实验

材料:树莓派2 b
面包板
跳线
4位共阳数码管

4位共阳数码管的引脚图:
(主要关注数字编号1-12的顺序,以及数字编号对应的字母编号的位置,即哪段led亮哪段灭搞清楚,DP就是小数点啦);


派2的40pin引脚图:
(使用 gpio readall 命令获得,依赖wiringPi库,安装方法查百度,主要看的是wPi的引脚编号)



软件方面我采用的是wiringPi C库(下文有完整源码);
根据以上的两张截图就可以连接硬件了:
数码管和树莓派的连线对应关系如下:

数码管段数字编号 -》数码管段字母编号 -》小派wPi引脚编号
1 ——》E——》21
2——》D——》22
3——》DP——》23
4——》C——》24
5——》G——》25
7——》B——》0
10——》F——》2
11——》A——》3

(共阳端口的链接)
数码管数字编号 -》wPi引脚编号
6——》26
8——》27
9——》28
12——》29

连接完上图一张,凑合着看吧:



连完所有的线,启动树莓派,写程序:
首先你要安装wiringPi开发库环境,百度一搜就会了,这里略过。

下面是源码:
居然不能回复可见,还是算了 (⊙o⊙)…
// 4位共阳数码管驱动程序
// 文件:led4display.c
// 作者:Jason
// Q1165175299 欢迎交流学习
#include <wiringPi.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

// 数值0-9对应的7段控制信号
// 由于共阳,1表示熄灭该段,0表示点亮该段
// 数组第二维0-6分别表示7段的A-G
const int value = {
    { 0,0,0,0,0,0,1 }, //0
    { 1,0,0,1,1,1,1 }, //1
    { 0,0,1,0,0,1,0 }, //2
    { 0,0,0,0,1,1,0 }, //3
    { 1,0,0,1,1,0,0 }, //4
    { 0,1,0,0,1,0,0 }, //5
    { 0,1,0,0,0,0,0 }, //6
    { 0,0,0,1,1,1,1 }, //7
    { 0,0,0,0,0,0,0 }, //8
    { 0,0,0,0,1,0,0 }//9
};

// 7个段的wPi GPIO引脚映射
// 下标0-6表示段A-G,元素分别表示A-G的wPi引脚编号
// 实际硬件连线就按这个关系连接
const int pin = { 3,0,24,22,21,2,25 };

// 4个共阳端的引脚映射
// 0-3分别表示从左往右4个数字位
// 数码管引脚6,8,9,12分别对应wPi引脚26,27,28,29
const int com = { 29,28,27,26 };

// 数码管的小数点wPi引脚号
const int pin_dot = 23;

// 函数头定义
char *get_system_time(void);

// usage: led4display
// example: led4display 1234 1011
// 主函数无错误检测,参数1、2必须都是4位数字
int main(int argc, char *argv[])
{
    char *num = NULL, dots[] = "1011";
    int i = 0, init = 0, seg = 0; // seg为7个段
    int count = 0, delay_time = 5;

    /*
    if (argc != 3) {
    printf("usage: led4display \n");
    printf("4 nums like 1234 to display number 1234\n");
    printf("4 dots like 1011, dot form left to right means off-on-off-off\n");
    exit(1);
    }
    */

    if (wiringPiSetup() == -1) {
    printf("wPi init fail\n");
    exit(2);
    }

    /*
    num = argv;
    dots = argv;
    */
    num = get_system_time();
    //dots = "1011"

    // initalize for all pins OUTPUT
    for (init = 0; init < 7; init++) {
    pinMode(pin, OUTPUT);
    }
    for (init = 0; init < 4; init++) {
    pinMode(com, OUTPUT);
    }
    pinMode(pin_dot, OUTPUT);

    while (1){
    // display
      for (i = 0; i < 4; i++) {
      // every 20s to get sys time
      if (count % (20000/delay_time) == 0){
      num = get_system_time();
      count = 0;
      }
      // firstly, empty 4 numbers
      for (seg = 0; seg < 7; seg++) {
      digitalWrite(pin, HIGH);
      }
      digitalWrite(pin_dot, dots - 48);
      // 打开第i个数码管的共阳端
      digitalWrite(com, HIGH);
      for (seg = 0; seg < 7; seg++) {
      // 打开数码管的段, 减48,把字符转换成数值(ASCII编码)
      digitalWrite(pin, value - 48]);
      }
      // 打开数码管的小数点
      digitalWrite(pin_dot, dots - 48);
      // 显示完一个数字后关闭显示
      delay(delay_time);
      count++;
      digitalWrite(com, LOW);
    }
    }

    return 0;
}

// get time
char *get_system_time(void)
{
    static char timestr;
    time_t t;
    struct tm *nowtime;

    time(&t);
    nowtime = localtime(&t);
    strftime(timestr, sizeof(timestr), "%H%M", nowtime);

    return timestr;
}
源码写好保存,开始编译,一条命令搞定了:
gcc -Wall -I/usr/local/include -L/usr/local/lib -lwiringPi -o led4display led4display.c
// 编译参数你可以 man 去查看,简单说下,-Wall显示所有警告,-I、-L分别指定了包含文件和库,-lwiringPi 这个很重要一定要加




运行啦:
sudo ./led4display


是不是看到数码管显示当前系统时间了?
截图呢?额,在上文已经放过了。。。。
看了下运行起来不会闪,程序cpu负载小于1%,应该可以了。




mouse_ox 发表于 2015-11-27 18:28:40

进来看看!!
页: [1]
查看完整版本: 【分享】做个4位数码管显示系统时间的小实验