鱼C论坛

 找回密码
 立即注册
查看: 827|回复: 9

[学习笔记] 51单片机 静态/动态数码管

[复制链接]
发表于 2023-1-19 09:15:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 Mike_python小 于 2023-1-19 09:17 编辑

51单片机 静态/动态数码管

数码管在我们的生活中非常常见,但是这节课可能有点不一样
你需要学习2进制转16进制(1248码)
和10进制转2进制(短除法)

1248码
比如我有一串2进制,10100010,使用1248码转换16进制就应该这么写:
WechatIMG199.jpeg
1248码从右向左写
二进制先写右边的,依次对应
如果二进制不从右向做写的话,可能出现以下问题:
101001
WechatIMG201.jpeg
第一个结果是29,而第二个是A4

在16进制中,A代表着10,B代表着11,以此类推

总结
1248和二进制从右向左写,最后读数正读

短除法
10进制转2进制的短除法非常简单
比如我要短除23这个数
WechatIMG203.jpeg
先用23/2=11余1
然后以此类推
到1/2=0余1的时候也就结束了

最后从下往上读,结果就是10111

我们一般采用第二种写法,第一种是方便大家理解

静态数码管
说了这么多了,该说说静态数码管了
截屏2023-01-19 07.55.56.png
这是一个数码管的原理图,上面是共阳,下面是共阴,我用的数码管就是共阴的

共阴极:当某个发光二极管的阳极为高电平时,发光二极管点亮,相应的段被显示。
共阳极:将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。

如右图所表,数码管上的8个小部分分别对应着几个IO口,所以我们只需要接通他们相对应的IO口,就可以实现点亮

比如我想点亮一个6,就需要知道abcdefg dp中需要哪个给1
AFGCDE,这几个点亮就可以变成一个6
所以我们看右图这几个对应的引脚
74219 10,把这几个引脚点亮就行了(PS:点亮需要给16进制,这里的太乱了,我懒得算了,等后面再算)

但是这只是一个数码管啊,我们的是4个连城一体的啊
截屏2023-01-19 08.42.46.png
看到这么多先不要着急,听我慢慢到来
首先左边的那些我们都不用看,只看两个大黄色的数码管就可以

这个数码管跟我们看到的一个的数码管很想,从下方都截出来了abcdefg dp这8个引脚,但是有一个问题,我们这8个数码管练成一体了,怎么就出来8条线(1一个数码管的线)?不应该是8x8=64条线吗?!

厂家为了减少IO口,就用了以下的方法:

看没看见每个数码管上方的LED8,LED7等等?这就是妙处

我们想要点亮比如说LED8的abcd,我们先给LED8一个1,就表明我们只要点亮led8,其他的是熄灭的,然后再把abcd点亮就行了~

如何把abcd点亮
我们把abcd点亮和单个数码管的一样,需要给abcd “1”,其他的 “0”
截屏2023-01-19 08.49.10.png
再从下网上数就是00001111,转化为16进制就是 0x0F

再看左侧,引脚都是P01,P02,P03,这时候我们采用统一赋值,给P0 = 0x0F
就可以把abcd点亮了

如何把LED8点亮
截屏2023-01-19 08.50.54.png
看这张图的右边,LED8对应着Y7,LED6对应着Y6,LED5对应着Y5

再看这张图的左边,有P22, P23, P24

这是有就有人要说了,为什么8个数码管用3个IO口就能控制????

好问题,这也是节省IO口的妙用

3个IO口正好可以表现0~7的10进制,比如P22, P23, P24都为1的时候就是7,都为0的时候就是0

那要控制LED7就是111,从下网上读对应的就是P24是1,P23也是1,P22也是1

那要控制LED6呢?就是110, P24是1,P23是1,P22就是0了
注意!二进制第一位要对应P24而不是P22

通过代码实现
#include <8052.h>
void main() {
    P2_4=1;
    P2_3=1;
    P2_2=1;

    P0 = 0x7D;
    while (1) {

    }


}

这里,我给大家总结了一个库,你们直接调用这个库就行
nixie.c
#include "Sleep.h"
#include <8052.h>

char num[18] = {
    0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
    0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x00
};

void Nixie(unsigned char weizhi, unsigned char number) {
    P2 &= ~0x1c;
    P2 |= (~weizhi & 0x07) << 2;
    /*
    switch (weizhi) {
        case 1:
            P2_4 = 1;
            P2_3 = 1;
            P2_2 = 1;
            break;
        case 2:
            P2_4 = 1;
            P2_3 = 1;
            P2_2 = 0;
            break;
        case 3:
            P2_4 = 1;
            P2_3 = 0;
            P2_2 = 1;
            break;
        case 4:
            P2_4 = 1;
            P2_3 = 0;
            P2_2 = 0;
            break;
        case 5:
            P2_4 = 0;
            P2_3 = 1;
            P2_2 = 1;
            break;
        case 6:
            P2_4 = 0;
            P2_3 = 1;
            P2_2 = 0;
            break;
        case 7:
            P2_4 = 0;
            P2_3 = 0;
            P2_2 = 1;
            break;
        case 8:
            P2_4 = 0;
            P2_3 = 0;
            P2_2 = 0;
            break;
    }
    */
    // 因为这个number所表示的含义有点乱
    // 要改这个switch就得改number所表示的含义
    switch (number) {
        case 0: P0 = num[0]; break;
        case 1: P0 = num[1]; break;
        case 2: P0 = num[2]; break;
        case 3: P0 = num[3]; break;
        case 4: P0 = num[4]; break;
        case 5: P0 = num[5]; break;
        case 6: P0 = num[6]; break;
        case 7: P0 = num[7]; break;
        case 8: P0 = num[8]; break;
        case 9: P0 = num[9]; break;
        case 'A': P0 = num[10]; break;
        case 'B': P0 = num[11]; break;
        case 'C': P0 = num[12]; break;
        case 'D': P0 = num[13]; break;
        case 'E': P0 = num[14]; break;
        case 'F': P0 = num[15];
        case ' ': P0 = num[16];
    }
    Sleep(2);
    P0 = 0x00;
}
这里要感谢@人造人 大佬

然后你们添加一个头文件
nixie.h
#ifndef __NIXIE_H__
#define __NIXIE_H__

void Nixie(unsigned char weizhi, unsigned char number);

#endif
之后直接调用这个库就行

比如说我想要在3处显示9
直接
Nixie(3, 9);
想在2处显示空
Nixie(2, ' ');
想在5处显示A
Nixie(5, 'A');

大家也可以自己丰富一下

动态数码管
因为厂家为了减少IO口,这8个数码管中不能同时打开,那怎么办呢?

利用数码管的余晖和人眼的残影保留,快速的开关开关数码管,欺骗人眼实现全部显示

在nixie库中我就已经做好了动态需要的步骤了
也就是最后的
    Sleep(2);
    P0 = 0x00;
sleep2是为了不要太快,不然就会有很明显的上一个的残影
P0=0x00也是为了消除数码管上次太多的残影

完整代码是这样的
#include <8052.h>
// #include "../Sleep.h"
#include "../nixie.h"



void main() {
    // P2_4=0;
    // P2_3=0;
    // P2_2=1;
    P2 = 0x00;
    

    while (1) {

        Nixie(1, 4);

        Nixie(2, 6);

        // Sleep(3);
        // P2_2 = 0;

    }


}
dong.jpeg

这节课有点难理解,建议去看看江科大的视频
如果有什么不理解的地方或者我有什么错误,请联系我

也可以在我的博客里看哦~https://cxwindlight.online/

评分

参与人数 3荣誉 +8 鱼币 +8 收起 理由
傻眼貓咪 + 5 + 5 感谢楼主无私奉献!
liuhongrun2022 + 2 + 2 加油!(虽然我看不懂)
MIke_python小小 + 1 + 1 无条件支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-1-19 09:19:10 | 显示全部楼层
AUV,评个分回回血吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-19 09:19:40 | 显示全部楼层
AUV
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

头像被屏蔽
发表于 2023-1-19 09:20:28 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-19 09:20:51 | 显示全部楼层
Python_tkinter 发表于 2023-1-19 09:20
AUV,您吉祥~我们北京没有马路,全是地道~

AUV吃了吗您
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-19 09:21:19 | 显示全部楼层

要一盘西红柿炒鸡蛋(模糊)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-19 09:46:37 | 显示全部楼层
改成这样试试
#include "Sleep.h"
#include <8052.h>

static unsigned char code[17] = {
    0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
    0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x00
};

void Nixie(unsigned char addr, unsigned char number) {
    if(number >= 17) return;
    P2 &= ~0x1c;
    P2 |= (~addr & 0x07) << 2;
    P0 = code[number];
    Sleep(2);
    P0 = 0x00;
}

// main.c
unsigned char i;
for(i = 0; i < 17; ++i) {
    Nixie(0, i);
    Sleep(1000);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2023-1-19 09:50:35 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-19 09:55:21 | 显示全部楼层
所以说,你这14-15行是什么意思,去掉
#include "Sleep.h"
#include <8052.h>

static unsigned char code[17] = {
    0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
    0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x00
};

void Nixie(unsigned char addr, unsigned char number) {
    if(number >= 17) return;
    P2 &= ~0x1c;
    P2 |= (~addr & 0x07) << 2;
    P0 = code[number];
}

// main.c
unsigned char i;
for(i = 0; i < 17; ++i) {
    Nixie(0, i);
    Sleep(1000);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-19 10:16:30 | 显示全部楼层
#include "Sleep.h"
#include <8052.h>

static unsigned char code[17] = {
    0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
    0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x00
};

void Nixie(unsigned char addr, unsigned char number) {
    if(number >= 17) return;
    P0 = 0x00;      // 消影
    P2 &= ~0x1c;
    P2 |= (~addr & 0x07) << 2;
    P0 = code[number];
}

// main.c
unsigned char i;
for(i = 0; i < 17; ++i) {
    Nixie(0, i);
    Sleep(1000);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 19:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表