目前共有6篇帖子。 內容轉換:不轉換▼
 
點擊 回復
461 5
【C51程序】按键控制数码管,按键时数码管既不闪烁也不熄灭
一派護法 十九級
1樓 發表于:2013-9-21 09:54

【seg.c】

#define DEBUG 0
#include <reg52.h>
#include "ports.h"
unsigned char code seg8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
unsigned int num1=0;
unsigned int num2=8050;
unsigned char ledid=0;
unsigned char interval=0;
unsigned char num3=0;
bit direction=0; //led旋转方向
bit speed_direction=0; //led旋转速度是否减速
unsigned char speed=1; //led旋转速度
void delay(unsigned int n)
{
 unsigned char i;
 while (n--)
  for (i=0;i<115;i++);
}
void seg8_scan(void)
{
 unsigned char i;
 unsigned int f=1000;
 unsigned char pt=0x00;
 for (i=0;i<=2;i++)
 {
  P0=0xff;
  SEG8=NBIT(i);
  P0=seg8[num1%f/(f/10)];
  delay(1);
  f/=10;
 }
 f=10000;
 for (i=3;i<=6;i++)
 {
  if (i==4)
   pt=0x80;
  else
   pt=0x00;
  
  P0=0xff;
  SEG8=NBIT(i);
  if (i==3 && num2<1000)
   P0=0xff;
  else
   P0=seg8[num2%f/(f/10)]+pt;
  delay(1);
  f/=10;
 }
 SEG8=0xff;
}
void key_scan(void)
{
 if (!K1)
 {
  seg8_scan();
  seg8_scan();
  seg8_scan();
  if (!K1)
  {
   num1++;
   if (num1>999)
   {
    num1=0;
    num2+=150;
    if (num2>9999)
     num2%=100;
   }
  }
  while (!K1)
   seg8_scan();
  seg8_scan();
  seg8_scan();
  seg8_scan();
 }
 if (!K2)
 {
  seg8_scan();
  seg8_scan();
  seg8_scan();
  if (!K2)
  {
   num1--;
   if (num1>=65530)
    num1=999;
   else if (num1==0)
   {
    num2+=100;
    if (num2>9999)
     num2%=100;
   }
  }
  while (!K2)
   seg8_scan();
  seg8_scan();
  seg8_scan();
  seg8_scan();
 }
}
void ledflow(void)
{
 unsigned char b;
 LED|=0x0f;
 LED&=NBIT(0);
 if (ledid>=4 && ledid<=15)
 {
  //全亮3s
  LED&=0xf0;
  ledid++;
  if (ledid==16)
  {
   direction=!direction;
   if (direction)
    ledid=17;
   else
    ledid=2;
   //更新旋转速度
   if (speed_direction)
    speed--;
   else
    speed++;
   if (speed>5)
    speed_direction=1;
   else if (speed==0)
    speed_direction=0;
  }
 }
 else
 {
  if (ledid>=0 && ledid<=2)
  {
   //正转
   ledid++;
   if (ledid==3)
    ledid=0;
   b=ledid+1;
  }
  else if (ledid>=17 && ledid<=19)
  {
   //反转
   ledid--;
   if (ledid==16)
    ledid=19;
   b=ledid-16;
  }
  LED&=NBIT(b);
 }
}
void main(void)
{
 P0=SEG8=0xff;
 LED=0xfc;
 EA=1;
 ET0=1;
 TMOD=0x01;
 TH0=0x3c;
 TL0=0xb0; //50ms
 TR0=1;
 while (1)
 {
  seg8_scan();
  key_scan();
 }
}
void timer0(void) interrupt 1
{
 interval++;
 if (interval>=speed)
 {
  interval=0;
  ledflow();
  num3++;
 }
 
 //LED全亮,右边数码管加0.01
#if DEBUG==1
 if (num3>=24)
#else
 if (num3>=240)
#endif
 {
  num2++;
  if (num2>9999)
   num2=0;
  num3=0;
  ledid=4;
 }
 TH0=0x3c;
 TL0=0xb0; //50ms
}

一派護法 十九級
2樓 發表于:2013-9-21 09:55

【端口定义】

【ports.h】

#define BIT(n) 1<<n
#define NBIT(n) ~(1<<n)
#if DEBUG==1
#define LED P1
#define SEG8 P2
 sbit K1=P1^4;
 sbit K2=P1^5;
#else
#define LED P2
#define SEG8 P1
 sbit K1=P2^4;
 sbit K2=P2^5;
#endif

一派護法 十九級
3樓 發表于:2013-9-21 09:58

【说明】

该程序的主要功能:

1.一个3位数码管和一个4位数码管,按键1可以使三位数码管加1,按键2可以使三位数码管减一。

2.12个LED旋转灯,每四个同种颜色的灯连在一起。

 

若#define LED P2

则当P2.0为低电平时,P2.1,P2.2,P2.3分别控制3组不同颜色的LED灯,每组4个LED灯且颜色相同。

一派護法 十九級
4樓 發表于:2013-9-21 09:58

LED灯还实现正反转、全亮的交替循环模式
一派護法 十九級
5樓 發表于:2013-9-21 10:00

该程序的核心函数是:

void key_scan(void)
{
if (!K1)
{
  seg8_scan();
  seg8_scan();
  seg8_scan();
  if (!K1)
  {
   num1++;
   if (num1>999)
   {
    num1=0;
    num2+=150;
    if (num2>9999)
     num2%=100;
   }
  }
  while (!K1)
   seg8_scan();
  seg8_scan();
  seg8_scan();
  seg8_scan();
}
if (!K2)
{
  seg8_scan();
  seg8_scan();
  seg8_scan();
  if (!K2)
  {
   num1--;
   if (num1>=65530)
    num1=999;
else if (num1==0)
   {
    num2+=100;
    if (num2>9999)
     num2%=100;
   }
  }
  while (!K2)
   seg8_scan();
  seg8_scan();
  seg8_scan();
  seg8_scan();
}
}

 

 

按键消抖延时delay(15)换成了三个seg8_scan()函数来扫描数码管,也起到了相同的延时作用,防止数码管闪烁。

在结束时等待按键释放的过程中,还在while语句中加了seg8_scan(),也是为了防止数码管熄灭。

最后的三个seg8_scan()是为了防止重键,也就是按一下却加了两次数字

一派護法 十九級
6樓 發表于:2013-9-21 10:03

实际测试中还会发现,按下按键后不放,流水灯仍然继续旋转,这是因为流水灯的旋转靠的是定时器中断,按下按键后虽然主程序卡死了,但中断还是正常进行的。

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:461 回複數:5
評論數: ?
作者: 巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2013-9-21 10:03
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。