PIC32 RTCC running too fast 1min = 10 sec

cpicrtc

I'm having problems with the clock settings on my PIC32.

One minute has a duration of 10s with the current settings.

Does anyone know where I have to change my settings?

Here's the code:

// Master header file for all peripheral library includes
#include 

// configuration settings
#pragma config FNOSC = PRIPLL, POSCMOD = HS, FPLLMUL = MUL_18, FPLLIDIV = DIV_2, FPBDIV = DIV_2, FPLLODIV = DIV_1
#pragma config FWDTEN = OFF

// pin definitions
#define PPEins      LATFbits.LATF4
#define PPZwei      LATDbits.LATD15
#define PPDrei      LATDbits.LATD14
#define PPVier      LATBbits.LATB15
#define MHUhr       LATBbits.LATB3      // provisorisch
#define PMFuenf     LATBbits.LATB11
#define PMZehn      LATBbits.LATB10
#define PMViertel   LATAbits.LATA15
#define PMZwanzig   LATAbits.LATA1
#define PMVor       LATAbits.LATA14
#define PMNach      LATAbits.LATA5
#define PMHalb      LATFbits.LATF13
#define PHEins      LATAbits.LATA4
#define PHZwei      LATAbits.LATA3
#define PHDrei      LATFbits.LATF12
#define PHVier      LATAbits.LATA2
#define PHFuenf     LATBbits.LATB13
#define PHSechs     LATBbits.LATB12
#define PHSieben    LATFbits.LATF8
#define PHAcht      LATFbits.LATF2
#define PHNeun      LATBbits.LATB14
#define PHZehn      LATFbits.LATF5
#define PHElf       LATBbits.LATB5      // provisorisch
#define PHZwoelf    LATEbits.LATE9      // provisorisch


// + BUTTON SETTINGS
// D2 Als output für (5V Ersatz) für Buttons definieren
// und auch gleich als high setzen
// + BUZZER SETTINGS


int main(void) {

    // PORT SETTINGS
    DDPCONbits.JTAGEN = 0; // disable JTAGport, free up PORTA
    TRISFbits.TRISF4 = 0;       // PPEins
    TRISDbits.TRISD15 = 0;      // PPZwei
    TRISDbits.TRISD14 = 0;      // PPDrei
    TRISBbits.TRISB15 = 0;      // PPVier
    // TODO: TRIS für PMUhr
    TRISBbits.TRISB11 = 0;      // PMFuenf
    TRISBbits.TRISB10 = 0;      // PMZehn
    TRISAbits.TRISA15 = 0;      // PMViertel
    TRISAbits.TRISA1 = 0;       // PMZwanzig
    TRISAbits.TRISA14 = 0;      // PMVor
    TRISAbits.TRISA5 = 0;       // PMNach
    TRISFbits.TRISF13 = 0;      // PMHalb
    TRISAbits.TRISA4 = 0;       // PHEins
    TRISAbits.TRISA3 = 0;       // PHZwei
    TRISFbits.TRISF12 = 0;      // PHDrei
    TRISAbits.TRISA2 = 0;       // PHVier
    TRISBbits.TRISB13 = 0;      // PHFuenf
    TRISBbits.TRISB12 = 0;      // PHSechs
    TRISFbits.TRISF8 = 0;       // PHSieben
    TRISFbits.TRISF2 = 0;       // PHAcht
    TRISBbits.TRISB14 = 0;      // PHNeun
    TRISFbits.TRISF5 = 0;       // PHZehn
    // TODO: elf
    // TODO: zwölf

    // Initial pin settings
    PPEins = 0;
    PPZwei = 0;
    PPDrei = 0;
    PPVier = 0;
    MHUhr = 0;
    PMFuenf = 0;
    PMZehn = 0;
    PMViertel = 0;
    PMZwanzig = 0;
    PMVor = 0;
    PMNach = 0;
    PMHalb = 0;
    PHEins = 0;
    PHZwei = 0;
    PHDrei = 0;
    PHVier = 0;
    PHFuenf = 0;
    PHSechs = 0;
    PHSieben = 0;
    PHAcht = 0;
    PHNeun = 0;
    PHZehn = 0;
    PHElf = 0;
    PHZwoelf = 0;

    rtccTime    tm, tAlrm;          // time structure
    rtccDate    dt, dAlrm;          // date structure

    // Configure the device for maximum performance.
    // This macro sets flash wait states, PBCLK divider and DRM wait states based on the specified
    // clock frequency. It also turns on the cache mode if avaialble.
    // Based on the current frequency, the PBCLK divider will be set at 1:2. This knoweldge
    // is required to correctly set UART baud rate, timer reload value and other time sensitive
    // setting.
    SYSTEMConfigPerformance(72000000L);

    PPEins = 1;
    delay_us(1000000); // TEST 1
    PPEins = 0;

    RtccInit();   // init the RTCC

    while(RtccGetClkStat()!=RTCC_CLK_ON);   // wait for the SOSC to be actually running and RTCC to have its clock source
                                            // could wait here at most 32ms
    PPZwei = 1;
    delay_us(1000000); // TEST 2
    PPZwei = 0;

    RtccOpen(0x10073000, 0x07011602, 0);

    PPDrei = 1;
    delay_us(1000000); // TEST 3
    PPDrei = 0;

    while(1){

        RtccGetTimeDate(&tm, &dt);

        // update single minutes
        int singleminutes = (int) (unbcd(tm.min)%5);
        switch(singleminutes){
            case 0:
                PPEins = 0;
                PPZwei = 0;
                PPDrei = 0;
                PPVier = 0;
                break;
            case 1:
                PPEins = 1;
                PPZwei = 0;
                PPDrei = 0;
                PPVier = 0;
                break;
            case 2:
                PPEins = 1;
                PPZwei = 1;
                PPDrei = 0;
                PPVier = 0;
                break;
            case 3:
                PPEins = 1;
                PPZwei = 1;
                PPDrei = 1;
                PPVier = 0;
                break;
            case 4:
                PPEins = 1;
                PPZwei = 1;
                PPDrei = 1;
                PPVier = 1;
                break;
        }

        // update 5 minutes
        int nfminutes = (int) (unbcd(tm.min)/5);
        switch(nfminutes){
            case 0:
                MHUhr       = 1;
                PMFuenf     = 0;
                PMZehn      = 0;
                PMViertel   = 0;
                PMZwanzig   = 0;
                PMVor       = 0;
                PMNach      = 0;
                PMHalb      = 0;
                break;
            case 1:
                MHUhr       = 0;
                PMFuenf     = 1;
                PMZehn      = 0;
                PMViertel   = 0;
                PMZwanzig   = 0;
                PMVor       = 0;
                PMNach      = 1;
                PMHalb      = 0;
                break;
            case 2:
                MHUhr       = 0;
                PMFuenf     = 0;
                PMZehn      = 1;
                PMViertel   = 0;
                PMZwanzig   = 0;
                PMVor       = 0;
                PMNach      = 1;
                PMHalb      = 0;
                break;
            case 3:
                MHUhr       = 0;
                PMFuenf     = 0;
                PMZehn      = 0;
                PMViertel   = 1;
                PMZwanzig   = 0;
                PMVor       = 0;
                PMNach      = 1;
                PMHalb      = 0;
                break;
            case 4:
                MHUhr       = 0;
                PMFuenf     = 0;
                PMZehn      = 0;
                PMViertel   = 0;
                PMZwanzig   = 1;
                PMVor       = 0;
                PMNach      = 1;
                PMHalb      = 0;
                break;
            case 5:
                MHUhr       = 0;
                PMFuenf     = 1;
                PMZehn      = 0;
                PMViertel   = 0;
                PMZwanzig   = 0;
                PMVor       = 1;
                PMNach      = 0;
                PMHalb      = 1;
                break;
            case 6:
                MHUhr       = 0;
                PMFuenf     = 0;
                PMZehn      = 0;
                PMViertel   = 0;
                PMZwanzig   = 0;
                PMVor       = 0;
                PMNach      = 0;
                PMHalb      = 1;
                break;
            case 7:
                MHUhr       = 0;
                PMFuenf     = 1;
                PMZehn      = 0;
                PMViertel   = 0;
                PMZwanzig   = 0;
                PMVor       = 0;
                PMNach      = 1;
                PMHalb      = 1;
                break;
            case 8:
                MHUhr       = 0;
                PMFuenf     = 0;
                PMZehn      = 0;
                PMViertel   = 0;
                PMZwanzig   = 1;
                PMVor       = 1;
                PMNach      = 0;
                PMHalb      = 0;
                break;
            case 9:
                MHUhr       = 0;
                PMFuenf     = 0;
                PMZehn      = 0;
                PMViertel   = 1;
                PMZwanzig   = 0;
                PMVor       = 1;
                PMNach      = 0;
                PMHalb      = 0;
                break;
            case 10:
                MHUhr       = 0;
                PMFuenf     = 0;
                PMZehn      = 1;
                PMViertel   = 0;
                PMZwanzig   = 0;
                PMVor       = 1;
                PMNach      = 0;
                PMHalb      = 0;
                break;
            case 11:
                MHUhr       = 0;
                PMFuenf     = 1;
                PMZehn      = 0;
                PMViertel   = 0;
                PMZwanzig   = 0;
                PMVor       = 1;
                PMNach      = 0;
                PMHalb      = 0;
                break;
        }

        // update hours
        int hours = (int) (unbcd(tm.hour)%12);
        if(nfminutes>=5) hours++;
        switch(hours){
            case 0:
                PHEins      = 0;
                PHZwei      = 0;
                PHDrei      = 0;
                PHVier      = 0;
                PHFuenf     = 0;
                PHSechs     = 0;
                PHSieben    = 0;
                PHAcht      = 0;
                PHNeun      = 0;
                PHZehn      = 0;
                PHElf       = 0;
                PHZwoelf    = 1;
                break;
            case 1:
                PHEins      = 1;
                PHZwei      = 0;
                PHDrei      = 0;
                PHVier      = 0;
                PHFuenf     = 0;
                PHSechs     = 0;
                PHSieben    = 0;
                PHAcht      = 0;
                PHNeun      = 0;
                PHZehn      = 0;
                PHElf       = 0;
                PHZwoelf    = 0;
                break;
            case 2:
                PHEins      = 0;
                PHZwei      = 1;
                PHDrei      = 0;
                PHVier      = 0;
                PHFuenf     = 0;
                PHSechs     = 0;
                PHSieben    = 0;
                PHAcht      = 0;
                PHNeun      = 0;
                PHZehn      = 0;
                PHElf       = 0;
                PHZwoelf    = 0;
                break;
            case 3:
                PHEins      = 0;
                PHZwei      = 0;
                PHDrei      = 1;
                PHVier      = 0;
                PHFuenf     = 0;
                PHSechs     = 0;
                PHSieben    = 0;
                PHAcht      = 0;
                PHNeun      = 0;
                PHZehn      = 0;
                PHElf       = 0;
                PHZwoelf    = 0;
                break;
            case 4:
                PHEins      = 0;
                PHZwei      = 0;
                PHDrei      = 0;
                PHVier      = 1;
                PHFuenf     = 0;
                PHSechs     = 0;
                PHSieben    = 0;
                PHAcht      = 0;
                PHNeun      = 0;
                PHZehn      = 0;
                PHElf       = 0;
                PHZwoelf    = 0;
                break;
            case 5:
                PHEins      = 0;
                PHZwei      = 0;
                PHDrei      = 0;
                PHVier      = 0;
                PHFuenf     = 1;
                PHSechs     = 0;
                PHSieben    = 0;
                PHAcht      = 0;
                PHNeun      = 0;
                PHZehn      = 0;
                PHElf       = 0;
                PHZwoelf    = 0;
                break;
            case 6:
                PHEins      = 0;
                PHZwei      = 0;
                PHDrei      = 0;
                PHVier      = 0;
                PHFuenf     = 0;
                PHSechs     = 1;
                PHSieben    = 0;
                PHAcht      = 0;
                PHNeun      = 0;
                PHZehn      = 0;
                PHElf       = 0;
                PHZwoelf    = 0;
                break;
            case 7:
                PHEins      = 0;
                PHZwei      = 0;
                PHDrei      = 0;
                PHVier      = 0;
                PHFuenf     = 0;
                PHSechs     = 0;
                PHSieben    = 1;
                PHAcht      = 0;
                PHNeun      = 0;
                PHZehn      = 0;
                PHElf       = 0;
                PHZwoelf    = 0;
                break;
            case 8:
                PHEins      = 0;
                PHZwei      = 0;
                PHDrei      = 0;
                PHVier      = 0;
                PHFuenf     = 0;
                PHSechs     = 0;
                PHSieben    = 0;
                PHAcht      = 1;
                PHNeun      = 0;
                PHZehn      = 0;
                PHElf       = 0;
                PHZwoelf    = 0;
                break;
            case 9:
                PHEins      = 0;
                PHZwei      = 0;
                PHDrei      = 0;
                PHVier      = 0;
                PHFuenf     = 0;
                PHSechs     = 0;
                PHSieben    = 0;
                PHAcht      = 0;
                PHNeun      = 1;
                PHZehn      = 0;
                PHElf       = 0;
                PHZwoelf    = 0;
                break;
            case 10:
                PHEins      = 0;
                PHZwei      = 0;
                PHDrei      = 0;
                PHVier      = 0;
                PHFuenf     = 0;
                PHSechs     = 0;
                PHSieben    = 0;
                PHAcht      = 0;
                PHNeun      = 0;
                PHZehn      = 1;
                PHElf       = 0;
                PHZwoelf    = 0;
                break;
            case 11:
                PHEins      = 0;
                PHZwei      = 0;
                PHDrei      = 0;
                PHVier      = 0;
                PHFuenf     = 0;
                PHSechs     = 0;
                PHSieben    = 0;
                PHAcht      = 0;
                PHNeun      = 0;
                PHZehn      = 0;
                PHElf       = 1;
                PHZwoelf    = 0;
                break;
        }

        // BUTTON CHECKING

    } // end: while(1)

}

int unbcd(int bcd) {
    return ((bcd>>4)*10)+bcd%16;
}

int bcd(int dec) {
    return ((dec/10)

Best Answer

This doesn't answer your question, but might make the code a little easier for you to debug. The case statements are really long and may not be the best way to explain what you are doing with your outputs. I make no guarantees that the code is operational (I have not run it at all), but this should get you thinking about file size and readability.

Your singleminutes case statement has a truth table like this:

//    | out
//  in| 0 1 2 3 4
// ---------------
//  0 | 0 0 0 0 0
//  1 | 0 1 0 0 0
//  2 | 0 1 1 0 0
//  3 | 0 1 1 1 0
//  4 | 0 1 1 1 1

which might be better represented with output-centric code like this:

if (singleminutes >= 1)
    PPEins = 1;
else
    PPEins = 0;

if (singleminutes >= 2)
    PPZwei = 1;
else
    PPZwei = 0;

if (singleminutes >= 3)
    PPDrei = 1;
else
    PPDrei = 0;

if (singleminutes >= 4)
    PPVier = 1;
else
    PPVier = 0;

The nfminutes is a little more complicated, but here is the Truth Table:

//   | MHUhr PMFuenf PMZehn PMViertel PMZwanzig PMVor PMNach PMHalb |        |
// --|--------------------------------------------------------------|--------|-----
// 0 | 1     0       0      0         0         0     0      0      | 1000 0 |  000
// 1 | 0     1       0      0         0         0     1      0      | 0100 0 |  010
// 2 | 0     0       1      0         0         0     1      0      | 0010 0 |  010
// 3 | 0     0       0      1         0         0     1      0      | 0001 0 |  010
// 4 | 0     0       0      0         1         0     1      0      | 0000 1 |  010
// 5 | 0     1       0      0         0         1     0      1      | 0000 0 |  101
// 6 | 0     0       0      0         0         0     0      1      | 0000 0 |  001
// 7 | 0     1       0      0         0         0     1      1      | 0100 0 |  011
// 8 | 0     0       0      0         1         1     0      0      | 0000 1 |  100
// 9 | 0     0       0      1         0         1     0      0      | 0001 0 |  100
//10 | 0     0       1      0         0         1     0      0      | 0010 0 |  100
//11 | 0     1       0      0         0         1     0      0      | 0100 0 |  100

and again some output-centric code:

    // MHUhr PMFuenf PMZehn PMViertel PMZwanzig
if( nfminutes == 0 )
    MHUhr = 1;
else
    MHUhr = 0;

if(( nfminutes == 1 ) || (nfminutes == 5) || (nfminutes == 7) || (nfminutes == 11))
    PMFuenf = 1;
else
    PMFuenf = 0;

if(( nfminutes == 2 ) || (nfminutes == 10) )
    PMZehn = 1;
else
    PMZehn = 0;
if(( nfminutes == 3 ) || (nfminutes == 9) )
    PMViertel = 1;
else
    PMViertel = 0;

if(( nfminutes == 4 ) || (nfminutes == 8) )
    PMZwanzig = 1;
else
    PMZwanzig = 0;


// PMVor PMNach PMHalb
if( ((nfminutes >= 1 ) && (nfminutes <= 4 )) || (nfminutes == 7))
    PMNach = 1;
else
    PMNach = 0;

if( (nfminutes >= 5) && (nfminutes <= 7 )
    PMHalb = 1;
    else
        PMHalb = 0;
if(nfminutes >=8)
    PMVor  = 1;
else
    PMVor  = 0;

The code above might do well with some #defines too

#define UHR     0
#define PHUENF_NACH 1
#define ZEHN_NACH   2
...
if(nfminutes == UHR)

Again for hours. Truth Table:

      | 12  1  2  3  4  5  6  7  8  9 10 11
//----|------------------------------------
// 0  | 1  0  0  0  0  0  0  0  0  0  0  0 
// 1  | 0  1  0  0  0  0  0  0  0  0  0  0 
// 2  | 0  0  1  0  0  0  0  0  0  0  0  0 
// 3  | 0  0  0  1  0  0  0  0  0  0  0  0 
// 4  | 0  0  0  0  1  0  0  0  0  0  0  0 
// 5  | 0  0  0  0  0  1  0  0  0  0  0  0 
// 6  | 0  0  0  0  0  0  1  0  0  0  0  0 
// 7  | 0  0  0  0  0  0  0  1  0  0  0  0 
// 8  | 0  0  0  0  0  0  0  0  1  0  0  0 
// 9  | 0  0  0  0  0  0  0  0  0  1  0  0 
// 10 | 0  0  0  0  0  0  0  0  0  0  1  0 
// 11 | 0  0  0  0  0  0  0  0  0  0  0  1

and code. Slightly different structure with all outputs being cleared, then only the correct output turned on.

// one-hot, clear all will not cause a glitch
PHZwoelf    = 0;
PHEins      = 0;
PHZwei      = 0;
PHDrei      = 0;
PHVier      = 0;
PHFuenf     = 0;
PHSechs     = 0;
PHSieben    = 0;
PHAcht      = 0;
PHNeun      = 0;
PHZehn      = 0;
PHElf       = 0;

if( hours == 0 )
    PHZwoelf = 1;   
if( hours == 1 )
    PHEins = 1;
if( hours == 2 )
    PHZwei = 1; 
if( hours == 3 )
    PHDrei = 1; 
if( hours == 4 )
    PHVier = 1; 
if( hours == 5 )
    PHFuenf = 1;    
if( hours == 6 )
    PHSechs = 1;    
if( hours == 7 )
    PHSieben = 1;   
if( hours == 8 )
    PHAcht = 1; 
if( hours == 9 )
    PHNeun = 1; 
if( hours == 10 )
    PHZehn = 1; 
if( hours == 11 )
    PHElf = 1;  

All this also allows you to do your input calculations together before your case statements.

// update single minutes
int singleminutes = (int) (unbcd(tm.min)%5);    // 1, 2, 3, 4
// update 5 minutes
int nfminutes = (int) (unbcd(tm.min)/5);    // Fuenf Nach, Zehn Nach, ...
// update hours
int hours = (int) (unbcd(tm.hour)%12);      // 12, 1, 2, 3, 4...
if(nfminutes>=5) hours++;           // 7:25 = Fuenf Vor Halb Acht (8)