原创 第十六课 按键之二 独立按键之按键计数

2009-6-2 15:42 4044 5 5 分类: MCU/ 嵌入式

第十六课 按键之二 独立按键之按键计数


程序讲解:


/*--------------------------------------------------------------*/
//LED八位数码滚动显示
//显示部分用中断方式,便于程序的拓展



/*--------------------------------------------------------------*/
//包含头文件
#include <reg52.h>
#include "74HC595.H"    //数码管驱动


//对应开发板端口
sbit K1 = P3^2;
sbit K2 = P3^3;
sbit K3 = P3^4;
sbit K4 = P3^5;



//全局变量定义
unsigned char LED_Pos;   //位扫描
unsigned char LED_Seg[8] = {16,16,16,16,16,16,16,16};    //每位数码管要显示的数据缓存
unsigned int  x;



/*--------------------------------------------------------------*/
//定时器初始化 前面讲的比较多了这里就简单提下
void T0_init(void)                    
{
    TMOD = 0x01;       //定时器0工作在方式1
    TH0  = 0xf8;           //2000us
    TL0  = 0x36;
    IE   = 0x82;             //开总中断和定时器 1中断
    TR0  = 1;                //允许定时器0工作
}


/*--------------------------------------------------------------*/
void delay10ms(void)
{
    unsigned char i,j;
    for(i=201;i>0;i--)
    for(j=32;j>0;j--);
}



/*--------------------------------------------------------------*/
//LED显示函数2
volatile void LED_Display2(void)
{
    Ser_IN(0x80 >> LED_Pos);              //位选  每次选中一位
    Ser_IN(seg[LED_Seg[LED_Pos]]);    //段选  数组seg[]是段码,在74HC595.H"头文件里面 
    Par_OUT();                                        //产生上升沿 锁存输出


   LED_Pos++;                                       //循环扫描
   if(LED_Pos == 8) LED_Pos = 0;         //LED_Pos控制位选和段选
}



/*--------------------------------------------------------------*/
//更新数据LED_Seg[8] (每位数码管要显示的数据 )
volatile void Display_pro(void)
{
 unsigned char i;
 unsigned int temp;
 i = 0;
 temp = x;
 while(temp/10)                   //判断temp是否为个位数,不是则进入while()循环进行处理
 {
  LED_Seg = temp%10;   //取最低位(个位)送到i对应的数码管位
  temp /= 10;                        //temp右移一位,百位变十位,十位变个位,个位消失(减小10倍)
  i++;                                  //指向下位数码管数据
 }
 LED_Seg = temp;           //最高位
 i++;
 while(i < 8) LED_Seg[i++] = 16;   //若高位为0则不显示,16 在数码管段码表数组(seg[])里面的段码为全灭
}


 


/*--------------------------------------------------------------*/
//中断显示
//定时器中断服务
void T0_intservice(void) interrupt 1
{
    TH0 = 0xf8;
    TL0 = 0x36;
    LED_Display2();
}



/*-------------------------------------------------------------*/
//主函数
void main(void)
{
 bit inc;
 bit dec;


 T0_init(); 
 while(1)
 {
  if (K1 == 0){delay10ms(); if(K1 == 0) x++; while(K1 == 0);}    //手动加
  if (K2 == 0){delay10ms(); if(K2 == 0) x--; while(K2 == 0);}      //手动减
  if (K3 == 0){delay10ms(); if(K3 == 0) inc = ~inc;while(K3 == 0);} //开启(关闭)自动加
  if (K4 == 0){delay10ms(); if(K4 == 0) dec = ~dec;while(K4 == 0);}  //开启(关闭)自动减
  if(inc) x++;           //自动加
  if(dec) x--;            //自动减
  Display_pro();      //将要显示的数据写入到缓存
 }
}


本节重点:
1、数码管要显示数据的更新。
    Display_pro();这个函数即实现了这个功能,比方说数码管要显示的数据室543210,这个函数就可以把0送到数据缓冲区数组(LED_Seg[8] )的最低位(从右至左的第一位),1送到次低位(从右至左的第二位),以此类推。543210只有六位数据,实验板上有8位数码管显然高两位没有要显示的数据,此时利用语句 while(i < 8) LED_Seg[i++] = 16; 即可让高两位关闭显示。这样就实现了数码管显示数据的更新。大家可以慢慢体会一下这个子函数!



2、Display_pro();函数处理数据的过程。
    首先判断要显示的数据是否为个位数,是个位数,则直接去他的个位数,将它送到LED_Seg (此时i = 0)就是将数据送到最右(低位)边的那个数码管显示。若不是个位数则进入while()进行处理,首先去要显示数据的最低位,送到LED_Seg (此时i = 0),然后将要显示的数据 temp减小10倍(百位变十位,十位变个位,个位消失)供十位数据的缓存。若 temp减小10倍的temp为个位数了,就执行 LED_Seg = temp;此时 i = 1;即将要显示的数据的十位送到了第二位数码管(从右至左)。百位数、千位数依次类推!


注:写的比较繁琐,就是实现数码管要显示数据的更新!


演示视频:


http://v.youku.com/v_show/id_XOTIzNjI1NTY=.html


相关程序:https://static.assets-stash.eet-china.com/album/old-resources/2009/5/31/8a32a946-1e1b-417b-b47e-cf80f0c1a8f2.rar



 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
5
关闭 站长推荐上一条 /3 下一条