普中51单片机教程-3.数码管

本篇主要介绍数码管的知识

简述

(1)理论概述

(2)共阳极和共阴极结构如下:

(3)段码表

(4)段码举例解释

例如在共阳极数码管中,我们要显示0的话,低电平有效,0xC0表示1100 0000,从左往右依次是高位--->低位,即DP--->A,那么0xC0表示数码管对应的abcd ef点亮,就是0

同理共阴极数码管则是高电平有效,0x3F表示0011 1111,也是数码管对应的abcd ef点亮,就是0

上述的要会运算,死记硬背不是长久之计!!!

(5)多个数码管

使用的是四位一体的共阴数码管,我们要选择LED8的话,那么就应该1000 0000

LED1-LED8连接到74HC138译码器,6、4、5端口为使能端,不用管,P22-P24为输入端,

Y0-Y7为输出端,输出低电平有效,如何看是输出低电平有效,还是高电平,一种方法就是看字母的头上带不带着——,带着就是输出低电平有效,还有一种方法就不过多解释,若为低电平有效字母一般都会标着“——"

  4          2         1 

P24     P23     P22          

比如000,那么加起来就是0,就是Y0

010,就是1*2的1次方,就是0+2+0=2,就是Y2

然后对P0进行相应的电平设置,显示要显示的结果

A0-B0以此类推,P00-P07输入什么,LCD0-LCD7就输出什么

3.1静态数码管显示

代码:

第一种

第二种

运用子函数和switch语句

#include <REGX52.H>

void Nixie (unsigned char location,number)
                        //位选和段选
{
    unsigned char choose[16]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D,0x7D, 0x07,0x7F, 0x6F, 0x77, 0x7C,0x39, 0x5E, 0x79, 0x71};//0-F

    switch(location)
    {
        case 1:P2_4=1;P2_3=1;P2_2=1;//Y7
                        break;
        case 2:P2_4=1;P2_3=1;P2_2=0;//Y6
                        break;
        case 3:P2_4=1;P2_3=0;P2_2=1;//Y5
                        break;
        case 4:P2_4=1;P2_3=0;P2_2=0;//Y4
                        break;
        case 5:P2_4=0;P2_3=1;P2_2=1;//Y3
                        break;
        case 6:P2_4=0;P2_3=1;P2_2=0;//Y2
                        break;
        case 7:P2_4=0;P2_3=0;P2_2=1;//Y1
                        break;
        case 8:P2_4=0;P2_3=0;P2_2=0;//Y0
                        break;
    }
    
    P0=choose[number];
}

void main()
{
    Nixie(1,4);
    while(1)
    {
    }
}

标红的变量定义不能放在switch后面,在 C 语言中,变量的定义必须在当前作用域的开头。

效果如下:

数码管静态显示

3.2动态数码管显示

原理:

因此要进行消影

代码:

#include <REGX52.H>

void Delay(unsigned int xms)//延时函数
{
    unsigned char i, j;
    while(xms--)
    {
    i = 2;
    j = 199;
    do
    {
        while (--j);
    } while (--i);
    }
}


void Nixie (unsigned char location,number)
                        //位选和段选
{
    unsigned char choose[16]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D,0x7D, 0x07,0x7F, 0x6F, 0x77, 0x7C,0x39, 0x5E, 0x79, 0x71};//0-F

    switch(location)
    {
        case 1:P2_4=1;P2_3=1;P2_2=1;//Y7
                        break;
        case 2:P2_4=1;P2_3=1;P2_2=0;//Y6
                        break;
        case 3:P2_4=1;P2_3=0;P2_2=1;//Y5
                        break;
        case 4:P2_4=1;P2_3=0;P2_2=0;//Y4
                        break;
        case 5:P2_4=0;P2_3=1;P2_2=1;//Y3
                        break;
        case 6:P2_4=0;P2_3=1;P2_2=0;//Y2
                        break;
        case 7:P2_4=0;P2_3=0;P2_2=1;//Y1
                        break;
        case 8:P2_4=0;P2_3=0;P2_2=0;//Y0
                        break;
    }
    
    P0=choose[number];
    Delay(1);
    P0=0x00;//清零

}

void main()
{
    while(1)
    {
        //位选 段选 清零 新的位选 段选 清零 
        Nixie(1,5);
        //Delay(2000);
        Nixie(2,2);
        //Delay(2000);
        Nixie(3,0);
        //Delay(2000);
    }
}

效果如下:

数码管动态显示

好的,我来为您介绍如何使用中C51单片机实验板结合数码管显示、定时器中断和按键功能,并使用Keil5编写相关代。 1. 硬件连接: -数码管的段选引脚连接到单片机的P0口 -数码管的位选引脚连接到单片机的P2口 - 将按键连接到单片机的P3.2口(INT0) 2. 主要功能实现: - 使用定时器0中断实现数码管动态扫描显示 - 使用外部中断0检测按键按下 - 在中断服务程序中更新显示内容 3. 示例代: ```c #include <reg52.h> #define uint unsigned int #define uchar unsigned char sbit key = P3^2; // 按键连接到P3.2 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; uchar dispbuf[4] = {0,0,0,0}; uchar dispbit = 0; void delay(uint ms) { uint i,j; for(i=ms;i>0;i--) for(j=110;j>0;j--); } void Timer0_Init() { TMOD |= 0x01; // 定时器0,模式1 TH0 = 0xFC; // 1ms定时初值 TL0 = 0x66; ET0 = 1; // 允许定时器0中断 EA = 1; // 允许总中断 TR0 = 1; // 启动定时器0 } void External0_Init() { IT0 = 1; // 设置INT0为边缘触发 EX0 = 1; // 允许外部中断0 EA = 1; // 允许总中断 } void Display() { P2 = 0xFF; // 关闭所有位选 P0 = dispbuf[dispbit]; // 输出段选数据 P2 = ~(0x01 << dispbit); // 打开当前位选 dispbit++; if(dispbit > 3) dispbit = 0; } void Timer0_ISR() interrupt 1 { TH0 = 0xFC; // 重新加载定时值 TL0 = 0x66; Display(); // 调用显示函数 } void External0_ISR() interrupt 0 { delay(20); // 消抖 if(key == 0) { // 按键按下处理 dispbuf[0]++; // 简单示例:显示内容加1 } } void main() { Timer0_Init(); External0_Init(); while(1) { // 主循环中可添加其他逻辑 } } ``` 这段代实现了以下功能: 1. 定时器0初始化为模式1,每1ms产生一次中断。 2. 外部中断0设置为边缘触发,用于检测按键。 3. 在定时器中断服务程序中调用Display()函数实现数码管动态扫描显示。 4. 在外部中断服务程序中处理按键按下事件,这里简单地将显示内容加1。 5. 主循环保持空闲,所有功能通过中断驱动。 注意:实际应用中可能需要根据具体硬件和需求调整定时器初值、延时时间等参数。同时,为了提高系统稳定性,建议在中断服务程序中只进行简单处理,比如设置标志位,具体功能实现放在主循环中。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值