Problem using Timer1 on PIC16LF15323

Enhanced mid-range devices. PIC12F1xxx and PIC16F1xxx

Problem using Timer1 on PIC16LF15323

Postby alessandrobertini » Fri May 25, 2018 1:18 pm

Hi,
I have a board using a PIC16F15323.
This board is equipped with a relay, a digital input to read, and is configured as i2cbus device slave of another microcontroller.
My board is predominantly in sleep, execpt when timer0 wakes up the micro to read the digital input, or when the host wants to communicate and activates the procedure to set or reset the relay.
My relay is bistable and wants a 5 ms pulse to set or reset its state, so I started the pulse procedure in polling and using timer1 wants to put the board in sleep and finish the pulse procedure at the end of the timer1 period.

The problem is that timer1 doesn't work.

Here is an excerpt of my code :
Code: Select all
/*
   Main application
 */
void main(void)
{
   // initialize the device
   SYSTEM_Initialize();
   
   // enable first reset pulse to bistable relay
   RELAY_OPERATE = 1;
   RELAY_STATE = 0;
   
   // Enable the Global Interrupts
   INTERRUPT_GlobalInterruptEnable();

   // Enable the Peripheral Interrupts
   INTERRUPT_PeripheralInterruptEnable();

   // operative loop
   while (1)
   {
      if( RELAY_OPERATE )
      {
         RELAY_OPERATE = 0;      // reset flag
         //
         TMR1_StartTimer();      // handler start relay
      }
      //
      CPUDOZEbits.IDLEN = 0;
      Sleep();                  // put in sleep
      //
      Nop();
   }
}


void interrupt INTERRUPT_InterruptManager (void)
{
    // interrupt handler
    if(PIE0bits.TMR0IE == 1 && PIR0bits.TMR0IF == 1)
    {
        TMR0_ISR();
    }
    //else
    if(INTCONbits.PEIE == 1 && PIE4bits.TMR1IE == 1 && PIR4bits.TMR1IF == 1)
    {
        TMR1_ISR();
    }
    //else
    if(INTCONbits.PEIE == 1 && PIE3bits.SSP1IE == 1 && PIR3bits.SSP1IF == 1)
    {
        I2C1_ISR();
    }
}


void TMR1_Initialize()
{
   //CKPS 1:1; nT1SYNC do_not_synchronize; TMR1ON off; T1RD16 disabled;
   T1CON = 0x04;

   //T1GE disabled; T1GTM disabled; T1GPOL low; T1GGO done; T1GSPM disabled;
   T1GCON = 0x00;

   //GSS T1G_pin;
   T1GATE = 0x00;

   //CS LFINTOSC;
   T1CLK = 0x03;  // 0x04;

   // Clear Interrupt flag before enabling the interrupt
   PIR4bits.TMR1IF = 0;

   // Enabling TMR1 interrupt.
   PIE4bits.TMR1IE = 1;
   
}


void TMR1_StartTimer(void)
{
   if( RELAY_STATE )
   {
      // start relay set pulse
      R_SET_SetHigh();      
   }
   else
   {
      // start relay reset pulse
      R_RESET_SetHigh();      
   }

   // TMR1 stopped
   T1CONbits.TMR1ON = 0;
   
   // TMR1 - 0xFF65 to obtain 5mSec;
   TMR1L = 0x65;
   TMR1H = 0xFF0;
   
   // Clear Interrupt flag before enabling the interrupt
   PIR4bits.TMR1IF = 0;

   // Start TMR1
   T1CONbits.TMR1ON = 1;
}


void TMR1_ISR(void)
{
   if( RELAY_STATE )
   {
      // end relay set pulse
      R_SET_SetLow();
   }
   else
   {
      // end relay reset pulse
      R_RESET_SetLow();
   }

   // Stop TMR1
   T1CONbits.TMR1ON = 0;

   // Clear the TMR1 interrupt flag
   PIR4bits.TMR1IF = 0;
}


void SYSTEM_Initialize(void)
{

    PIN_MANAGER_Initialize();
    OSCILLATOR_Initialize();
    I2C1_Initialize();
    TMR1_Initialize();
    TMR0_Initialize();
}

void OSCILLATOR_Initialize(void)
{
    // NOSC HFINTOSC; NDIV 1;
    OSCCON1 = 0x60;
    // CSWHOLD may proceed;
    OSCCON3 = 0x00;
    // MFOEN disabled; LFOEN disabled; ADOEN disabled; EXTOEN disabled; HFOEN disabled;
    OSCEN = 0x00;
    // HFFRQ 1_MHz;
    OSCFRQ = 0x00;
    // MFOR not ready;
    OSCSTAT = 0x00;
    // HFTUN 0;
    OSCTUNE = 0x00;
}


My problem is that when the micro executes the following instructions :
// TMR1 - 0xFF65 to obtain 5mSec;
TMR1L = 0x65;
TMR1H = 0xFF0;
the write operation are not executed, timer1 remains with the previous value, and the period between "TMR1_StartTimer" execution and the "TMR1_ISR" activation is about 2 seconds, that is exactly the period of time needed for counting from 0x0000 and the next roll-over with a clock of 31kHz.

Thanks
Alessandro
Last edited by ric on Sat May 26, 2018 11:44 am, edited 1 time in total.
Reason: Put "code" tags around the code.
alessandrobertini
 
Posts: 4
Joined: Thu Apr 09, 2015 11:42 am
PIC experience: Professional 1+ years with MCHP products

Re: Problem using Timer1 on PIC16LF15323

Postby jtemples » Sat May 26, 2018 5:18 pm

Why are you writing 12 bits to TMR1H? Why are you not using RD16 mode?
jtemples
Verified identity
 
Posts: 195
Joined: Sun May 25, 2014 2:23 am
Location: The 805
PIC experience: Professional 5+ years with MCHP products

Re: Problem using Timer1 on PIC16LF15323

Postby ric » Mon May 28, 2018 3:00 am

Also posted at http://www.microchip.com/forums/m1053232.aspx
where the bad TMR1H value has already been pointed out.

RD16 shouldn't matter, as the value is only written when the timer is stopped.
No code has been shown for the R_SET_SetHigh(), R_RESET_SetHigh(), R_SET_SetLow(), R_RESET_SetLow() functions.
The last two are called from inside the ISR, so could cause havoc if they enable interrupts.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: Problem using Timer1 on PIC16LF15323

Postby alessandrobertini » Thu May 31, 2018 8:18 am

Hi,
thanks to jtempes and ric for your replay.
1.) "Why are you writing 12 bits to TMR1H" ... I fixed this error writing the correct value (0xFF), but the result was the same
2.) the code for R_SET_SetHigh(), R_RESET_SetHigh(), R_SET_SetLow(), R_RESET_SetLow() functions are simple... they are macros. here are the code:
#define R_SET_SetHigh() do { LATAbits.LATA2 = 1; } while(0)
#define R_SET_SetLow() do { LATAbits.LATA2 = 0; } while(0)
#define R_RESET_SetHigh() do { LATCbits.LATC3 = 1; } while(0)
#define R_RESET_SetLow() do { LATCbits.LATC3 = 0; } while(0)

How we can see, the can't interfere with the irq execution.

Is there someone that have used timer1 with this PIC?
alessandrobertini
 
Posts: 4
Joined: Thu Apr 09, 2015 11:42 am
PIC experience: Professional 1+ years with MCHP products

Re: Problem using Timer1 on PIC16LF15323

Postby AussieSusan » Fri Jun 01, 2018 4:09 am

Not sure why you want such a complex macro expansion where directly setting the LAT bit would be clearer. Also (and this is a bit of a guess) a smart-enough compiler may see the 'while(0)' at the end and decide that the whole loop can be optimised away. Probably shouldn't as the C rules are that a while-do loop is always executed at least once but.....
Is the WDT turned on?
Just to check that the timer is working, have you created a simple version of the code that initialises the timer, starts it and then blocks until the IF bit is set without using interrupts? That way you can make sure that you are writing to the register correct and the clocks are 'ticking' as expected. Then you can add back in the interrupt aspects.
Susan
AussieSusan
Verified identity
 
Posts: 173
Joined: Mon Jun 16, 2014 4:45 am
PIC experience: Experienced Hobbyist

Re: Problem using Timer1 on PIC16LF15323

Postby alessandrobertini » Fri Jun 01, 2018 7:25 am

Hi Susan,
thank for your reply.
The macros for the set/reset bit are written by the C code configurator of MPLAB-X and is not my idea. However they work fine and there is no interferation with the irq execution.
I did all the tests with and without irq. Always the same result. With the debugger, breaking exactly before the FIRST Timer1 write instructions (not inside the irq timer1 routine) I see that executing the 0xFF65 write operation, the timer1 remains unchanged. I suspect that this timer1 is in a read-only state because there is a procedure to unlock that i don't make.
alessandrobertini
 
Posts: 4
Joined: Thu Apr 09, 2015 11:42 am
PIC experience: Professional 1+ years with MCHP products

Re: Problem using Timer1 on PIC16LF15323

Postby ric » Fri Jun 01, 2018 1:37 pm

I suspect a bug in the debugger/simulator.
I would always rig up a crude serial port for output and do my own debugging.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products


Return to 14-Bit Core (enhanced)

Who is online

Users browsing this forum: No registered users and 3 guests

cron