mariuszoll
Member level 5
- Joined
- Aug 28, 2012
- Messages
- 82
- Helped
- 1
- Reputation
- 2
- Reaction score
- 0
- Trophy points
- 1,286
- Activity points
- 2,147
Hi,
I am working on a calendar/clock application that uses PCF8583 RTC and PIC18F4550. The pull-up resistors on SCL and SDA are both of 4k7. I use serial communication (USART) and Hyperterminal to display the information. I display the date on dd/mm/yy format and the time on hh/mm/ss format. It does not work properly as expected. It displays:
Date: 45/25/12
Time: 45:165:1
.............
45:165:59
As far the seconds are concerned, they are incrementing correctly from 1 to 59.
Could you help me please to fix this problem?
Attached you can find my code:
Thank you in advance.
I am working on a calendar/clock application that uses PCF8583 RTC and PIC18F4550. The pull-up resistors on SCL and SDA are both of 4k7. I use serial communication (USART) and Hyperterminal to display the information. I display the date on dd/mm/yy format and the time on hh/mm/ss format. It does not work properly as expected. It displays:
Date: 45/25/12
Time: 45:165:1
.............
45:165:59
As far the seconds are concerned, they are incrementing correctly from 1 to 59.
Could you help me please to fix this problem?
Attached you can find my code:
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 #include <p18f4550.h> #include <delays.h> #include <sw_uart.h> #include <i2c.h> // Pragma, internal register configuration #pragma config FOSC = INTOSCIO_EC //Internal oscillator, port function on RA6, EC used by USB #pragma config WDT = OFF // watch dog disabled #pragma config IESO = OFF //Oscillator Switchover mode disabled //#pragma config PWRT = OFF //PWRT disabled #pragma config BORV = 2 // output voltage test 2V #pragma config PBADEN=OFF //PORTB<4:0> pins are configured as digital I/O on Reset #pragma config STVREN=OFF //Stack full/underflow will not cause Reset #pragma config LVP=OFF //Single-Supply ICSP disabled #pragma config XINST=OFF //Instruction set extension and Indexed Addressing mode disabled (Legacy mode) // definitions #define PCF8583_WRITE_ADDRESS 0xA0 #define PCF8583_READ_ADDRESS 0xA1 // Register addresses #define PCF8583_CTRL_STATUS_REG 0x00 #define PCF8583_100S_REG 0x01 #define PCF8583_SECONDS_REG 0x02 #define PCF8583_MINUTES_REG 0x03 #define PCF8583_HOURS_REG 0x04 #define PCF8583_DATE_REG 0x05 #define PCF8583_MONTHS_REG 0x06 #define PCF8583_TIMER_REG 0x07 #define PCF8583_ALARM_CONTROL_REG 0x08 #define PCF8583_ALARM_100S_REG 0x09 #define PCF8583_ALARM_SECS_REG 0x0A #define PCF8583_ALARM_MINS_REG 0x0B #define PCF8583_ALARM_HOURS_REG 0x0C #define PCF8583_ALARM_DATE_REG 0x0D #define PCF8583_ALARM_MONTHS_REG 0x0E #define PCF8583_ALARM_TIMER_REG 0x0F // Use the first NVRAM address for the year byte. #define PCF8583_YEAR_REG 0x10 // Commands for the Control/Status register. #define PCF8583_START_COUNTING 0x00 #define PCF8583_STOP_COUNTING 0x80 // Structure defines the user's date and time data. typedef struct{ unsigned char seconds; // 0 to 59 unsigned char minutes; // 0 to 59 unsigned char hours; // 0 to 23 unsigned char day; // 1 to 31 unsigned char month; // 1 to 12 unsigned char year; // 0 to 99 unsigned char weekday; // 0=Sunday, 1=Monday, etc } date_time_t; // Variables /** L O C A L F U N C T I O N S *******************************************/ void init_UART(void) { TXSTAbits.TX9=0; TXSTAbits.TXEN=1; TXSTAbits.SYNC=0; TXSTAbits.BRGH=1; TXSTAbits.TX9D=0; RCSTAbits.SPEN=1; BAUDCONbits.BRG16=0; SPBRG=25; // 9600KBaud } void PCF8583_write_byte(char address, char data) { IdleI2C(); StartI2C(); //start while(SSPCON2bits.SEN); Delay1TCY(); // delay 5us (see datasheet pg20) Delay1TCY(); Delay1TCY(); Delay1TCY(); WriteI2C(PCF8583_WRITE_ADDRESS); // address and write flag IdleI2C(); WriteI2C(address); IdleI2C(); WriteI2C(data); IdleI2C(); StopI2C(); while(SSPCON2bits.PEN); // stop Delay1TCY(); // delay 4us (see datasheet pg20) Delay1TCY(); Delay1TCY(); Delay1TCY(); } char PCF8583_read_byte(char address) { char retval; IdleI2C(); StartI2C(); //start while(SSPCON2bits.SEN); Delay1TCY(); // delay 5us (see datasheet pg20) Delay1TCY(); Delay1TCY(); Delay1TCY(); WriteI2C(PCF8583_WRITE_ADDRESS); // address and write flag IdleI2C(); WriteI2C(address); IdleI2C(); RestartI2C(); //restart while(SSPCON2bits.RSEN); Delay1TCY(); // delay 5us (see datasheet pg20) Delay1TCY(); Delay1TCY(); Delay1TCY(); WriteI2C(PCF8583_READ_ADDRESS); //address and read flag IdleI2C(); retval=ReadI2C(); IdleI2C(); StopI2C(); while(SSPCON2bits.PEN); // stop Delay1TCY(); // delay 4us (see datasheet pg20) Delay1TCY(); Delay1TCY(); Delay1TCY(); return(retval); } void PCF8583_init(void) { PCF8583_write_byte(PCF8583_CTRL_STATUS_REG,PCF8583 _START_COUNTING); } // This function converts an 8 bit binary value // to an 8 bit BCD value. // The input range must be from 0 to 99 unsigned char bin2bcd(unsigned char x) { unsigned char y; y=(x / 10) << 4; y= y | (x % 10); return(y); } // This function converts an 8 bit BCD value to // an 8 bit binary value. // The input range must be from 00 to 99. unsigned char bcd2bin(unsigned char x) { unsigned char binary; binary = ((x & 0xF0 )>>4 ) * 10 + (x & 0x0F); return (binary); } void PCF8583_set_datetime( date_time_t *dt) { unsigned char bcd_sec; unsigned char bcd_min; unsigned char bcd_hrs; unsigned char bcd_day; unsigned char bcd_mon; // Convert the input date/time into BCD values // that are formatted for the PCF8583 registers bcd_sec=bin2bcd(dt->seconds); bcd_min=bin2bcd(dt->minutes); bcd_hrs=bin2bcd(dt->hours); bcd_day=bin2bcd(dt->day) | (dt->year <<6); bcd_mon=bin2bcd(dt->month) |(dt->weekday << 5); // Stop the RTC from counting, before we write to the date and time registers PCF8583_write_byte(PCF8583_CTRL_STATUS_REG,PCF8583 _STOP_COUNTING); // Write to the date and time registers IdleI2C(); StartI2C(); //start while(SSPCON2bits.SEN); Delay1TCY(); // delay 5us (see datasheet pg20) Delay1TCY(); Delay1TCY(); Delay1TCY(); WriteI2C(PCF8583_WRITE_ADDRESS); // address and write flag IdleI2C(); WriteI2C(PCF8583_100S_REG); // Start at 100's reg IdleI2C(); WriteI2C(0x00); // Set 100's reg=0 IdleI2C(); WriteI2C(bcd_sec); IdleI2C(); WriteI2C(bcd_min); IdleI2C(); WriteI2C(bcd_hrs); IdleI2C(); WriteI2C(bcd_day); IdleI2C(); WriteI2C(bcd_mon); IdleI2C(); StopI2C(); while(SSPCON2bits.PEN); // stop Delay1TCY(); // delay 4us (see datasheet pg20) Delay1TCY(); Delay1TCY(); Delay1TCY(); // Write the year to the first NVRAM location. Live it in binary format. PCF8583_write_byte(PCF8583_YEAR_REG,dt->year); // Now allow the RTC to start counting again PCF8583_write_byte(PCF8583_CTRL_STATUS_REG,PCF8583 _START_COUNTING); } //Read the Date and Time from the hardware registers in the PCF8583 void PCF8583_read_datetime(date_time_t *dt) { unsigned char year_bits; unsigned char year; unsigned char bcd_sec; unsigned char bcd_min; unsigned char bcd_hrs; unsigned char bcd_day; unsigned char bcd_mon; // Read the date/time registers inside the PCF8583 IdleI2C(); StartI2C(); //start while(SSPCON2bits.SEN); Delay1TCY(); // delay 5us (see datasheet pg20) Delay1TCY(); Delay1TCY(); Delay1TCY(); WriteI2C(PCF8583_WRITE_ADDRESS); // address and write flag IdleI2C(); WriteI2C(PCF8583_SECONDS_REG); // Start at secods reg IdleI2C(); RestartI2C(); //start while(SSPCON2bits.RSEN); Delay1TCY(); // delay 5us (see datasheet pg20) Delay1TCY(); Delay1TCY(); Delay1TCY(); WriteI2C(PCF8583_READ_ADDRESS); // address and write flag IdleI2C(); bcd_sec=ReadI2C(); IdleI2C(); bcd_min=ReadI2C(); IdleI2C(); bcd_hrs=ReadI2C(); IdleI2C(); bcd_day=ReadI2C(); IdleI2C(); bcd_mon=ReadI2C(); IdleI2C(); StopI2C(); while(SSPCON2bits.PEN); // stop Delay1TCY(); // delay 4us (see datasheet pg20) Delay1TCY(); Delay1TCY(); Delay1TCY(); // Convert the date/time values from BCD to // unsigned 8-bit integers. Unpack the bits // in the PCF8583 registers where required. dt->seconds = bcd2bin(bcd_sec); dt->minutes = bcd2bin(bcd_min); dt->hours = bcd2bin(bcd_hrs & 0x3F); dt->day = bcd2bin(bcd_day & 0x3F); dt->month = bcd2bin(bcd_mon & 0x1F); dt->weekday=bcd_mon >> 5; year_bits=bcd_day >> 6 ; // Read the year byte from NVRAM. // This is an added feature of this driver. year = PCF8583_read_byte(PCF8583_YEAR_REG); /* //Check if the two " year bits " were incremented by the PCF8583. while(year_bits!= (year & 3)) year++; dt->year=year; // Now update the year byte in the NVRAM inside the PCF8583 PCF8583_write_byte(PCF8583_YEAR_REG, year); */ } void print_date_time(char t) { int k,n,j,m,c; unsigned char data; char string[5]; data=t; n=data; j=0; while(n!=0) { c=n%10; n=n/10; string[j]=c+48; j++; } m=j-1; while(m>=0) { WriteUSART(string[m]); while(!TXSTAbits.TRMT); m--; } } ///////////////////functia main/////////////////////////////////////////// void main(void) { date_time_t dt; //Outputs: TRISCbits.TRISC6=0; // UART__TX //Inputs: TRISBbits.TRISB0=1; // I2C_SDA TRISBbits.TRISB1=1; // I2C_SCL TRISCbits.TRISC7=1; // UART__RX // Oscillator frequency OSCCON=0b01100110; // 4MHz // the configuration of the functions of port pins ADCON1=0b00001111; // digital port configured // Initializations init_UART(); TXREG=12; // new page // I2C settings SSPSTAT=0x80; // SLEW RATE CONTROL DISABLED FOR std mode (100khz) SSPCON1=0x28; // i2c master mode, serial synch enable SSPCON2=0x00; SSPADD=0x09; // for 100Khz PCF8583_init(); dt.seconds=0; // 0 seconds dt.minutes=25; // 25 minutes dt.hours=10; // 10am - 24-hour format dt.day=27; // 27 dt.month=8; // August dt.weekday=1; // Monday dt.year=12; // 2012 PCF8583_set_datetime(&dt); while(1) { // Read the date and time from the PCF8583 and dispaly it once per second Delay10KTCYx(100); PCF8583_read_datetime(&dt); print_date_time(dt.weekday); TXREG=32; // space TXREG=32; // space print_date_time(dt.day); TXREG=47; // / print_date_time(dt.month); TXREG=47; print_date_time(dt.year); TXREG=32; // space TXREG=32; // space print_date_time(dt.hours); TXREG=58; // : print_date_time(dt.minutes); TXREG=58; print_date_time(dt.seconds); TXREG=10; // new line TXREG=13; //carriage return } } // main
Thank you in advance.
Last edited by a moderator: