PIC Microcontroller Serial and timer/counters

Discussion in 'Embedded Systems and Microcontrollers' started by Maketronic, Nov 23, 2010.

  1. Maketronic

    Thread Starter Active Member

    Mar 21, 2009
    49
    0
    Hi All

    I have a project I am working on at the moment using a PC application to send through what is essentially 'bit sequences' (via a serial link) to a PIC16F877A microcontroller (running at 10Mhz).

    Currently I have the project to the point where the microcontroller recieves my serial string and creates a certain bit pattern on its outputs.
    Currently I have the PC application set up so that it sends say 0001001 then waits say 1 second (as instructed) before sending the next bit pattern in its sequence.
    This works greak however I was asked to add another capability to the setup.
    When any bit is turned on at the recieving microcontroller end it remains on for approx 1 second after its 'turn on' instruction.
    Simple you say. Yes, My problem arises when you send through another sequence say only 0.3 sec later and the other bit is still timing.
    My idea is to run an internal timer/counter set to approx 0.1 second. When a bit is instructed to turn on it sets a corresponding element in an array to 10, then any time the timer counts it decrements the count in each element of the array and then the Microcontroller outputs an on bit where the corresponding element is greater than zero.

    I guess my biggest query is if you a listening for serial data with a simple loop and also doing an operation with a hardware timer/counter, will you miss some/many incoming serial sequences ?(because a hardware timer/counter acts like an interrupt correct?)

    My application would require the 1 second 'On time' to not be precise however the serial strings may need to be only 0.1 second appart (never less and most often more)

    Your ideas would be greatly welcomed I have no experience as the whether hardware timers and serial comms play nice together.

    Regards

    Bruce
     
  2. JDT

    Well-Known Member

    Feb 12, 2009
    658
    85
    I would always have the incoming serial cause an interrupt and deal with the incoming byte in the interrupt.

    Your 0.1s timer could be polled if accuracy is not too important or could also be handled in an interrupt.

    When you enter the interrupt, the first thing you do is to test the interrupt flags to see what has caused it. Clear the flag and handle it as required. Before you return from the interrupt, go back and test the flags again in case the another interrupt flag has occurred. Only return when no flags are set.
     
  3. Maketronic

    Thread Starter Active Member

    Mar 21, 2009
    49
    0
    So for instance have the loop poll for serial
    set interrupt flag
    if flag cause by serial deal with serial work in interrupt
    if flag is caused by timer overflow, increment bit element values
    clear interrupt flag
    return to loop

    Have I understood you correctly
     
  4. Maketronic

    Thread Starter Active Member

    Mar 21, 2009
    49
    0
    Just as an aside also

    Are there any PIC Micro chips that can be set up to generate an interrupt from a serial input native or would it always be something you have to poll for?
     
  5. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    The 16F877A does, search for RCIE in the datasheet.
     
  6. JDT

    Well-Known Member

    Feb 12, 2009
    658
    85
    I'm sure most PIC's that have an internal USART and interrupt capability have this. The PIC16F870 series certainly do.

    Don't poll for anything. The code will jump to the interrupt vector when an interrupt occurs. You have to set-up various registers including INTCON and PIE so that the interrupt happens.

    So, when the code vectors to the interrupt (see the flowchart - easier than text!).
     
  7. Maketronic

    Thread Starter Active Member

    Mar 21, 2009
    49
    0
    Thanks so much for your help, while I have used portb and timer interrupts in the distant past I have not yet used usart interrupts.
    I have looked into the data sheets and I think I can follow it reasonably well.
    The only query I am still working on is the use of PEIE and whether it applys to me, no doubt a bit of google combined with a measure of fiddle will fix that.

    I am now thinking to use the interrupt on the incoming uart and storing that data to arrays and then the non interrupt part of my program will execute a loop every 0.1 seconds and then decrement the values in the corresponding array until zero and while the array values are non zero set the corresponding bits on the outputs.

    I will get programming and let you guys know how i get on.

    By the way JDT what program did you use for the flowchart?
     
  8. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    That flowchart(or a similar one) is available in various microchip datasheets and on their website.

    For your comms, be sure to make the interrupt routine as short as possible. Avoid using any delay() functions, it's better to have the uC skipping over false if/then or case statements than doing a delay.
     
  9. Maketronic

    Thread Starter Active Member

    Mar 21, 2009
    49
    0
    Thanks so much everybody for your help.
    I believe I may have my firmware complete.

    I used a UART based interrupt to react to incoming data then I used a simple loop and delay outside the interrupt to decrement the values in my arrays and while they are non zero turn on the corresponding bits.
    While I realise the loop and delay wont be as accurate as the 'proper' pic timers it will suffice for my application.

    I have attached my code for interests sake if anyone is curious

    Regards

    Bruce
     
  10. JDT

    Well-Known Member

    Feb 12, 2009
    658
    85
    Try to spend as little time in the interrupt as possible.

    Read your incoming serial byte and place in a circular buffer. Maintain write and read pointers to this buffer as variables. Don't do a for-next loop in the interrupt.

    So, when a serial byte is received, the code in the interrupt will read this byte and place it in the circular buffer at the write pointer. Then increment the pointer and exit the interrupt. Simple and quick. Process the data in the circular buffer elsewhere.

    Have to say, I am not an expert in using C for PICs. I usually do it in assembler!
     
Loading...