c - I can't show time from DS1307 with PIC16f88 -
i write program long code alarm clock. use ccs compile use rom =80% ram=8%-51% . simulate program in proteus work. when use in real hardware show time = 00:00:80 , not run second. code read time ds1307. change battery 3v of ds1307 show same time. when push button not show too. think if code wrong should can't run in proteus. how fix ? please me.
this code.
#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) { // tens digit doing multiple subtraction // of 10 binary value. if(temp >= 10) { temp -= 10; retval += 0x10; } else // ones digit adding remainder. { retval += temp; break; } } return(retval); } // input range - 00 99. byte bcd2bin(byte bcd_value) { byte temp; temp = bcd_value; // shifting upper digit right 1 same multiplying 8. temp >>= 1; // isolate bits upper digit. temp &= 0x78; // 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; } /************ 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 */ (i = pos; > 0; i--) { (j = 0; j < i; j++) { /* move max (in [0] [i]) last ([i]) */ if (all[j] > all[j+1]) { /* exchange if bigger next */ t = all[j]; all[j] = all[j+1]; all[j+1] = t; } } } minimval= all[0]; (i = 0; < 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 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 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 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 %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 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); } }
now remove external interrupt , change code this. can show menu when push button time still not run .
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; } } }
you must use device (ds1307) 32.768khz quartz crystal instead 20mhz crystal. , don't forget use right capacitances. see datasheet of device page 7.
Comments
Post a Comment