1
\$\begingroup\$

I am using timer1 on DSPIC30f4011 to generate an interrupt every one millisecond. However, the timer1 ISR is not executed every time on POR (2 out of 10 times). If I turn on the power for the chip and use MCLR (switch it to high or low) the timer will work everytime on a MCLR reset. Is there anything that I need to clear in the software? I already reset the timer1 flag.

unsigned char t2=0;
unsigned char  t1=0;
unsigned char t0=0;
void main() {
  ADPCFG=0xff;
  //timer1 setting##########
  T1IF_bit= 0;                     //clear flag 
  IEC0.T1IE         = 1;           //enable timer1 interrupt
  IPC0=0b0100000000000000;         //priority
  PR1                 = 7373;      //load
  //###########


  UART2_Init(115200);             //output something to computer


  ////////
  T1CON.TON=1;  ///start timer1
  ////////
  while(1){

    UART_Write(t2);
    UART_Write(t1);
    UART_Write(t0); 
  }
}
void Timer1Interrupt() iv IVT_ADDR_T1INTERRUPT{

  T1IF_bit= 0;  //clear the flag
  t0++;         //increment something
  if(t0==255){t1++;}
  if(t1==255){t2++;}
}
\$\endgroup\$
  • \$\begingroup\$ When I load the same code to a new chip, the timer1 starts on POR 9 out of 10 times. \$\endgroup\$ – Timtianyang Feb 21 '13 at 19:15
1
\$\begingroup\$

If it only sometimes starts, it is probably a hardware problem. Check that the power supply rise time is within spec for the PIC. If not, a external reset circuit may be required. The power up timer and brown out detect (if there is one) may also help.

It doesn't seem that the firmware is all that relevant to this, but there are a number of issues with it. Hard coded constant, like 7373, magically picked out of the air are a really bad idea. Also, your 3-byte increment routine in the interrupt is broken. It's funny how you have to stand on your head to increment 3 bytes in C when this would be simpler in assembler. I haven't done a interrupt routine in C30, so I'm not sure about this, but I don't see any obvious way the compiler is supposed to know this is a interrupt routine and therefore end with a RETFIE instruction instead of RETURN. Isn't there some pragma you have to mutter to the compiler for it to produce a valid interrupt routine?

\$\endgroup\$
  • \$\begingroup\$ Sorry about this, I am actually using mikroC. Interrupt vector iv IVT_ADDR_T1INTERRUPT will tell PIC what to execute when there is a timer1 interrupt. Also, how do you increment those three bytes? I am not very familiar with assembler. \$\endgroup\$ – Timtianyang Feb 21 '13 at 18:20
  • \$\begingroup\$ @Timt: Putting code at the interrupt vector is not the same as telling the compiler that the function is actually a interrupt routine. Look at the compiler manual to see how to do that. Incrementing a 24 bit variable in machine code is actually easier done on 32 bits. Data natively is 16 bits wide. You can manipulate byte entities, but whole words is easier. To do the increment you'd use ADD #1 on the first word and ADDC #0 on the second. \$\endgroup\$ – Olin Lathrop Feb 21 '13 at 18:32
  • \$\begingroup\$ I see. Now I am incrementing a 4 byte long variable inside of the interrupt routine and output shifted bytes (first second and third bytes). It fixed the incrementing problem. Once an interrupt enable is set and the interrupt vector is directed to a function, compiler will take care of it. But still, the POR doesn't always trigger the timer1 interrupt. I have to use an external circuit to flip MCLR. \$\endgroup\$ – Timtianyang Feb 21 '13 at 18:42
  • \$\begingroup\$ When I load the same code to a new chip, the timer1 starts on POR 9 out of 10 times. \$\endgroup\$ – Timtianyang Feb 21 '13 at 19:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.