conjee 发表于 2013-5-30 22:52:45

Arduino 4位数码管按键计数器

本帖最后由 conjee 于 2013-5-30 22:53 编辑

Arduino 4位数码管按键计数器,支持断电存储。
学习要点:
       1.数码管编码,及扫描输出。
       2.中断使用。
       3.EEPROM 写入long型数据。(参考论坛文章)


效果图:


视频:
http://v.ku6.com/show/v9v58SWlLnTbtweCXcNCrg...html?from=my

接线图:


完整代码:
#include <avr/eeprom.h>

#define EEPROM_write(address, var) eeprom_write_block((const void *)&(var), (void *)(address), sizeof(var))//EEPROM支持long 占用4字节
#define EEPROM_read(address, var) eeprom_read_block((void *)&(var), (const void *)(address), sizeof(var))//EEPROM支持long 占用4字节

#definePinA 2//中断0
#define led11
#define led23
#define led34
#define led45

#define da6
#define db7
#define dc8
#define dd9
#define de 10
#define df 11
#define dg 12
#define dp 13


long count ;

unsigned long time = 0;
int data = {0x3f, 0x06, 0x5b, 0x4f,0x66,0x6d,0x7d,0x07,0x7f, 0x6f, 0x80};   

// the setup routine runs once when you press reset:
void setup() {               
   pinMode(PinA,INPUT);
   
//for(int i = 0; i < 4; i++)
//      disValue.dchar = EEPROM.read(i);
   EEPROM_read(0, count);
// count = 0;
// EEPROM_write(0,count);
   attachInterrupt(0, runCount, FALLING);    //设置触发,中断号0,即数字2口


    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);
    pinMode(led3, OUTPUT);
    pinMode(led4, OUTPUT);
   
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
   
   for(int i=6; i < 14; i++){
      pinMode(i, OUTPUT);
   
}

ledTest();

}

void runCount()            //触发函数
{

if ((millis() - time) > 150) //防抖动处理
{
    count ++;
      //for(int i = 0; i < 4; i++) {
       //EEPROM.write(i,*dpointer);
      EEPROM_write(0,count);
      //   dpointer++;
   // }
   
}
      
time = millis();

}

//led test 初始测试
void ledTest(){

    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);

   for(int i=0; i < 11; i++){
      ledOut(led1, i );
      delay(200);
}

selecLed(led1);
ledOut(led1, 0 );

}

//select LED 选择对应的数码位
void selecLed(int led){
for(int i=1; i < 5; i++){
    int t = i>1?i+1:1;
    if( t == led){
      digitalWrite(t, LOW);
    }else {
       digitalWrite(t, HIGH);
    }      
}
}

//led out 单个显示
void ledOut(int ledSelect, int td){
       digitalWrite(ledSelect, LOW);
       intset = 0x01;
       for(int i=6; i<14; i++){
            int dis =data & set;
                digitalWrite(i, dis);
            set = set<<1;
       }
}

//led display
void ledDisplay(unsigned long d){
int d1 = d%10;
int d2 = (d/10)%10;
int d3= (d/100)%10;
int d4= d/1000;
   if(d<10){
         selecLed(led1);
         ledOut(led1, d1);
    }else if(d >=10 && d < 100){
         selecLed(led1);
         ledOut(led1, d1);
         delay(10);
         selecLed(led2);
         ledOut(led2, d2);
         delay(10);
    }else if(d >=100 && d < 1000){
      selecLed(led1);
         ledOut(led1, d1);
         delay(7);
         selecLed(led2);
         ledOut(led2, d2);
         delay(8);
      selecLed(led3);
         ledOut(led3, d3);
          delay(9);
    }else if(d >=1000 && d < 10000){
      selecLed(led1);
         ledOut(led1, d1);
         delay(5);
         selecLed(led2);
         ledOut(led2, d2);
         delay(6);
      selecLed(led3);
         ledOut(led3, d3);
          delay(7);
      selecLed(led4);
         ledOut(led4, d4);
         delay(8);
    }

}


// the loop routine runs over and over again forever:
void loop() {

       ledDisplay(count);   //显示值
      

}

ro0t 发表于 2013-5-31 10:28:07

Arduino 玩数码管 总觉得 管脚不够用 不如51管脚多。。。

conjee 发表于 2013-5-31 10:48:29

ro0t 发表于 2013-5-31 10:28 static/image/common/back.gif
Arduino 玩数码管 总觉得 管脚不够用 不如51管脚多。。。

恩,可以用一个595扩展一下或两个373数据和片选复用。

friskit 发表于 2013-6-1 09:33:03

ro0t 发表于 2013-5-31 10:28 static/image/common/back.gif
Arduino 玩数码管 总觉得 管脚不够用 不如51管脚多。。。

总线:)))))

conjee 发表于 2013-6-1 13:09:25

本帖最后由 conjee 于 2013-6-1 13:10 编辑

friskit 发表于 2013-6-1 09:33 static/image/common/back.gif
总线))))


可以使用595芯片,能省下5个IO口,
效果图如下:


用595芯片后程序如下:
#include <avr/eeprom.h>

#define EEPROM_write(address, var) eeprom_write_block((const void *)&(var), (void *)(address), sizeof(var))
#define EEPROM_read(address, var) eeprom_read_block((void *)&(var), (const void *)(address), sizeof(var))
#define uchar unsigned char

#definePinA 2//中断0
#define led11
#define led23
#define led34
#define led45

#define da6
#define db7

#define dc8
#define DataOUT 8
#define DataSTB 9
#define DataCLK 10

#define dd9
#define de 10

#define df 11
#define dg 12
#define dp 13

int subPin = A1;


int keyValue = 1024;

long count ;

unsigned long time = 0;
uchar data = {0x3f, 0x06, 0x5b, 0x4f,0x66,0x6d,0x7d,0x07,0x7f, 0x6f, 0x80};   

// the setup routine runs once when you press reset:
void setup() {               
   pinMode(PinA,INPUT);
   
//for(int i = 0; i < 4; i++)
//      disValue.dchar = EEPROM.read(i);
   EEPROM_read(0, count);
// count = 0;
// EEPROM_write(0,count);
   attachInterrupt(0, runCount, FALLING);    //设置触发,中断号0,即数字2口


    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);
    pinMode(led3, OUTPUT);
    pinMode(led4, OUTPUT);
   
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
   
   for(int i=6; i < 14; i++){
      pinMode(i, OUTPUT);
   
}

ledTest();

}

void runCount()            //触发函数
{

if ((millis() - time) > 150) //防抖动处理
{
   
   keyValue = analogRead(subPin);
   
if( keyValue < 500){
    count--;
    keyValue = 1023;
}else{
    count ++;
}

      //for(int i = 0; i < 4; i++) {
       //EEPROM.write(i,*dpointer);
      EEPROM_write(0,count);
      //   dpointer++;
   // }
   
}
      
time = millis();

}

//led test
void ledTest(){

    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);

   for(int i=0; i < 11; i++){
      ledOut(led1, i );
      delay(200);
}

selecLed(led1);
ledOut(led1, 0 );

}

//select LED
void selecLed(int led){
for(int i=1; i < 5; i++){
    int t = i>1?i+1:1;
    if( t == led){
      digitalWrite(t, LOW);
    }else {
       digitalWrite(t, HIGH);
    }      
}
}

//led out
void ledOut(int ledSelect, int td){
    //   digitalWrite(ledSelect, LOW);
       intset = 0x01;
      
       /** not use 595
       for(int i=6; i<14; i++){
            int dis =data & set;
            digitalWrite(i, dis);
            set = set<<1;
       } */
      
      //use 595
      
       // int testData = 0x9f;
      //uchar testData = 0x06;
      
      //testData =~testData;
         
       for(int i=0; i<8; i++){
            digitalWrite(DataCLK, 0);
            
            uchar dis =data & set;
               
            digitalWrite(DataOUT, dis);
            
            set = set<<1;
            
            digitalWrite(DataCLK,1);
            
       }
      digitalWrite(DataSTB, 0);      //595刷新            
              digitalWrite(DataSTB, 1);   

}

//led display
void ledDisplay(unsigned long d){
int d1 = d%10;
int d2 = (d/10)%10;
int d3= (d/100)%10;
int d4= d/1000;
   if(d<10){
         selecLed(led1);
         ledOut(led1, d1);
    }else if(d >=10 && d < 100){
         selecLed(led1);
         ledOut(led1, d1);
         delay(10);
         selecLed(led2);
         ledOut(led2, d2);
          delay(10);
    }else if(d >=100 && d < 1000){
      selecLed(led1);
         ledOut(led1, d1);
         delay(7);
         selecLed(led2);
         ledOut(led2, d2);
         delay(8);
      selecLed(led3);
         ledOut(led3, d3);
         delay(9);
    }else if(d >=1000 && d < 10000){
      selecLed(led1);
         ledOut(led1, d1);
         delay(5);
         selecLed(led2);
         ledOut(led2, d2);
         delay(6);
      selecLed(led3);
         ledOut(led3, d3);
          delay(7);
      selecLed(led4);
         ledOut(led4, d4);
         delay(8);
    }

}


// the loop routine runs over and over again forever:
void loop() {

       ledDisplay(count);   
   

}

philhoo 发表于 2013-6-2 08:13:26

学习啦,那个595芯片能不能详细介绍一下,电路图。

凝子徔眸 发表于 2014-4-9 23:08:45

求实验原理图和接线图,新手学习用

pol25 发表于 2015-5-6 12:59:14

高手们,能给一个电路的接线图吗

pol25 发表于 2015-5-10 13:39:31

库文件在哪儿有啊
页: [1]
查看完整版本: Arduino 4位数码管按键计数器