시계 만들기 3탄!! [DS1307, Atmega32, TCN75] 시계 소스, 회로도

글 내용


SHW-M110S | Normal program | Spot | 1/24sec | Off Compulsory | 2011:01:28 19:47:05


납땜은 6개월전에 끝냈으나 프로그램하는게 귀찮아 팽개쳐놨던 시계..
FND가 15개나 되어 다이나믹제어가 가능할까도 싶었지만.. 잘 동착되는거보니..ㅋㅋ
(사진으로보는거보다 약간 흐립니다.)

시, 분, 초
온도
월, 일
표시가 가능합니다.

이것을 끝으로 시계는 안만들거같네요...ㅋㅋ (아.. 근데 쪼마난 시계 하나 더 만들고 싶다는..ㅋㅋ)

회로도 안그릴라 했는데 어떤분의 요청으로 그리게 되어 올립니다..ㅋㅋ(회로도는 클릭해서 보세요~)




/**************************************************************************

2010.01.28 완성.

PORTB 0~7 : 각 세그먼트.
PORTA 0~7 : 시, 분, 초, 온도 두번째 자리까지.
PORTC 4~7 : 온도 끝자리부터 월, 일

***************************************************************************/


#include <avr/io.h>
#include <delay.h>

unsigned char number_time[16]= { 0b00111111,0b00000110,0b01011011,0b01001111,0b01100110,0b01101101,
0b01111101,0b00100111,0b01111111,0b01101111,0x00,0,0,0,0,0};

unsigned char month,date,hour, min, sec, mon, day;
unsigned int temp=0;
int month0,month1,day0,day1,hour0,hour1,min0,min1,sec0,sec1,temp0, temp1, temp2;

void time_print1(int value, int value1, int value2,int value3,int value4, int value5) {

 if(value2>12) value2=value2-12; // 12/24 시간제.
 if(value2==0) value2=12; // 자정일때 12로 표시.
  
 //각 자리수 계산.
 month0=value/10;
 month1=value-(value/10*10);
 day0=value1/10;
 day1=value1-(value1/10*10);
 hour0=value2/10;
 hour1=value2-(value2/10*10);
 if(hour0==0) hour0=10;
 min0=value3/10;
 min1=value3-(value3/10*10);
 sec0=value4/10;
 sec1=value4-(value4/10*10);

 temp0=value5/100;
 temp1=(value5-(value5/100*100))/10;
 temp2=value5%10;


 //FND에 숫자 표시
 int g;
 for(g=0;g<10;g++){
 PORTB=0x00; PORTC=0x01; delay_ms(1);
 
  if(hour0==1) {PORTA=0x01; delay_ms(1);}
 else PORTA=0x00;
 PORTB=number_time[hour1]; PORTA=0x02;delay_ms(1);
 PORTB=number_time[min0]; PORTA=0x04;delay_ms(1);
 PORTB=number_time[min1]; PORTA=0x08;delay_ms(1);
 PORTB=number_time[sec0]; PORTA=0x10;delay_ms(1);
 PORTB=number_time[sec1]; PORTA=0x20;delay_ms(1);
 PORTA=0x00;
 
 PORTB=number_time[temp0]; PORTA=0x40;delay_ms(1);
 PORTB=(0x80|number_time[temp1]); PORTA=0x80;delay_ms(1);
 PORTA=0x00;
 PORTB=number_time[temp2]; PORTC=0x08;delay_ms(1);
 
 if(month0==0) month0=10;
 PORTB=number_time[month0]; PORTC=0x10; delay_ms(1);
 PORTB=number_time[month1]; PORTC=0x20; delay_ms(1);
 PORTB=number_time[day0]; PORTC=0x40;delay_ms(1);
 PORTB=number_time[day1]; PORTC=0x80; delay_ms(1);
 PORTB=0x00; PORTC=0x40; delay_ms(1);
  
 }
}

unsigned int tcn75_read(unsigned char address)
{
 delay_us(3);  
 unsigned int high_byte=0, low_byte=0, result;
 TWCR = 0xA4;      // START condition
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x08);
 TWDR = 0x90;     // TCN75 Slave Address (R/W =0; Write)
 TWCR = 0x84;      // MT_SLA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x18);
 TWDR = address;  // Select Temperature Register
 TWCR = 0x84;      // MT_DATA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x28);
 TWCR = 0xA4;      // RESTART condition
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x10);
 TWDR = 0x91;    // TCN75 Slave Address (R/W =1; Read)
 TWCR = 0x84;      // MR_SLA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x40);
 TWCR = 0xC4;      // MT_DATA_ACK        
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x50);   
 high_byte = TWDR; //상위바이트                             
 TWCR = 0x84;      // MR_DATA_NOACK      // 84
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x58);     // 58
 low_byte = TWDR;  // 하위바이트
 TWCR = 0x94;      // STOP condition
 result  = high_byte << 1;
 result |= (low_byte >> 7);
 return result;
}

 

void rtc_write(unsigned char address, unsigned char byte) {
 delay_us(3);    // 없거나 위치가 다르면 동작 안함 이유는?? 뭘까??
 TWCR = 0xA4;      // START condition
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x08);
 TWDR = 0xD0;
 TWCR = 0x84;      // MT_SLA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x18);
 TWDR = address;
 TWCR = 0x84;      // MT_DATA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x28);
 TWDR = byte;
 TWCR = 0x84;      // MT_DATA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x28);
 TWCR = 0x94;      // STOP condition
}

unsigned char rtc_read(unsigned char address) {
 delay_us(3);    // 없거나 위치가 다르면 동작 안함 이유는?? 뭘까??
 unsigned char byte;
 TWCR = 0xA4;      // START condition
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x08);
 TWDR = 0xD0;
 TWCR = 0x84;      // MT_SLA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x18);
 TWDR = address;
 TWCR = 0x84;      // MT_DATA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x28);
 TWCR = 0xA4;      // RESTART condition
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x10);
 TWDR = 0xD1;
 TWCR = 0x84;      // MR_SLA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x40);
 TWCR = 0x84;      // MR_DATA_NOACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x58);
 byte = TWDR;
 TWCR = 0x94;      // STOP condition
 return byte;
}

 

int main()
{
 int o=0;
 
 TWBR= 72;  
 TWSR= 0x00;
 TWCR= 0x04;

 DDRA=0xFF;
 DDRB=0xFF;
 DDRC=0xFF;

// rtc_write(0x05,0x01);   // month
// rtc_write(0x04,0x28);   // date
// rtc_write(0x03,0x01);   // day  
// rtc_write(0x02,0x19);   // h
// rtc_write(0x01,0x08);   // m
// rtc_write(0x00,0x00);   // s

 while(1){
  month=  rtc_read(0x05);
  month=  ((month >>4) & 0x01)*10 + (month & 0x0f);

  date=   rtc_read(0x04);
  date=   ((date >>4) & 0x03)*10 + (date & 0x0f);

  hour=   rtc_read(0x02);
  hour=   ((hour >>4) & 0x07)*10 + (hour & 0x0f);
 
  min=    rtc_read(0x01);
  min=    ((min >>4) & 0x07)*10 + (min & 0x0f);
 
  sec= rtc_read(0x00);
  sec= ((sec >>4) & 0x07)*10 + (sec & 0x0f);
  
  
  if(o==20)
  {  
   temp=tcn75_read(0x00);
   if((temp & 0x0001)==0x0001) {temp=temp/2*10; temp+=5;}
   else if ((temp & 0x0001)==0x0000)  {temp=temp/2*10;}
   if(o==20) o=0;
  }
  o++;

  time_print1(month,date,hour,min,sec,temp);
 }
 return 0;
}

위의 소스. 


업데이트 소스(온도를 50번 계산한 평균을 구해 출력)
  1. user picture
    글 잘 봤습니다. Twi_write/read 처음 delay는 DS1307 스펙에 나오네요. Bus free time 입니다. 최소 4.7us 이상 주라 되어 있네요 ^^

티스토리 툴바