Title: โปรแกรมตั้งค่านาฬิกาด้วยPIC16F877ด้วยDS1307 Post by: tellme_kisme on May 21, 2009, 09:42:42 AM พี่คะช่วยแนะนำทีคะว่าเราจะเขียนโปรแกรมตั้งนาฬิกายังไงแต่ไม่ได้ตั้งผ่านhyperlink นะคะตั้งผ่านคียแพด
คือตอนนี้ทำได้แล้วตั้งผ่านhyperlink ดูตามหนังสือ แต่พอมาทำงานจริง..ต่อวงจรจริงแล้ววันเวลามันไม่ตรงคะ มันเป็น FF คะ แต่ตั้งผ่านคียแพคไม่รู้จะทำยังไง..เฮออ..แนะนำทีนะคะ Title: Re: โปรแกรมตั้งค่านาฬิกาด้วยPIC16F877ด้วยDS1307 Post by: smitdh on May 21, 2009, 01:20:21 PM ทีจริงแล้วหลักการตั้งเวลาจาก keypad หรือ hyperterminal มันก็คล้ายๆกันนะครับ
เพียงแต่เราต้องแปลงค่า keycode ที่ได้จาก keypad ไปเป็นตัวเลขแล้วเก็บค่าเวลาที่จะตั้งไว้ใน buffer (RAM) ก่อนแล้ว จึงค่อยนำค่าใน buffer มาเซ็ทลงไปใน RTC อีกที แล้ว Display เป็นอะไรละครับ 7SEG หรือ LCD เพราะการเขียนโค็ดก็จะต่างกัน โดยปกติแล้วเค้ามักจะเขียนรูทีนบน hyperterminal ก่อนเพราะการเตรียมการมันง่ายที่สุด ใช้จอบน PC เป็น Display และใช้ Keyboard บน PC เป็น keypad ลองดูตัวอย่างบน Hyperterminal นี้อีกทีนะครับ อาจจะต่างกันกับ ที่คุณได้มา //******************************************** //DS1307 //Device Address 1101xxxx (DX) //Address // 0 sec bit7 is Ctrl 1=stop 0=start // 1 min // 2 Hour // 3 Day // 4 date // 5 mount // 6 year #case #include <16F628.h> #use delay(clock=4000000) #fuses XT,PUT,BROWNOUT,MCLR,NOWDT,NOPROTECT,NOLVP #use rs232(baud=9600, xmit=PIN_A1, rcv=PIN_A0) #define DS1307_SDA PIN_A2 #define DS1307_SCL PIN_A3 #use i2c(master, sda=DS1307_SDA, scl=DS1307_SCL) #define RTCWRITE 0xD0 #define RTCREAD 0xD1 // initial DS1307 //Sets the specified pin to the input mode. void INIT_DS1307() { output_float(DS1307_SCL); output_float(DS1307_SDA); } //========================== // write data one byte to // DS1307 //========================== void WRITE_DS1307(BYTE address, BYTE data) { short int status; i2c_start(); i2c_write(RTCWRITE); i2c_write(address); i2c_write(data); i2c_stop(); i2c_start(); status=i2c_write(RTCWRITE); while(status==1) { i2c_start(); status=i2c_write(RTCWRITE); } } //Read data one byte from DS1307 //start //W Ctrl+w //W adr //start //W Ctrl+r // BYTE READ_DS1307(BYTE address) { BYTE data; i2c_start(); //Write Ctrl 1101 000 0 ID+ADR+mode W=0 i2c_write(RTCWRITE); i2c_write(address); //Addres i2c_start(); //Read Data i2c_write(RTCREAD); // Write Ctrl 1101 000 1 ID+ADR+mode R=1 data=i2c_read(0); //Get data i2c_stop(); return(data); } void main(void) { char c; int8 sec,min,hour,day,date,month,year; set_tris_a(0B00000001); printf("DS1307\r\nPress Spacebar to Get Time\r\n"); delay_ms(50); INIT_DS1307(); //set write_ds1307(0,0x10); //min write_ds1307(1,0x10); //min write_ds1307(2,0x02); //Hour write_ds1307(3,0x07); //Day write_ds1307(4,0x29); //date write_ds1307(5,0x7); //mount write_ds1307(6,0x9); //year sec=READ_DS1307(0); WRITE_DS1307(0,sec & 0x7F); // enable oscillator(bit 7 =0) while(1) { if(kbhit()) //Check data Receive { c=getc(); if(c==' ') { sec=READ_DS1307(0); // read second min=READ_DS1307(1); // read minute hour=READ_DS1307(2); // read hour day=READ_DS1307(3); // read day date=READ_DS1307(4); // read date month=READ_DS1307(5); // read month year=READ_DS1307(6); // read year //putc(0x0c); printf("Time : %02X:%02X:%02X\r\n",hour,min,sec); printf("Day : %02X\r\n",day); printf("Date : %02X/%02X/20%02X\r\n",date,month,year); } } } } ลองอย่างนี้ซิครับลองดัดแปลงโปรแกรมบน Hyperterminal นี่แหละ โดยจำลอง keypad ของ PC กดที่ละตัว แล้วให้ MCU echo (ส่งผลที่ได้ออกบนจอ) แต่คีย์ที่กดจะเป็น ASCII คือ "1" จะเป็นค่าในhex 0x31 เราจึงต้องแปลง ASCII มาเป็นเลขฐาน10 ก่อน แล้วจึงเขียนลงไปใน RTC |