Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

RETFIE: Is it required?

Status
Not open for further replies.
Yes, but if TMR1 overflows during a read, it screws things up, doesn't it? So, you would need to check for that.
No, two's complement maths takes all that into account. You don't need to think about the overflow, just blindly subtract.

An example, count1 = 65036, count2 = 100; count2 - count1 = -64936, which as an unsigned 16-bit integer is 600 (which is the expected result).

The calculation came out exact (according to the sim). That was nice to see. There were no lost cycles as happened while I started and stopped TMR1 in the polling method. Now, I have to decide whether to do some of the math at the 683 side and save a few milliseconds of transmission time, or just send the raw data and do it all at the 16F1519 side (both are only at 8 MHz). The subtraction is fairly quick, so I am thinking of doing that with the 683.
I meant missed incoming PWM cycles. If you run the code you provided in a loop, every second PWM cycle is ignored.

I did mention starting TMR1 partway through a cycle, which is not relevant to the code you provided, which takes this into account (by ignoring a cycle).

The code I'm getting at is more like the following, which doesn't miss PWM cycles or TMR counts:
Code:
   setup CCP
   start TMR1

   wait for falling edge
   lastCount = CCPR1

loopstart:
   wait for rising edge
   lowCount = CCPR1 - lastCount
   lastCount += lowCount               ; this simply sets lastCount to the value read from CCPR1

   wait for falling edge
   highCount = CCPR1 - lastCount
   lastCount += highCount              ; this simply sets lastCount to the value read from CCPR1

   ; we now have the high and low counts... can do something with them, perhaps?

   goto loopstart
 
If you enable interrupts, you get called exactly when you need it. You can do the same processing inside interrupts. The only difference is that you don't need to poll all the time. Interrupts will be automatically postponed if you do something critcal (such as processing a different interrupt).

Code:
CCP_interrupt:
  if (we're waiting for rising edge) {
     T2 = CCPR - risingEdge
     T1 = fallingEdge - risingEdge
     risingEdge = CCPR
     reprogram CCP for falling edge
  }
  else {
     fallingEdge = CCPR
     reprogram CCP for rising edge
  }
  retfie
 
MCU_interrupt:
  send out the dutyCycle
  retfie
 
Main_code:
  set up timer and inerrupts
  do_forever {
    if (new value for T2 received) {
      dutyCycle = T1/T2
      other calculations
    }
  }
 
Interrupts will be automatically postponed if you do something critcal (such as processing a different interrupt).
If the CCP interrupt occurs first, the 'critical' interrupt will be postponed, unless you allow nested interrupts.

You are of course correct that the CCP can be handled during an interrupt. If it is though, its effect on the timing of the other function in the interrupt has to be considered e.g. serial transmission routine.

I still think the use of the pic12f683 is likely superfluous, and that the CCP module of the pic16f1519 could be used (with CCP handling in interrupt, or in the superloop) instead.
 
If the CCP interrupt occurs first, the 'critical' interrupt will be postponed, unless you allow nested interrupts.

Yes, but the CCP interrupt takes only dozen of instructions to process. Such delay shouldn't hurt anything. That's why I moved the dutyCycle calculation to the main routine.

You are of course correct that the CCP can be handled during an interrupt. If it is though, its effect on the timing of the other function in the interrupt has to be considered e.g. serial transmission routine.

You disable interrupts when something time-critical is going on. In this case this is easily done by doing serial communications from within the MCU interrupt (because other interrupts are automatically disabled). As soon as sending is done and interrupt exits, the CCP interrupt that was pending (if any) gets executed. The only concern is to process MCU interrupt faster than 4ms so that two CCP interrupts couldn't occur during the sending. But even with longer sending times, it's not hard to detect the double-CCP-interrupt situation and dismiss the corresponding measurement.

I still think the use of the pic12f683 is likely superfluous, and that the CCP module of the pic16f1519 could be used (with CCP handling in interrupt, or in the superloop) instead.

I totally agree with that. There are PICs with multiple CCP or other capture modules. It is easier on the processor to get pulse width measurement with these modules directly rather than receiving digital transmissions from smaller MCUs.
 
If you're going to send the serial data using busy loops, there's no advantage in putting it in an ISR; just leave it as a blocking function called from the main loop. Then the interrupt is disabled in only ~1ms chunks. But if you're doing this, then there's no need to use interrupts at all; just process everything in the main loop.

Anyway, because the requirement is so basic, there's plenty of approaches that will give similar results; the one I posted before doesn't have any need to disable interrupts, and never has to worry about missing a PWM cycle.
 
If you're going to send the serial data using busy loops, there's no advantage in putting it in an ISR; just leave it as a blocking function called from the main loop. Then the interrupt is disabled in only ~1ms chunks. But if you're doing this, then there's no need to use interrupts at all; just process everything in the main loop.

Anyway, because the requirement is so basic, there's plenty of approaches that will give similar results; the one I posted before doesn't have any need to disable interrupts, and never has to worry about missing a PWM cycle.

Yes, you certainly can go by without interrupts. You simply send the serial data when needed and check for CCP condition between bytes. Definitely, there are many ways to do this.

I personally try to use interrupts for every task that I can. I also use DMA to make intervals between interrupts longer (of course no DMA on this PIC). This way I may have code for serial, for LCD, for DS1820 etc. Some of them disable interrupts for time-critical steps, some don't. The interrupts take care of timing and I don't need to worry about it. And I don't need to modify the code (such as inserting CCP checks in between bytes of serial code). Then all the tasks run by themselves and I only need to coordinate them in the main code.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top