微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 52单片机16路跑马灯按键无效

52单片机16路跑马灯按键无效

时间:10-02 整理:3721RD 点击:

如果能用VR来调节速度就更好了,刚开始学习,望各位前辈多多指教

#include<REG52.H>
#define LED1_8 P0    //左8个LED,起始P0.0对应LED1,依次对应
#define LED9_16 P2   //右8个LED,起始P2.0对应LED9,依次对应
#define _7SEG P1     //7段数码管
#define KEYBOARD P3  //键盘
#define uchar  unsigned char
#define uint unsigned int
uint code SpeedCode[]={1,3,5,7,10,14,18,23,27,32,40,50,65,80,100,120,140,170,200,280,320,360,400,500,600,700,800,900,1000};  //速度码
uchar code LEDDisplayCode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F};  //7段共阴数码管0-8字码
//uchar code LEDDisplayCode[]={0x40,0x79,0x2B,0x30,0x19,0x12,0x02,0x78,0x00};   //7段共阳数码管0-8字码
uchar mode;
uint count,systemSpeed,speedNum,index;
bit direction,flag;
void Delay1ms(uint num)//num ms 延时函数
{
     uint i,j;
     for(i=0;i<num;i++)
         for(j=0;j<125;j++);  //1ms延时
}
void Display(uchar Value)    //数码管驱动函数
{
    _7SEG=LEDDisplayCode[Value];
}
uchar KeyScan(void)     //键盘读入函数
{
    uchar check1,check2,key=0x00;
check1=KEYBOARD&0x07;   //第一次读键盘值
if(check1==0x07)
     return 0x00;
Delay1ms(10);
check2=KEYBOARD&0x07;   //第二次读键盘值
if(check2=check1)     //若两次值相同,无键按下,返回0值
   return 0x00;
if(!(check1&0x01))    //key1键按下
     key|=0x01;
if(!(check1&0x02))    //key2键按下
     key|=0x02;
if(!(check1&0x04))    //key3键按下
     key|=0x04;
    return key;        //返回键值
}
void LEDShow(uint LEDStatus)
{
     LED1_8=~(LEDStatus&0x00FF);
  LED9_16=~((LEDStatus>>8)&0x00FF);
}
void Timer1(void)interrupt 3   //T1 interrupt service routine
{
      if(++count>=systemSpeed) //*利用计数1000次,使用12M晶振时等同计时1ms,当
   //中断次数小于systemSpeed次数时,保持原有跑马运行模式不变,仅当
  // 中断次数超过systemSpeed次数时才改变一次跑马运行模式,同时systemSpeed
   //置0,这就避免了过多使用延时函数,既造成了CPU的资源浪费,又使按键失灵
   //的弊端   */
{
    count=0;
    if(mode==0x00)     //模式0:一个灯亮从左到右跑
    {
       LEDShow(0x0001<<index);
    index=(index+1)%16;
  }
  else if(mode==0x01)  //模式1:一个灯亮从右到左跑
  {
     LEDShow(0x8000>>index);
     index=(index+1)%16;
  }
  else if(mode==0x02)    //模式2:一个灯先从左到右再从右到左
  {
      if(direction)
      LEDShow(0x0001<<index);
   else
      LEDShow(0x8000>>index);
   if(index==15)
      direction=!direction;
      index=(index+1)%16;
  }
  else  if(mode==0x03)  //模式3:全亮后逐个灭,先左右,后右左,然后全部灭逐个亮,先右左,后左右
  {
      if(direction)
   {
     if(flag)
       LEDShow(0xFFFE<<index);
     else
       LEDShow(~(0x7FFF>>index));
    }
    else
    {
       if(flag)
     LEDShow(0x7FFF>>index);
    else
     LEDShow(~(0xFFFE<<index));
     }
     if(index==15)
     {
        direction=!direction;
     if(direction)
        flag=!flag;
      }
   }  
   }
   TH1=0xFC;
   TL1=0x18;    //重载初值
}
void main(void)
{
    uchar key;
/******************************************************/
mode=0x00;
count=0;
index=0;
direction=1;
flag=1;
speedNum=12;   //初始速度
LED1_8=0x00;
LED9_16=0x00;
_7SEG=0xFF;
Delay1ms(1000);
LED1_8=0xFF;
LED9_16=0xFF;
_7SEG=0x00;
KEYBOARD=0xFF;
systemSpeed=SpeedCode[speedNum];
Display(mode);
   /******************************************************/
   TMOD =0x10;    //T1模式
   TH1=0xFC;
   TL1=0x18;  //计数1000个脉冲
   ET1=1;    //允许T1中断
   EA=1;     //开总中断
   TR1=1;    //开T1中断
   /******************************************************/
   while(1)  //死循环不断的读按键的状态,并按键值响应相关状态跑马花样
   {
   key=KeyScan();
   if(key!=0x00)
   {
      if(key&0x01)
   {
      direction=1;
   index=0;
   flag=1;
   mode=(mode+1)%4;    //9中模式循环
   Display(mode);
    }
    if (key&0x02)
    {
      if(speedNum>0)
   {
      speedNum--;
      systemSpeed=SpeedCode[speedNum];
    }
      }
     if(key&0x04)
     {
        if(speedNum<30)
     {
        speedNum++;
     systemSpeed=SpeedCode[speedNum];
      }
   }
  }
    }
}


程序逻辑很清晰,这样看不出问题,你检查是不是硬件电路的问题没?

亲,我感觉是驱动能力不够,你是加上驱动看看

啦啦?

定时器中断里面重装初值不是应在中断一开始就重装吗。

按键未能启动。。

上传仿真和编译文件。
还有咋不去Proteus板块提问呢?
以下是板块的链接
http://bbs.elecfans.com/zhuti_proteus_1.html

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top