HuaShine2015 发表于 2015-3-28 20:06:30

仿苹果风格的二进制时钟

本帖最后由 HuaShine2015 于 2015-3-28 20:06 编辑

用ATmega8做了个仿苹果风格的二进制时钟,现在M8真便宜才2.5元/片。
先上图:


http://v.youku.com/v_show/id_XOTIxOTUyNjUy.html
http://v.youku.com/v_show/id_XOTIxOTU3MjI4.html




源码如下:
//二进制时钟源代码Hua.Shine 2015-03-28
//Mega8-16MHZ x 1; 74HC595 x 2; 共阳8x8LED x 1; DS1302 RTC模块
//5v锂电池模块 x 1; 220欧电阻 x 8; 按钮开关 x 1;
//接线方式:
// Mega8 D3 --> 按钮开关 pin1
// Mega GND --> 按钮开关 pin2
// Mega8 D5 --> DS1302 RTC RST_PIN
// Mega8 D6 --> DS1302 RTC DATA_PIN
// Mega8 D7 --> DS1302 RTC CLK_PIN
// Mega8 D8 --> 74HC595 ST_CP
// Mega8 D12 --> 74HC595 SH_CP
// Mega8 D11 --> 74HC595 DS

#include <stdio.h>
#include <string.h>
#include <DS1302.h>

/* Create buffers */
//char buf;
//char day;
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
//Pin connected to DS of 74HC595
int dataPin = 11;
//Pin connected to SRCLR of 74HC595
//int clearPin = 10;

/* Set the appropriate digital I/O pin connections */
uint8_t CE_PIN   = 5;
uint8_t IO_PIN   = 6;
uint8_t SCLK_PIN = 7;
/* Create a DS1302 object */
String inputString = "";
boolean stringComplete = false;

int numdata = {0}, j = 0;
DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);

const byte LEDnum = {   //定义数字的点阵映射

{B00111100,B00100100,B00100100,B00100100,B00100100,B00100100,B00100100,B00111100},//0
{B00100000,B00100000,B00100000,B00100000,B00100000,B00100000,B00100000,B00100000},//1
{B00111100,B00100000,B00100000,B00111100,B00000100,B00000100,B00000100,B00111100},//2
{B00111100,B00100000,B00100000,B00111100,B00100000,B00100000,B00100000,B00111100},//3
{B00100100,B00100100,B00100100,B00111100,B00100000,B00100000,B00100000,B00100000},//4
{B00111100,B00000100,B00000100,B00111100,B00100000,B00100000,B00100000,B00111100},//5
{B00111100,B00000100,B00000100,B00111100,B00100100,B00100100,B00100100,B00111100},//6
{B00111100,B00100000,B00100000,B00100000,B00100000,B00100000,B00100000,B00100000},//7
{B00111100,B00100100,B00100100,B00111100,B00100100,B00100100,B00100100,B00111100},//8
{B00111100,B00100100,B00100100,B00111100,B00100000,B00100000,B00100000,B00111100},//9
{B00000000,B00000000,B00011000,B00000000,B00000000,B00011000,B00000000,B00000000} //:

};
const byte col = {       //列选择

   B01111111,//col number 1
   B10111111,//col number 2
   B11011111,//col number 3
   B11101111,//col number 4
   B11110111,//col number 5
   B11111011,//col number 6
   B11111101,//col number 7
   B11111110   //col number 8
   
};

const byte bset = {

B00000000,
B10000000,
B01000000,
B11000000,
B00100000,
B10100000,
B01100000,
B11100000,
B00010000,
B10010000,

};

boolean bmode = false;

void print_time()             //显示时间到点阵
{
    if(bmode == false){                  ////24小时格式顺序显示
      Time t = rtc.time();
      for(int i=0;i<250;i++){
      numplay((int)(t.hr/10));
      }
      for(int i=0;i<250;i++){
      numplay((int)(t.hr%10));
      }
      for(int i=0;i<150;i++){
      numplay(10);
      }      
      for(int i=0;i<250;i++){
      numplay((int)(t.min/10));
      }
      for(int i=0;i<250;i++){
      numplay((int)(t.min%10));
      }   
          delay(1200);
    }else{                                 //二进制格式显示
      Time t = rtc.time();
      for(int i=0;i<1000;i++){
      bitplay((int)(t.hr/10),0);   
      bitplay((int)(t.hr%10),1);
      bitplay((int)(t.min/10),2);
      bitplay((int)(t.min%10),3);
      bitplay((int)(t.sec/10),4);
      bitplay((int)(t.sec%10),5);
      bitplay(0,6);
      bitplay(0,7);      
      }
    }

}

void wake_up(){                                                                //按钮中断函数,切换显示格式
bmode=(!bmode);
}

void setup() {                                                                //主函数
      
Serial.begin(9600);
inputString.reserve(25);
pinMode(latchPin,OUTPUT);
pinMode(3,INPUT_PULLUP);
attachInterrupt(1, wake_up, FALLING);
rtc.write_protect(false);
rtc.halt(false);

}

void loop() {

if (stringComplete) {                        //有串口输入事件响应代码块
    Serial.println("You inputed : " + inputString);
      for(int i = 0; i < inputString.length() ; i++){      //此处使用论坛例程处理串口时间数据
            if(inputString == ',' || inputString == 0x10 || inputString == 0x13)
            {
                j++;
            }
            else
            {
                numdata = numdata * 10 + (inputString - '0');
            }
      }
      
    Time t(numdata, numdata, numdata, numdata, numdata, numdata, numdata);   //转换成int型的年月日时分秒星期数据在此写入RTC模块
    for(int i = 0; i < 7 ; i++){
      numdata=0;
    }
    rtc.time(t);
    j=0;      
    inputString = "";
    stringComplete = false;
}

print_time();

}

void bitplay(int num, int cl){          //预处理二进制格式显示数据
   
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, col);   
    shiftOut(dataPin, clockPin, bset);
    digitalWrite(latchPin, 1);

}

void numplay(int num){                                        //预处理24小时格式显示数据

for(int i=0;i<9;i++){
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, col);   
    shiftOut(dataPin, clockPin, LEDnum);
    digitalWrite(latchPin, 1);
}
}

void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {   //此处使用Ariduino官方4HC595移位显示处理方法代码,具体可以参考Arduino官方教程ShiftOut:http://www.arduino.cc/en/Tutorial/ShiftOut

int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);

digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);

for (i=7; i>=0; i--){
    digitalWrite(myClockPin, 0);
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {      
      pinState= 0;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
}

//stop shifting
digitalWrite(myClockPin, 0);
}

void serialEvent() {                        //串口事件响应代码
while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    inputString += inChar;

    if (inChar == '\n') {
      stringComplete = true;
    }
}
}


线路原理图


下面是来源于网络的对74HC595的应用示范

li23108 发表于 2015-3-29 07:04:59

感谢分享源码

li23108 发表于 2015-3-29 07:12:52

pinMode(3,INPUT_PULLUP);
attachInterrupt(1, wake_up, FALLING);   Pullup是启用内部上拉电阻吗?
attachlnterrupt。是什么意思,内部执行的是什么

HuaShine2015 发表于 2015-3-29 09:51:40

li23108 发表于 2015-3-29 07:12 static/image/common/back.gif
pinMode(3,INPUT_PULLUP);
attachInterrupt(1, wake_up, FALLING);   Pullup是启用内部上拉电阻吗?
...

给上拉,只是为了开关在常态时稳定

suoma 发表于 2015-3-29 16:40:25

不用74hc595可以吗?

mavericklx 发表于 2015-3-30 18:56:27

漂亮的作品···
顶一个

wscr_wscr 发表于 2015-4-15 01:38:37

赞一个说得很详细               
页: [1]
查看完整版本: 仿苹果风格的二进制时钟