2013-08-26 9 views
0

자명종 용 코드를 작성합니다. 저는 ROM = 80 % RAM = 8 % -51 %를 사용하는 CCS 컴파일을 사용합니다. 나는 프로 테우스에서 내 프로그램을 시뮬레이트한다. 하지만 실제 하드웨어에서 사용할 때는 시간 = 00:00:80을 표시하고 두 번째는 실행하지 않습니다. 내 코드가 DS1307에서 시간을 읽습니다. DS1307의 배터리 3V는 바뀌지 만 동일한 시간이 표시됩니다. 단추를 누르면 아무것도 표시되지 않습니다. 내 코드가 잘못되면 프로 테우스로 돌아갈 수 없다고 생각합니다. 그것을 고치는 방법? 도와주세요.PIC16f88을 사용하여 DS1307에서 시간을 표시 할 수 없습니다

이것은 내 코드입니다.

#include <16F886.h> 
#fuses HS,NOWDT,NOPROTECT,NOLVP 
#use delay(clock=20000000) 

#include "flex_LCD.c" 
#use I2C(master, sda=PIN_C4, scl=PIN_C3) 
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) 

#define ADDR_DS1307 0xD0 //Address DS1307 

int set_hr=24; 
int set_min=60; 
short int f_next = FALSE; 
short int delay_chk=FALSE; 
int cnt; 

typedef struct{ 
    BYTE sec;  // seconds 
    BYTE min;  // minute 
    BYTE hr;  // hour 
    BYTE day; 
    BYTE date; 
    BYTE month; 
    BYTE year; 
}DS1307_RTC; 

DS1307_RTC RTC; 

typedef struct{ 

    int min;  // minute 
    int hr;  // hour 
    int sec_delay; 
}time_feed; 

time_feed t_feed; 


void DS1307_Write(unsigned char ctl, unsigned char dat); 
BYTE DS1307_Read(unsigned char ctl); 
void DS1307_WriteDate(void); 
void DS1307_WriteTime(void); 

void DS1307_ReadDate(void); 
void DS1307_ReadTime(void); 
void Set_Voice(); 


BYTE bin2bcd(BYTE binary_value) 
{ 
    BYTE temp; 
    BYTE retval; 

    temp = binary_value; 
    retval = 0; 

    while(1) 
    { 
    // Get the tens digit by doing multiple subtraction 
    // of 10 from the binary value. 
    if(temp >= 10) 
    { 
     temp -= 10; 
     retval += 0x10; 
    } 
    else // Get the ones digit by adding the remainder. 
    { 
     retval += temp; 
     break; 
    } 
    } 

    return(retval); 
} 

// Input range - 00 to 99. 
BYTE bcd2bin(BYTE bcd_value) 
{ 
    BYTE temp; 

    temp = bcd_value; 
    // Shifting upper digit right by 1 is same as multiplying by 8. 
    temp >>= 1; 
    // Isolate the bits for the upper digit. 
    temp &= 0x78; 

    // Now return: (Tens * 8) + (Tens * 2) + Ones 

    return(temp + (temp >> 2) + (bcd_value & 0x0f)); 
} 

    /*******************************************************/ 
void DS1307_Write(unsigned char ctl, unsigned char dat){ 
    i2c_start(); 
    i2c_write(ADDR_DS1307); 
    i2c_write(ctl); 
    i2c_write(dat); 
    i2c_stop(); 
} 

/*******************************************************/ 
BYTE DS1307_Read(unsigned char ctl){ 

    BYTE dat; 

    i2c_start(); 
    i2c_write(ADDR_DS1307); 
    i2c_write(ctl); 

    i2c_start(); 
    i2c_write(ADDR_DS1307+1); 
    dat = i2c_read(0); 
    i2c_stop(); 
    return(dat); 
} 

/*******************************************************/ 
void DS1307_WriteDate(void){ 
    DS1307_Write(0x04,RTC.date); 
    DS1307_Write(0x05,RTC.month); 
    DS1307_Write(0x06,RTC.year); 
} 

/*******************************************************/ 
void DS1307_WriteTime(void){ 
    DS1307_Write(0x00,RTC.sec); 
    DS1307_Write(0x01,RTC.min); 
    DS1307_Write(0x02,RTC.hr); 
} 

/*******************************************************/ 
void DS1307_ReadDate(void){ 
    RTC.date = DS1307_Read(0x04); 
    RTC.month = DS1307_Read(0x05); 
    RTC.year = DS1307_Read(0x06); 
} 

/*******************************************************/ 
void DS1307_ReadTime(void){ 
    RTC.sec = DS1307_Read(0x00); 
    RTC.min = DS1307_Read(0x01); 
    RTC.hr = DS1307_Read(0x02); 
} 

void DS1307_SetTime(int hr, int min){ 

    RTC.hr = bin2bcd(hr); 
    RTC.min = bin2bcd(min); 
    RTC.sec = 0x00; 
} 

/************* Delay *************/ 
void delay(){ 
int sec_delay; 

    for(sec_delay=t_feed.sec_delay;sec_delay>0;sec_delay--){ 
    output_high(pin_C5); 
    lcd_gotoxy(1,2); 
    delay_ms(1000); 
    printf(lcd_putc,"\r Food = %d sec " sec_delay); 
    } 
    output_low(pin_C5); 
} 

void clr_voice(){ 
    output_high(pin_C0); 
    output_high(pin_C1); 
    output_high(pin_C2); 
    delay_ms(1000); 
    output_float(pin_C0); 
    output_float(pin_C1); 
    output_float(pin_C2); 
} 

/************* time **************/ 
void time(){ 

    int hr=bcd2bin(RTC.hr); 
    int min=bcd2bin(RTC.min); 

    delay_ms(50); 
    lcd_gotoxy(1,2); 
    //printf(lcd_putc,"\r -- : -- "); 
    printf(lcd_putc,"\r %02d : %02d ", hr,min); 
    delay_ms(50); 

while(1){ 

if(input(PIN_B1)==0){ 

    delay_ms(100); 
    hr++; 

if(hr>=24){hr=0;} 

    delay_ms(100); 
    lcd_gotoxy(1,2); 

    printf(lcd_putc,"\r %02d : %02d ", hr,min); 
    delay_ms(50); 


}else if(input(PIN_B2)==0){ 

    delay_ms(100); 
    min++; 

if(min>=60){min=0;} 

    delay_ms(100); 
    lcd_gotoxy(1,2); 
    printf(lcd_putc,"\r %02d : %02d ", hr,min); 
    delay_ms(50); 

} 

if(input(PIN_B3)==0){ 

    lcd_gotoxy(1,2); 
    printf(lcd_putc,"\r Time : %02d:%02d ", hr,min); 
    delay_ms(50); 


    DS1307_SetTime(hr,min); 
    DS1307_WriteTime(); 

    break; 

} 
} // while hr 

} 

/************* check same time **************/ 
int check_time(int hr[], int hr_ck, int min[], int min_ck,int count){ 
    int x; 
    for(x=0;x<count;x++){ 

    if((hr[x]== hr_ck) && (min[x]== min_ck)){ 

    if((hr_ck==24)&& (min_ck==60)){ 

     return 0; 
     break; 

    }else{ 
     return 1; 
     break; 
    } 
    } 
    } 
    return 0; 

} 

/************ get now time ***************/ 
int16 getNow(){ 

    int16 now_hr,now_min; 
    int16 now_all; 

    DS1307_ReadTime(); 

    now_hr = bcd2bin(RTC.hr); 
    now_min = bcd2bin(RTC.min); 
    now_all = (now_hr*60)+now_min; 

    //printf("\r\n n=%ld",now_all); 
    return now_all; 
} 

/**************************************/ 
int16 next_time(int16 hr, int16 min, int pos){ 

int32 minimVal; 
int i=0; 
int16 now_all; 
int32 all[5],t; 
int16 hrk[5],mnk[5]; 
int n,j; 

hrk[pos] = hr; 
mnk[pos] = min; 
all[pos] =(hrk[pos]*60 + mnk[pos]) ; 

//minimVal2 = (hrk[0]*60) + mnk[0]; 
now_all = getNow(); 
//printf("\r\n pos=%d, n=%ld, ",pos,all[pos]); 

n = sizeof(all)/sizeof(all[0]); 

    /* bubble sort */ 
    for (i = pos; i > 0; i--) { 
     for (j = 0; j < i; j++) { /* move max (in [0] to [i]) to last ([i]) */ 
      if (all[j] > all[j+1]) { /* exchange if bigger than next */ 
       t = all[j]; 
       all[j] = all[j+1]; 
       all[j+1] = t; } } } 

       minimVal= all[0]; 

    for (i = 0; i < pos+1; i++) { 
    //printf("\r\n%ld ", all[i]); 

    if(all[i]>now_all){ 
    if(all[i]!=1500){ 
     minimVal= all[i]; 
     break; 
    } 
} 
    } 

//printf("\r\n min %ld ", minimVal); 

return minimVal; 

} 

/************* Show Menu **************/ 
void show_menu(){ 
    delay_ms(50); 
    lcd_gotoxy(1,2); 
    printf(lcd_putc,"[Next]  [OK]"); 
    delay_ms(50); 
} 

/************* feed time **************/ 
void feed_time(int count){ 


int hr[5],min[5]; 
int16 next; 

while(1){ 

if(input(PIN_B1)==0){ 

delay_ms(250);  // delay for add hr 
set_hr++; 

if(set_hr>24){ 
    set_hr=0; 
    set_min= 0; 
} 

if(set_hr==24){ 
    set_min=60; 
    delay_ms(50); 
    lcd_gotoxy(1,2); 
    printf(lcd_putc,"\r F%d : -- : -- ",count+1); 
    delay_ms(50); 
}else{ 
    delay_ms(50); 
    lcd_gotoxy(1,2); 
    printf(lcd_putc,"\r F%d : %02d : %02d ", count+1, set_hr,set_min); 
    delay_ms(50); 
} 

}else if(input(PIN_B2)==0){ 

    delay_ms(250);  // delay for add min 
    set_min++; 

if(set_min>=60){ 
    if(set_hr==24){set_hr=0;} 
    set_min=0; 

} 
    delay_ms(50); 
    lcd_gotoxy(1,2); 
    printf(lcd_putc,"\r F%d : %02d : %02d " count+1, set_hr,set_min); 
    delay_ms(50); 

} 

if(input(PIN_B3)==0){ 
    hr[count] = set_hr; 
    min[count] = set_min; 

    if(check_time(hr,set_hr,min,set_min,count)){ 

     delay_ms(50); 
     lcd_gotoxy(1,1); 
     //printf(lcd_putc,"\rn=%d ar= %d,va= %d" ,count, set_hr,set_min); 
     printf(lcd_putc,"\r This is same. "); 
     delay_ms(50); 

    } 

    else{ 

      next= next_time(hr[count],min[count],count); 
      t_feed.hr=next/60; 
      t_feed.min=next%60; 

if(set_hr==24){ 

    delay_ms(50); 
    lcd_gotoxy(1,1); 
    printf(lcd_putc,"\r F%d : -- : -- ",count+1); 
    delay_ms(50); 

    lcd_gotoxy(1,2); 
    printf(lcd_putc,"\r     "); 
    delay_ms(50); 

    if((count+2)!=6){ 

     lcd_gotoxy(1,2); 
     printf(lcd_putc,"\r F%d : -- : -- ",count+2); 
     delay_ms(50); 
    } 

}else{ 

    delay_ms(50); 
    lcd_gotoxy(1,1); 
    printf(lcd_putc,"\r F%d : %02d : %02d " count+1, set_hr,set_min); 
    delay_ms(50); 

    if((count+2)!=6){ 
     lcd_gotoxy(1,2); 
     printf(lcd_putc,"\r F%d : %02d : %02d ",count+2,set_hr,set_min); 
     delay_ms(50); 
    } 

} 
    f_next=TRUE; 
    break; 

    } 
    } 

} // while hr 

} 

/************* Sec Period **************/ 
void sec_feed(){ 

//unsigned int sec=10; 

while(input(PIN_B3)){ 

if(input(PIN_B1)==0){ 
    delay_ms(100); 
    t_feed.sec_delay++; 

    if(t_feed.sec_delay>=200){t_feed.sec_delay=200;} 
     delay_ms(100); 
     lcd_gotoxy(1,2); 
     printf(lcd_putc,"\r Time : %d sec ",t_feed.sec_delay); 
     delay_ms(50);  
} 

if(input(PIN_B2)==0){ 
    delay_ms(100); 
    t_feed.sec_delay--; 

    if(t_feed.sec_delay<=1){t_feed.sec_delay=1;} 
     delay_ms(100); 
     lcd_gotoxy(1,2); 
     printf(lcd_putc,"\r Time : %d sec ",t_feed.sec_delay); 
     delay_ms(50); 
} 
} // while sec 
t_feed.sec_delay = t_feed.sec_delay; 
//delay(); 

} 

/************* Record **************/ 
void rec(){ 
int i; 
//unsigned int sec=10; 

while(input(PIN_B3)){ 

if(input(PIN_B0)==0){ 
    delay_ms(50); 

    lcd_gotoxy(1,1); 
    printf(lcd_putc,"\r Please Wait... "); 
    delay_ms(50); 


    for(i=0;i<10;i++){ //clear voice 10 Sec. 
    output_low(pin_C0); 
    output_high(pin_C1); 
    output_high(pin_C2); 
    lcd_gotoxy(1,2); 
    delay_ms(1000); 

    } 

    for(i=10;i>0;i--){ //clear voice 10 Sec. 
     output_high(pin_C0); 
     output_low(pin_C1);  // record 
     output_high(pin_C2); 

     delay_ms(50); 

    lcd_gotoxy(1,1); 
    printf(lcd_putc,"\r Say now %d ", i); 
    delay_ms(50); 
    delay_ms(850); 
    } 

    output_high(pin_C0); // play 
    output_high(pin_C1); 
    output_low(pin_C2); 
    delay_ms(500); 

    clr_voice(); 

    lcd_gotoxy(1,1); 
    printf(lcd_putc,"\r Record Voice "); 
} 

} // while sec 

} 

/************* Set time **************/ 
void Set_Time(){ 

    delay_ms(50); 
    lcd_gotoxy(1,1); 
    printf(lcd_putc,"\r Set Clock "); 

    show_menu(); 

while(1){ 

    if(input(PIN_B3)==0){ 

     delay_ms(250); 
     time(); 
     break; 
    } 

    if(!input(PIN_B0)){ 

     break; 
    } 
} 
} 

/************* Set Feed Time **************/ 
void Set_Feed_Time(){ 
    int i; 
    lcd_gotoxy(1,1); 
    printf(lcd_putc,"\r Set Feed Time "); 

    show_menu(); 

while(1){ 

    if(input(PIN_B3)==0){ 

     delay_ms(50); 
     lcd_gotoxy(1,2); 
     printf(lcd_putc,"\r F1 : -- : -- "); 


     delay_ms(250); 


     for(i=0;i<5;i++){  // count feed time 
     feed_time(i); 
     delay_ms(250); 
     } 

     break; 

} 

    if(!input(PIN_B0)){ 

     break; 
    } 

} 
} 

/***************** Set Period Time *********************/ 

void Set_Period_Time(){ 

    lcd_gotoxy(1,1); 
    printf(lcd_putc,"\rSet Feed Period"); 

    show_menu(); 

while(1){ 

    if(input(PIN_B3)==0){ 

     delay_ms(50); 
     lcd_gotoxy(1,2); 
     printf(lcd_putc,"\r Time : %d sec ",t_feed.sec_delay); 

     delay_ms(250); 
     sec_feed(); 

    break; 
} 

    if(!input(PIN_B0)){ 

     break; 
    } 
} 
    } 

/***************** Set Voice *********************/ 

void Play_Voice(){ 

    lcd_gotoxy(1,1); 
    printf(lcd_putc,"\r Play Voice "); 

    show_menu(); 

    while(1){ 

    if(input(PIN_B3)==0){ 
     delay_ms(250); 



    output_high(pin_C0); 
    output_high(pin_C1); 
    output_low(pin_C2); 
    delay_ms(500); 

    clr_voice(); 
} 

    if(!input(PIN_B0)){ 
     break; 
    } 
} 

     if(f_next==TRUE){ 
      delay_ms(50); 
      lcd_gotoxy(1,2); 
      printf(lcd_putc,"\r Next : %02d:%02d " ,t_feed.hr,t_feed.min); 

      delay_ms(50); 
     }else{ 
      delay_ms(50); 
      lcd_gotoxy(1,2); 
      printf(lcd_putc,"\r     "); 
      delay_ms(50); 
     } 
    } 

/***************** Rec Voice *********************/ 

void Rec_Voice(){ 

    lcd_gotoxy(1,1); 
    printf(lcd_putc,"\r Record Voice "); 

    show_menu(); 

while(1){ 

    if(input(PIN_B3)==0){ 

    delay_ms(50); 
    lcd_gotoxy(1,2); 
    printf(lcd_putc,"[REC]  [OK]"); 

    delay_ms(250); 
    rec(); 

    break; 
} 

    if(!input(PIN_B0)){ 

     break; 
    } 


} 


    } 

#INT_EXT       
void EXT_ISR(void)     
{ 
if(cnt==0){ 
    delay_ms(250); 
    Set_Feed_Time(); 

    cnt=1; 
} 
//ext_int_flag = TRUE; 
} 

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

void main(){ 

lcd_init(); 

int16 next; 
int tick_delay; 
t_feed.sec_delay = 10; 

clr_voice(); 

    enable_interrupts(GLOBAL); 
    enable_interrupts(INT_EXT); // Set external interrupt 
    ext_int_edge(H_TO_L);  // External interrupt high to low edge 

while(TRUE){ 
    delay_ms(50); 

    if(cnt==1){ 
     delay_ms(250); 
     Set_Period_Time(); 
     delay_ms(250); 
     Set_Time(); 
     delay_ms(250); 

    cnt=0; 
} 

    lcd_gotoxy(1,1); 
    DS1307_ReadTime(); 

    if((t_feed.hr==bcd2bin(RTC.hr)) && (t_feed.min==bcd2bin(RTC.min))){ 
     if (delay_chk==0) { 

     output_high(pin_C0); 
     output_low(pin_C1); 
     output_high(pin_C2); 

     tick_delay=1; 
     delay(); 
     delay_chk=1; 

     next = next_time(24,60,5); 
     t_feed.hr=next/60; 
     t_feed.min=next%60; 

      lcd_gotoxy(1,2); 
      printf(lcd_putc,"\r Next : %02d:%02d " ,t_feed.hr,t_feed.min); 
      delay_ms(50); 

     } 
    }else{ 
     delay_chk=0; 
    } 

    if((tick_delay==1)&&(bcd2bin(RTC.sec)>=30)){ 
     clr_voice(); 
     tick_delay=0; 
    } 
     delay_ms(50); 
     printf(lcd_putc,"\rTime : %2X:%2X:%2X\n", RTC.hr, RTC.min, RTC.sec); 
     delay_ms(250); 

    } 
} 

는 지금은 외부 인터럽트를 제거하고 다음과 같이 코드를 변경합니다. 버튼을 누르면 메뉴가 표시되지만 시간은 여전히 ​​실행되지 않습니다.

void main(){ 

lcd_init(); 

int16 next; 
int tick_delay; 
t_feed.sec_delay = 10; 

clr_voice(); 

while(TRUE){ 
delay_ms(50); 


if(input(PIN_B0)==0){ 
delay_ms(250); 
    Set_Time(); 

    delay_ms(250); 
    Set_Period_Time(); 
    delay_ms(250); 

    Rec_Voice(); 
    delay_ms(250); 
    Play_Voice(); 
    delay_ms(250); 
Set_Feed_Time(); 

} 

    lcd_gotoxy(1,1); 
    DS1307_ReadTime(); 
     printf(lcd_putc,"\rTime : %2X:%2X:%2X\n", RTC.hr, RTC.min, RTC.sec); 
    delay_ms(100); 

    if((t_feed.hr==bcd2bin(RTC.hr)) && (t_feed.min==bcd2bin(RTC.min))){ 
     if (delay_chk==0) { 

    output_high(pin_C0); 
    output_low(pin_C1); 
    output_high(pin_C2); 

    tick_delay=1; 
    delay(); 
    delay_chk=1; 

     next = next_time(24,60,5); 
     t_feed.hr=next/60; 
     t_feed.min=next%60; 

      lcd_gotoxy(1,2); 
      printf(lcd_putc,"\r Next : %02d:%02d " ,t_feed.hr,t_feed.min); 
      delay_ms(50); 


     } 
    }else{ 
    delay_chk=0; 
    } 

    if((tick_delay==1)&&(bcd2bin(RTC.sec)>=30)){ 
    clr_voice(); 
    tick_delay=0; 
    } 
    } 
} 
+2

코드가 상당히 많습니다. 큰 질문을하는 것이 쉽지 않을 것 같습니다. [읽어주세요] (http://www.catb.org/esr/faqs/smart-questions.html#code). – unwind

+0

나는 proteus에서 시뮬레이션 할 때 아무런 문제가 없지만 실제 하드웨어에서는 사용할 수 없습니다. – user572575

+0

크리스탈이 연결되어 있습니까? 명령이 작동하도록 설정합니까? –

답변

0

감사합니다. 이제 DS1307의 첫 번째 시간은 00.00.80입니다. 시간을 설정하면 두 번째로 실행됩니다.

0

와우, 많은 코드입니다. 하드웨어로 컴파일하고 테스트 할 수있는 코드의 가장 작은 부분으로 분해하는 것이 좋습니다. 그런 다음 기능을 추가하여 작동 여부를 확인하십시오. 시뮬레이션은 훌륭하지만 현실 세계에서는 그렇지 않습니다.

Check my post here 코드가 I2C를 통해 DS1307과 통신합니다. Arduino를 사용하여, 이것은 내가 설정 한 가장 간단한 의사 소통 프로젝트였습니다. 업데이트 : 나는 PIC32 chipKIT uC32에서 RTC를 작동 시켰습니다. 내 오작동이 무엇인지 모르겠습니다. : P 필자는 풀업 저항 (2.7kΩ)을 구현했고 보드에 전원 커넥터에 5V가 공급되면 I2C/DS1307은 충분한 전압을 얻지 못한다. USB 전원을 공급 받으면 RTC 시간을 얻을 수 있습니다. 슬프게도, 내 uC32는 9V 또는 12V에서 너무 뜨거워서 RTC를 공급하기 위해 5V를 병렬 처리합니다.

2

이 장치 (DS1307)에는 32.768kHz 수정 결정 대신 20MHz 수정을 사용해야합니다. 그리고 올바른 커패시턴스를 사용하는 것을 잊지 마십시오. 장치 페이지 7의 데이터 시트를 참조하십시오.

관련 문제