Timer 0, mode 1 interrupt in 8051

Discussion in 'Embedded Systems and Microcontrollers' started by cmartinez, May 15, 2017.

  1. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    I've seldom used interrupts in the 8051, and then only to manage serial UART communications. Truth is, I don't like interrupts... they mess up program execution timing, which is critical in most of the applications that I've worked on... but I'm sure that the designers put them there for pretty solid set of good reasons... Emoji Smiley-51.png

    This time, I need to use timer 0 in mode 1. That is, a 16-bit timer.

    Now, I do know how to set up a timer interrupt, and how to configure the timer for that purpose (I think). My question is:
    • Does the timer stop when execution is vectored to its corresponding routine and then restarts when the RETI instruction is encountered?
    • Or does the timer resets itself immediately upon vectoring and starts running again regardless if its service routine has been completed or not?

    I've already re-read the 8051's hardware manual, but the details still seem a little foggy to my tired brain...

    My concern is if the code in the service routine is too large, maybe the timer interrupt will call itself before the routine has been completed and exited, and an endless loop will ensue.... my intuition tells me that the timer will only restart after completing its service routine, but I'd like to hear it from people more experienced than me.

    @Papabravo
     
  2. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    @absf, if I remember correctly, you also know a bit about the 8051 architecture.
     
    absf likes this.
  3. shteii01

    AAC Fanatic!

    Feb 19, 2010
    4,378
    691
    According to my textbook, it stops, saves the program counter, jumps to ISR. Once ISR is done, it goes back to where it stoped and continues executing the code.
     
    absf and cmartinez like this.
  4. joeyd999

    AAC Fanatic!

    Jun 6, 2011
    3,940
    5,325
    Then you are doing it wrong. I use interrupts to ensure critical timing for the portions of code that require it.
     
  5. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    That's more or less what I thought too. But I wanted to hear it from someone else before I jumped into writing code.
     
  6. shteii01

    AAC Fanatic!

    Feb 19, 2010
    4,378
    691
    From: "The 8051 Microcontroller and Embedded Systems", Second Edition, by M. A. Mazidi, J. G. Mazidi, R. D. McKinlay.
    "
    1. It finishes the instruction it is executing and saves the address of the next instruction (PC) on the stack.
    ....
    5. Upon executing the RETI instruction, the microcontroller returns to the place where it was interrupted. First, it gets the program counter (PC) address from the stack by popping the top two bytes of the stack into the PC. Then it starts to execute from that address.
    "
     
    cmartinez likes this.
  7. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    That is the key to my question. Is the timer suspended while its interrupt is being serviced, and does the RETI instruction restarts the timer after being executed?
     
  8. absf

    Senior Member

    Dec 29, 2010
    1,850
    504
    Yes, but not detailed enough to answer your questions.

    See my thread in ETO "Learning 8051". Looks like ETO folks are more interested in old mcu.:D

    Allen
     
    cmartinez likes this.
  9. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    Old???? the 8051 is alive and well and will keep'n kicking for a long time still! ... :D
     
    Last edited: May 15, 2017
    absf likes this.
  10. shteii01

    AAC Fanatic!

    Feb 19, 2010
    4,378
    691
    The way I read it, the timer is stopped and the place where it stopped is stored in the stack. When you return, the clock starts from where it was stopped.

    Since you are doing timer interrupt, don't you turn over from FFFFh to 0000h, timer flag goes active and that activates the timer interrupt? So your clock is finished. In order to start the clock you need to reload the timer.
     
  11. shteii01

    AAC Fanatic!

    Feb 19, 2010
    4,378
    691
    The stuff I quoted from the textbook applies to all interrupts, not just timer interrupt. But timer interrupt is special in that it activates ISR when timer flag goes to 1, but timer flag goes to 1 when timer turns over from FFFFh to 0000h.
     
    cmartinez likes this.
  12. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    That works well in the µs scale. At least in a 20 MHz MCU. But not in a clock cycle-by-cycle basis, which is what I'm dealing here with.

    upload_2017-5-15_18-58-32.png
     
  13. Papabravo

    Expert

    Feb 24, 2006
    11,624
    2,438
    The Timer itself does not stop in the interrupt routine. When it goes from 0xFFFF to 0x0000 it keeps right on going. The timer is controlled by the timer run bit (TR0 in this case). This is important because it keeps track of the time you spend in the interrupt routine. This allows you to compute the value you need to use for a reload to get precise timing. This timer architecture is nearly 40 years old and the Output Compare units developed for the Electronic Engine Controller built around the 80C196 are much easier to use for interrupts at precisely repeatable intervals.

    If you can help it, you never want to do an excessive amount of work INSIDE AN INTERRUPT ROUTINE. That is the road to perdition. You record the occurrence of the interrupt, reload the timer, and exit. While looking for things to do you notice that a timer interrupt has occurred and you go process things. If you really want to be slick about it you can mess with the stack so that when you issue the RETI you go to a foreground processing loop that handles the timer work, with other interrupts enabled. When the foreground work is done you retrieve the original stack entry from the timer interrupt and return to the background loop. You only do this if you absolutely have to -- there is considerable overhead to it and it's a bitch to debug without really good tools. Edit, Compile, Burn won't get you there, at least not quickly.
     
    Last edited: May 15, 2017
    cmartinez likes this.
  14. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    EXACTLY the answer that I was looking for... you've probably saved me numerous hours of testing and debugging... many, many thanks! :)
     
  15. Papabravo

    Expert

    Feb 24, 2006
    11,624
    2,438
    You're always welcome. I think of you as my Mexican Opposite Number.
    Say what? What is that exactly? Since you asked; I'll tell you.

    During the 1950's at the height of the cold war, my engineer father, told me a story about my Russian Opposite Number. He was a young boy of about nine (in October of 1957) whose father worked in the Russian Aerospace business on Sputnik, and this boy was studying very hard, getting good grades, so he could grow up and go to college and become an engineer just like his father so the Russians could be the first to land on the moon. The subtle suggestion was that I might want to think about doing the same thing. His name was Boris Ivanoveech and we were cosmically linked or so I was led to believe at the time.

    This is just a coincidence but both of us have a considerable affiliation with the 8051 architecture and it's various derivatives. So remembering my father's story I have dubbed you my Mexican Opposite Number. The Mexican Engineer and entrepreneur that is most like me in the whole world. CONGRATULATIONS -- I think?
     
    cmartinez likes this.
  16. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    I just hope your income is, or was, the perfect binary complement of mine... :D .. just kidding... I've been doing quite well the last couple of years, but prior to that I almost had a nervous breakdown... with a kid in college, and the other one with special needs, rent to pay (both home and office), and medical insurance payments that could not be skipped or my daughter would've lost access to all her necessary treatments...

    You have no idea of how much good you do to others around you with even the smallest of gestures.

    Again, my most profuse thanks to you, my friend.
     
  17. Papabravo

    Expert

    Feb 24, 2006
    11,624
    2,438
    I'm sorry to hear of those tribulations and you're still welcome to pick my brain any old time.
     
  18. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    Thanks... but after 18 years of my daughter's arrival in the world, she's my greatest blessing and source of motivation.. plus, my 20 year old kid grew up helping around the house with every need that his little sis required. And that built his character to heights that I, as a father, would've never even dreamed of... And I was such a spoiled brat when I was his age! ... And my mom (still around and in perfect health at 85) likes to stare at me and remind me of how she gave birth to her third of six child (that would be me) with no anesthesia whatsoever because the doctor was stuck in a traffic jam that night... and then she'd tell me how lucky I've been... to which I always answer: "yeah, mom... ain't it wonderful when life's not fair in your favor" ?

    So yes, I've had my fair share of problems... but definitely far more blessings ... and no tribulations in the strict sense of the word, thank God
     
  19. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    Another question. I seldom use interrupts and therefore I'm no expert on them.

    If I have two interrupt sources, say timer0 overflow, and external interrupt 0; and I use two separate routines to deal with each of them, will one routine be interrupted by the other? Or does that have to do with how interrupt priority is set up?

    Specifically:
    I just wrote code that deals with timer0 interrupt. When that code is vectored to, the timer is stopped and then a flag is set such that the code will not proceed until that flag has been cleared by the external interrupt, will that work?

    Here's the relevant segment of code:

    Code (Text):
    1.  
    2. ;*********    Defined interrupt addresses
    3. ORG 0003H   ;External Interrupt 0 - IE0, configured as falling edge detector
    4.    ACALL MONITOR_EDGE
    5.   RETI
    6. ORG 000BH   ;Timer 0 Overflow     - TF0
    7.    ACALL TIMER0_SVC
    8.   RETI
    9.  
    10. .
    11. .
    12. .
    13. .
    14. .
    15. ;*********
    16. MONITOR_EDGE:
    17.    SETB FALLING_EDGE_FLAG
    18. RET
    19.  
    20. ;*********
    21. TIMER0_SVC:
    22.     CLR TR0                  ;stop timer0, to process the following instructions properly and prevent
    23.                              ;an overlapping timer interrupt event
    24.  
    25.     CLR FALLING_EDGE_FLAG    ;Wait for a falling edge event reported by the MONITOR_EDGE routine before
    26.     JNB FALLING_EDGE_FLAG, $ ;continuing.
    27.     SETB TR0                 ;restart timer0 and continue
    28. RET
    29.  
     
  20. cmartinez

    Thread Starter AAC Fanatic!

    Jan 17, 2007
    5,346
    6,257
    Maybe this answers my question.

    From the AT89LP4052 manual:

    "An interrupt service routine in progress can be interrupted by a higher priority interrupt, but not by another interrupt of the same or lower priority. The highest priority interrupt cannot be interrupted by any other interrupt source. If two requests of different priority levels are pending at the end of an instruction, the request of higher priority level is serviced. If requests of the same priority level are pending at the end of an instruction, an internal polling sequence determines which request is serviced. The polling sequence is based on the vector address; an interrupt with a lower vector address has higher priority than an interrupt with a higher vector address. Note that the polling sequence is only used to resolve pending requests of the same priority level."

    This means that my code might work as is, since the external interrupt 0 vector address is lower than timer 0's. But to make sure, I'm going to set external interrupt 0 as highest priority.
     
Loading...