单片机C语言实现数码管控制

发布者:泉地水无痕最新更新时间:2018-05-07 来源: eefocus关键字:单片机  C语言  数码管控制 手机看文章 扫描二维码
随时随地手机看文章

数码管作为人机接口的重要显示部件,广泛应用于各行各业。本文将围绕数码管的原理和使用展开讨论,实验内容也是由浅入深,结合C语言特性,着意于在实验中掌握数码管和C语言知识。文章采用与单片机C语言实现独立按键检测与矩阵键盘操作同样的开发板。以下先给出数码管的电路原理图。


上图中的4个数码管为共阳极数码管。数码管实际是由8个发光二极管组成的,而共阳极是指将这8个二极管的正极连接到一个公共端。所以当这8个二极管的任何一个负极通低电平的时候,相应的二极管就会被点亮,相反,通高电平则灭。详细请参照以下原理图。


图中任取一个数码管,有a, b, c, d, e, f, g, p分别代表组成该数码管的发光二极管。当要该数码管显示0到9之间任一数字的时候,要给每一个二极管不一样的电平(0或1),8个二极管分别由P0口的8个I/O口控制,P0口的控制输出即为段码。

上面说的是单个数码管的显示,然后我们有四个数码管,怎么选择我要用哪个数码管呢?回到数码管原理图,可以看到数码管底下的DIG口分别连接到4个驱动三极管,并最终由P2口的4个端子来控制。这样就可以选择哪个数码管工作,譬如希望最左侧数码管亮,我们称其为千位数码管(因为有4个数码管,分别代表个十百千),则只需给P2.0口送低电平。

实验一

好了,现在就来做个实验,实验目标是使千位数码管显示数字6。直接上代码。

#include "reg51.h"  

 //char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

 code char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

 sbit QIAN = P2^0; //QIAN表示千位  

 void main()  

 {  

    P0 = seg[6];  

    QIAN = 0;  

    while(1)  

    {  

          

    }  

 }  

程序中,显示定义了段码,进入main函数后,先给P0口数字6的显示段码,再选通千位数码管,这样千位数码管就顺利地显示6。这里我们重点讲解seg数组。

char seg[10]


10:10个数连续存放。


seg:代表了第一个数的首地址。


char:每个数最大值不超过255,即一个内存单元(如果定义成int则每个数要占用两个内存单元)。


但是这10个数存在哪呢?


有两种方法。第一种也就是当我们采用char seg[...]={...}这种定义方法时,程序下载烧到ROM后,当下次上电时候,程序会自动将这数组拷贝到RAM。第二种当定义成code char seg[...]={...}时候,程序下载烧到ROM后,内核只从ROM中读取,并不通过RAM。这样的好处是节省了内存资源,但同时程序执行时seg数组也不能被更改。


实验二


接下来我们要使4个数码管都显示,本例显示1234。直接上代码:

#include "reg51.h"  

 //char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

 code char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

 sbit QIAN = P2^0;  

 char i;  

 char smgbuf[4]={1,2,3,4}; //从RAM的smgbuf这个地址开始连续存放4个数,并且每个数占一个单元。  

  

 void delay(unsigned int x)  

 {  

    while(x)   //注意这里不是1  

    {  

        x--;  

    }     

 }  

  

 void load_smg()   //将数码管显示缓冲区的数据,显示到数码管上  

 {  

    char i;  

    for(i=0;i<4;i++)   

    {  

        P0=0xFF;   //消除上一个循环的影子,因为i每一次叠代时,数码管都会有上一次叠代的痕迹,0xFF则是使所有数码管灭掉。  

        P0 = seg[smgbuf[i]];  

        P2 = ~(1<

        delay(200);  

    }  

 }  

  

 void main()  

 {  

    while(1)  

    {  

        load_smg();  

    }  

 }  

实验三

下面我们希望用四个数码管显示一个可变的数字,这个数字记录了程序执行进入main函数的次数。还是直接上代码(为了方便代码管理,拆分代码到main.c和smg.c):


main.c文件



#include "reg51.h"  

unsigned int count;  

extern void load_smg();  

  

void main()  

 {  

    int a;  

    while(1)  

    {  

        load_smg();  

        a++;  

        if(a>=200)  

        {  

            count++;  

            a=0;              

        }  

    }  

 }  

smg.c文件


 #include "reg51.h"   

  //char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

 code char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

 char i;  

 char smgbuf[4]={1,2,3,4}; //从RAM的smgbuf这个地址开始连续存放4个数,并且每个数占一个单元。  

 sbit QIAN = P2^0;  

 extern unsigned int count; //外部申明  

  

 void delay(unsigned int x)  

 {  

    while(x)     

    {  

        x--;  

    }     

 }  

  

void fill_smgbuf() //向LED缓冲区填充数据  

{  

    smgbuf[0]=count/1000;  //千位,我们希望千位数码管来显示数字的千位  

    smgbuf[1]=(count%1000)/100;  //百位  

    smgbuf[2]=((count%1000)%100)/10;   //十位  

    smgbuf[3]=((count%1000)%100)%10;   //个位  

}  

  

void load_smg()   //将缓冲区的数据,显示到数码管上  

 {  

    char i;  

    fill_smgbuf();  

    for(i=0;i<4;i++)   

    {  

        P0=0xFF;    

        P0 = seg[smgbuf[i]];  

        P2 = ~(1<

        delay(200);  

    }  

 }  

实验四

接下来我们要引入独立按键控制数码管上的数字加1(K1键)或减1(K2键)。还是上代码:

main.c文件


#include "reg51.h"  

  

extern void load_smg();  

extern delay(unsigned int x);  

extern void key1();  

extern void key2();  

  

unsigned int count;  

  

void main()  

 {  

    while(1)  

    {  

        load_smg();  

        key1();  

        key2();  

    }  

 }  

smg.c文件


 #include "reg51.h"   

  //char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

 code char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

 char smgbuf[4]={1,2,3,4};   

 extern unsigned int count;   

  

 void delay(unsigned int x)  

 {  

    while(x)     

    {  

        x--;  

    }     

 }  

  

void fill_smgbuf()   

{  

    smgbuf[0]=count/1000;    

    smgbuf[1]=(count%1000)/100;    

    smgbuf[2]=((count%1000)%100)/10;     

    smgbuf[3]=((count%1000)%100)%10;     

}  

  

void load_smg()     

 {  

    char i;  

    fill_smgbuf();  

    for(i=0;i<4;i++)   

    {  

        P0=0xFF;     

        P0 = seg[smgbuf[i]];  

        P2 = ~(1<

        delay(200);  

    }  

 }  

key.c文件


#include "reg51.h"  

extern delay(unsigned int x);  

extern unsigned int count;  

sbit K1=P2^4;  //+1  

sbit K2=P2^5;   //-1  

  

void key1()  

{  

    static char st;  

    if(K1==0)  

    {  

        if(st==0)  

        {  

            delay(5000);  

            if(K1==0)  

            {  

                st=1;  

                count++;  

            }  

        }  

    }  

    else  

    {  

        st=0;  

    }  

}  

  

void key2()  

{  

    static char st;  

    if(K2==0)  

    {  

         if(st==0)  

         {  

            delay(5000);  

            if(K2==0)  

            {  

                st=1;  

                count--;  

            }  

         }  

    }  

    else  

    {  

        st=0;  

    }  

}  

这个实验有一个地方需要注意,即每当复位,按K2键,数码管显示535。这是因为开机后程序默认count值为0,即16个0。当按下K2键后,减1,变成负1。而负1在内存中为16个1(负数的补码为其绝对值的原码取反再加1),又因为count定义为unsigned,所以显然count为65535。65535再被1000除,得到了535。


总结:

1、掌握数的分离方法,例如求出5678的个十百千位。


2、C语言数组是数据批量处理的基础。


3、尝试分别用四个键去控制个十百千四个数码管的闪烁。


关键字:单片机  C语言  数码管控制 引用地址:单片机C语言实现数码管控制

上一篇:51单片机的LED与数码管的驱动
下一篇:单片机:按键(使用中断)控制数码管的数字加减(c语言实

推荐阅读最新更新时间:2024-03-16 16:01

基于CAN控制器的对等式单片机多机系统的通信
    摘要: 针对单片机多机系统主从式通信的缺点,提也了利用CAN控制器实现单片机多机系统对等式通信,并对其硬件组成原理、通信程序的设计做了详细的分析。     关键词: 单片机多机系统 “对等式”通信 控制器局域网(CAN) 关于单片机的多机通信,许多文章及相关书籍都有介绍,但就其多机通信的方式而言大多为“主从式”,这一通信方式限制了单片机功能的发挥及广泛的应用。虽然文献 利用巧秒的硬件手段实现了单片机多机之间的“对等式”通信,但其通信方式实质上仍是“主从式”。本文介绍了一种基于CAN控制器的单片机多机系统,从本质上实现了任意两机之间直接相互通信,从而克服了“主从式”多机通信的缺点。 1 CAN技术简
[网络通信]
单片机专用系统的系统程序构成
专用系统是指利用微处理器构成的具有特定功能的系统,它是针对某个特定的功能专门设计的。近年来随着计算机技术的发展,使家用电器到形形色色的工控系统、通信系统的智能化成为可能。这些系统采用微处理器或微控制器构成智能系统,即在一个电子系统中内含微处理器或微控制器进行系统的信息处理和控制。由于在系统中,微处理器仅作为一个部件,因而将其称为嵌入式处理器。   专用系统的设计包括了系统的硬件设计和软件设计。   专用系统的硬件设计是根据专用系统的功能要求选择硬件设备,设计硬件设备的接口电路,并分配其地址。除此之外,还需根据系统对存储器的需要选择程序存储器和数据存储器的容量并分配地址。   专用系统的软件即系统程序包含了程序区、数据区和堆栈区等部分
[单片机]
基于STM32单片机的DLP驱动电路研究
DLP投影技术是应用美国德州仪器公司开发的数字微镜元件--DMD(Digital Micromirror Device)作为主要关键处理元件以实现数字光学处理过程的技术。DLP显示的色彩清晰度高、艳丽、细腻、逼真,且为全数字显示即可靠性极高,能在各类产品(如大屏幕数字电视、公司/家庭/专业会议投影机和数码相机(DLP Cinema))中提供最佳图像效果。目前,大部分的家用或商用DLP投影机都采用了单片结构,使得其便于移动携带,因而得到越来越广泛的应用。在目前应用发展的基础上,又对其结构的精简性、携带的方便性提出了更高的要求。传统的DLP投影仪是通过DVI接口接收外部信号,并且经过信号转换传送给DLP控制器来控制DLP的显示,占用的
[单片机]
基于STM32<font color='red'>单片机</font>的DLP驱动电路研究
单片机4x4矩阵键盘扫描程序
采用反转法判断按键坐标,即行号与列号获得按键码。 写完后发现Proteus一个问题:直接使用这样的if(P10xf0!=0xf0)语句时,调不出来,当用了一个中间变量过渡时,就调出来了,害我花了一个上午的时间,现在暂时不知道Proteus为什么要这样,实际中是不需要的。 程序如下: #include #define uchar unsigned char #define uint unsigned int void delayMS(unsigned int z); uchar keyscan(void); void main(void) { uchar key; while(1)
[单片机]
用ZHX1010实现单片机之间的红外通信
摘要:ZHX1010是ZiLOG公司的红外收发芯片,该芯片在1米范围内的最高速度可达115.2kbps,2.4V~5.5V的宽电源范围可使其与各种电压的CPU进行方便的接口。文中介绍了ZHX1010的特点、结构和使用方法,并给出了它与AT89C51的接口应用。 关键词:红外通信 单片机 ZHX1010 引言 目前的单片机应用系统之间一般都使用UART进行通信,通过电平转换口将信号变成RS232或RS485信号来进行直接通信。这种有线通信的好处是通信误码率比较低,受干扰的机率相对较少,但对于要经常插拔通信 线的系统来说,有线通信反而容易出现故障。笔者在开发织机控制系统时,要用一个手持式编程器来修改控制系统的工作参数。在实际使用
[工业控制]
PIC单片机延时问题
#include p18f45k22.h //时间函数的测试  非定时器的使用  软件仿真 调试debug的使用 //在watch当中可以添加特殊功能寄存器和变量等 #define uint unsigned int  #define uchar unsigned char void delayChar(uchar n);//uchar的取值在0~256之间  否则溢出  void delayInt(uint n);//使用时尽量在对时间要求不精确时使用 void main(void){ ANSELA=0; TRISAbits.RA0=0; PORTAbits.RA0=1; delayChar(5); PORTAbits.RA0=
[单片机]
单片机51多任务的操作系统原理
  想了很久,要不要写这篇文章?最后觉得对操作系统感兴趣的人还是很多,写吧。我不一定能造出玉,但我可以抛出砖。   包括我在内的很多人都对51使用操作系统呈悲观态度,因为51的片上资源太少。但对于很多要求不高的系统来说,使用操作系统可以使代码变得更直观,易于维护,所以在51上仍有操作系统的生存机会。   流行的uCos,Tiny51等,其实都不适合在2051这样的片子上用,占资源较多,唯有自已动手,以不变应万变,才能让51也有操作系统可用。这篇贴子的目的,是教会大家如何现场写一个OS,而不是给大家提供一个OS版本。提供的所有代码,也都是示例代码,所以不要因为它没什么功能就说LAJI之类的话。如果把功能写全了,一来估计你也不
[单片机]
51单片机中变量的定义及应用方法
变量就是一种在程序执行过程中其值能不断变化的量。要在程序中使用变量必须先用标识符作为变量名,并指出所用的数据类型和存储模式,这样编译系统才能为变量分配相应的存储空间。定义一个变量的格式如下: 在定义格式中除了数据类型和变量名表是必要的,其它都是可选项。存储种类有四种:自动(auto),外部(extern),静态(statIC)和寄存器(register),缺省类型为自动(auto)。 而这里的数据类型则是和我们在第四课中学习到的名种数据类型的定义是一样的。说明了一个变量的数据类型后,还可选择说明该变量的存储器类型。存储器类型的说明就是指定该变量在C51硬件系统中所使用的存储区域,并在编译时准确的定位。注意的是在AT89C51芯
[单片机]
51<font color='red'>单片机</font>中变量的定义及应用方法
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved