hxf 发表于 2015-7-7 16:40:55

从零开始 开关计数器(4位数码管的控制)

本帖最后由 hxf 于 2015-7-7 17:03 编辑

       楼主有一个朋友最近购置了一批游乐设施,想知道这些设施每天的工作情况,于是拜托楼主做一个计数器,记录下开机次数和开机时间。

初步方案(方案一):3641共阳极四位数码管+arduino+开关   实现简单的计数功能并显示
先查阅了一些关于数码管的资料,推荐一个讲的比较详细的   http://bbs.elecfans.com/jishu_455250_1_1.html
接下来是接线,只需要在原图上稍作改动即可:

程序同样是在原作者程序上稍作了些改动,感谢开源的arduino:
//设置阴极接口
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int p = 8;
//设置阳极接口
int d4 = 9;
int d3 = 10;
int d2 = 11;
int d1 = 12;
//设置变量
long n = 0;
int number=0;
int state;//当前开关状态
int old_state;//前时刻开关状态
int Button=13;
void setup()
{
pinMode(d1, OUTPUT);
pinMode(d2, OUTPUT);
pinMode(d3, OUTPUT);
pinMode(d4, OUTPUT);
pinMode(a, OUTPUT);
pinMode(b, OUTPUT);
pinMode(c, OUTPUT);
pinMode(d, OUTPUT);
pinMode(e, OUTPUT);
pinMode(f, OUTPUT);
pinMode(g, OUTPUT);
pinMode(p, OUTPUT);
pinMode(Button,INPUT);
}
void loop()
{
state=digitalRead(Button);
if(state!=old_state)number=number++;
screen(number/2);
old_state=state;
}
void screen(int n)
{
clearLEDs();
pickDigit(1);
pickNumber((n/1000)%10);
clearLEDs();
pickDigit(2);
pickNumber((n/100)%10);
clearLEDs();
pickDigit(3);
pickNumber((n/10)%10);
clearLEDs();
pickDigit(4);
pickNumber(n%10);
}
void pickDigit(int x)//定义pickDigit(x),其作用是开启dx端口
{
digitalWrite(d1, LOW);
digitalWrite(d2, LOW);
digitalWrite(d3, LOW);
digitalWrite(d4, LOW);
switch(x)
{
case 1:
    digitalWrite(d1, HIGH);
    break;
case 2:
    digitalWrite(d2, HIGH);
    break;
case 3:
    digitalWrite(d3, HIGH);
    break;
default:
    digitalWrite(d4, HIGH);
    break;
}
}
void pickNumber(int x)   //定义pickNumber(x),其作用是显示数字x
{
switch(x)
{
default:
    zero();
    break;
case 1:
    one();
    break;
case 2:
    two();
    break;
case 3:
    three();
    break;
case 4:
    four();
    break;
case 5:
    five();
    break;
case 6:
    six();
    break;
case 7:
    seven();
    break;
case 8:
    eight();
    break;
case 9:
    nine();
    break;
}
}
void dispDec(int x)//设定开启小数点
{
digitalWrite(p, LOW);
}
void clearLEDs()//清屏
{
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
digitalWrite(p, HIGH);
}
void zero()//定义数字0时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, HIGH);
}
void one()//定义数字1时阴极那些管脚开关
{
digitalWrite(a, HIGH);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
}
void two()//定义数字2时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, HIGH);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, HIGH);
digitalWrite(g, LOW);
}
void three()//定义数字3时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, LOW);
}
void four()//定义数字4时阴极那些管脚开关
{
digitalWrite(a, HIGH);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
}
void five()//定义数字5时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, HIGH);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, HIGH);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
}
void six()//定义数字6时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, HIGH);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
}
void seven()//定义数字7时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
}
void eight()//定义数字8时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
}
void nine()//定义数字9时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, HIGH);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
}

eysajan 发表于 2015-7-7 17:05:13

程序写得很详细,但是这样写太麻烦了吧?

hxf 发表于 2015-7-7 17:09:37

eysajan 发表于 2015-7-7 17:05 static/image/common/back.gif
程序写得很详细,但是这样写太麻烦了吧?

恩,也可以自己尝试建立库文件

eysajan 发表于 2015-7-7 17:18:36

本帖最后由 eysajan 于 2015-7-7 17:25 编辑

hxf 发表于 2015-7-7 17:09 static/image/common/back.gif
恩,也可以自己尝试建立库文件

也没必要库文件,没必要每一个数字设计几行代码,用for循环可以简化接口定义和输出状态。用字符串可以设定每一个数字的高低电平,那样可以把这个程序简化好多。这是我做的温度控制器方案,参考一下。
#include <Arduino.h>
#define termo A0   
#define Reli0      
#define Reli1 1   

#define Put_A 2
#define Put_B 3
#define Put_C 4
#define Put_D 5
#define Put_E 6
#define Put_F 7
#define Put_G 8
#define Put_H 9

#define Hane1 10
#define Hane2 11
#define Hane3 12
#define Hane4 13

int tengshek=0;
int asti=0;
int usti=0;

int chong=40;
int kichik=20;
int halet=0;
int ter = 0;         
int temp = 0;               
unsigned char jedwel =
{/*   
               aaaaaaa   
            ff            bb   
            ff            bb   
            ff            bb
             ggggggg
            ee            cc
            ee            cc
            ee            cc
             ddddddd    hh*/
/*{a,   b,   c,   d,   e,   f,   g },   */
{1,   1,   1,   1,   1,   1,   0 },   //0   0
{0,   1,   1,   0,   0,   0,   0 },   //1   1
{1,   1,   0,   1,   1,   0,   1 },   //2   2
{1,   1,   1,   1,   0,   0,   1 },   //3   3
{0,   1,   1,   0,   0,   1,   1 },   //4   4
{1,   0,   1,   1,   0,   1,   1 },   //5   5
{1,   0,   1,   1,   1,   1,   1 },   //6   6
{1,   1,   1,   0,   0,   0,   0 },   //7   7
{1,   1,   1,   1,   1,   1,   1 },   //8   8
{1,   1,   1,   1,   0,   1,   1 },   //9   9
{1,   1,   1,   0,   1,   1,   1 },   //A   10
{0,   1,   1,   1,   1,   1,   0 },   //U   11
{0,   1,   1,   0,   1,   1,   1 },   //H   12
{0,   0,   0,   0,   0,   0,   1 }    //-   13
};

unsigned char hane_jedwel ={{0,1,1,1},{1,0,1,1},{1,1,0,1},{1,1,1,0}};
void setup()
{         pinMode(Put_A,   OUTPUT);               
      pinMode(Put_B,   OUTPUT);
      pinMode(Put_C,   OUTPUT);
      pinMode(Put_D,   OUTPUT);
      pinMode(Put_E,   OUTPUT);
      pinMode(Put_F,   OUTPUT);
      pinMode(Put_G,   OUTPUT);
      pinMode(Put_H,   OUTPUT);
      pinMode(Reli   ,      OUTPUT);
      pinMode(Reli1,   OUTPUT);
      pinMode(Hane1,   OUTPUT);
      pinMode(Hane2,   OUTPUT);
      pinMode(Hane3,   OUTPUT);
      pinMode(Hane4,   OUTPUT);}
void loop()
{    tengshek=analogRead(1);
   asti=analogRead(2);
   usti=analogRead(3);   
   ter = analogRead(termo);            
   temp = ter * 4.8876;               
if(temp/10>chong)
digitalWrite(Reli,LOW);
else digitalWrite(Reli,HIGH);
   if(temp/10<kichik)
digitalWrite(Reli1,LOW);
else digitalWrite(Reli1,HIGH);
if (tengshek>900)
         {delay(20);
          halet++;
if (halet==3)
          halet=0;};
if (usti>900)
   {delay(100);
   if(halet==1)
          chong++;
          else if(halet==2)
          kichik++;    };
if (asti>900)
   {delay(100);
   if(halet==1)
          chong--;
else if(halet==2)
          kichik--;    };
switch(halet)
{case 0:
      Korsitish(0,   12);                        //H
      delay(3);
      Korsitish(1,   temp/100%10);               
      delay(3);
      Korsitish(2,   temp/10%10);                     
      delay(3);
      Korsitish(3,   temp%10);                     
      delay(3);
      break;
case 1:
      Korsitish(0,   11);                        //U
      delay(3);
      Korsitish(1,   13);                        //-
      delay(3);
      Korsitish(2,   chong/10%10);                     
      delay(3);
      Korsitish(3,   chong%10);                     
      delay(3);
      break;
case 2:
      Korsitish(0,   10);                        //A
      delay(3);
      Korsitish(1,   13);                        //-
      delay(3);
      Korsitish(2,kichik/10%10);               
      delay(3);
      Korsitish(3,kichik%10);                  
      delay(3);
      break;}}

void Korsitish(int Hane,   int reqem)               
{      digitalWrite(Put_A,   LOW);                  
      digitalWrite(Put_B,   LOW);
      digitalWrite(Put_C,   LOW);
      digitalWrite(Put_D,   LOW);
      digitalWrite(Put_E,   LOW);
      digitalWrite(Put_F,   LOW);
      digitalWrite(Put_G,   LOW);
      digitalWrite(Put_H,   LOW);
   
      digitalWrite(Hane1,   hane_jedwel);
      digitalWrite(Hane2,   hane_jedwel);
      digitalWrite(Hane3,   hane_jedwel);
      digitalWrite(Hane4,   hane_jedwel);
   
      digitalWrite(Put_A,   jedwel);      
      digitalWrite(Put_B,   jedwel);
      digitalWrite(Put_C,   jedwel);
      digitalWrite(Put_D,   jedwel);
      digitalWrite(Put_E,   jedwel);
      digitalWrite(Put_F,   jedwel);
      digitalWrite(Put_G,   jedwel);
      if(halet==0&&Hane==2)         
      digitalWrite(Put_H,   HIGH);
      else digitalWrite(Put_H,   LOW);}

来源 http://alip.biz/forum.php?mod=viewthread&tid=35813&extra=page%3D2&page=1

hxf 发表于 2015-7-7 17:37:47

eysajan 发表于 2015-7-7 17:18 static/image/common/back.gif
也没必要库文件,没必要每一个数字设计几行代码,用for循环可以简化接口定义和输出状态。用字符串可以设 ...

牛,很不错的思路啊

hxf 发表于 2015-7-7 17:40:42

eysajan 发表于 2015-7-7 17:18 static/image/common/back.gif
也没必要库文件,没必要每一个数字设计几行代码,用for循环可以简化接口定义和输出状态。用字符串可以设 ...

不过我那样做是因为后期想通过74hc595进行一下IO口扩展

eysajan 发表于 2015-7-7 18:36:32

hxf 发表于 2015-7-7 17:40 static/image/common/back.gif
不过我那样做是因为后期想通过74hc595进行一下IO口扩展

用74HC595的话更简单了,代码更短
#include <Arduino.h>
#define tengshex 2
#define asti         3
#define usti         4
#define clockPin5
#define latchPin6
#define reqem    7
#define hane      8
int chong=40;
int kichik=20;
int halet=0;
int ad = 0;      
int temp = 0;      
                                  //0,1 ,2 , 3 , 4 , 5 , 6 , 7 , 8 ,9
unsigned char reqem_jedwel ={252,96,218,242,102,182,190,224,254,246};
void setup()
{         pinMode(clockPin ,      OUTPUT);               
      pinMode(latchPin ,            OUTPUT);
      pinMode(reqem,            OUTPUT);
      pinMode(hane ,               OUTPUT);
      pinMode(tengshex,INPUT_PULLUP);
      pinMode(asti,       INPUT_PULLUP);
      pinMode(usti,       INPUT_PULLUP);}
void loop()
{ if(digitalRead(tengshex) == LOW)
         {delay(20);
          halet++;
if (halet==3)
          halet=0; };
if(digitalRead(asti) == LOW)
{delay(20);
   if(halet==1)
          chong--;
          else if(halet==2)
          kichik--;    };
if(digitalRead(usti) == LOW)
   {delay(100);
   if(halet==1)
          chong++;
else if(halet==2)
          kichik++;    };
   ad= analogRead(A0);                        
   temp = ad* 4.8876;                        
switch(halet)
{case 0:
      Korsitish(7,   110);               
      delay(3);
      Korsitish(11 ,   reqem_jedwel);      
      delay(3);
      Korsitish(13 ,   reqem_jedwel+128);      
      delay(3);
      Korsitish(14,   reqem_jedwel);               
      delay(3);
      break;
case 1:
      Korsitish(7,   124);               
      delay(3);
      Korsitish(11,   2);               
      delay(3);
      Korsitish(13,   reqem_jedwel);      
      delay(3);
      Korsitish(14 ,   reqem_jedwel);      
      delay(3);
      break;
case 2:
      Korsitish(7,   238);               
      delay(3);
      Korsitish(11,   2);               
      delay(3);
      Korsitish(13 ,reqem_jedwel);      
      delay(3);
      Korsitish(14 ,reqem_jedwel);               
      delay(3);
      break;}    }
void Korsitish(unsigned char _Hane,   unsigned char _reqem)      
{          /*if(temp/10<kichik)_Hane&=16;
            if(temp/10<chong&&temp/10>kichik) _Hane&=32;
            if(temp/10>chong) _Hane&=64;*/
    digitalWrite(latchPin,LOW);
    shiftOut(hane ,clockPin,MSBFIRST,_Hane);
    shiftOut(reqem ,clockPin,MSBFIRST,_reqem);
    digitalWrite(latchPin,HIGH); }

lm4766 发表于 2015-7-9 00:06:45

占用IO口多,程序又太罗嗦
页: [1]
查看完整版本: 从零开始 开关计数器(4位数码管的控制)