Thread: External Counter, Plese Help

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    5

    External Counter, Plese Help

    Hello,

    I'm currently programming my first ever project. Its a multimeter specifically desinged to be used to test solar panels, batterys and lanterns on buoys.

    I need to have two buttons to control it. but i only have 1 external inturrupt available on the microcontroller. So i have used an external timer set to FFFF so that when the button is pressed the timer roles over and generates an interupt. as part of the ISR the timer is set back to FFFF.

    However whenever i disable and reinable the timer the button must be pressed twice before it works. once to 'wake it up' it seems and once to acutally use it. I have managed to program all stages so that the button does not need to be disabled however upon start up of the unit when i enable all the timers and interupts the problem still ocurrs.

    Does anyone have any suggestions on how to fix this? I would greatly appreciate any help.

    Best regards,

    Dan
    Last edited by SMTU_1; 07-31-2007 at 03:10 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I need to have two buttons to control it. but i only have 1 external inturrupt available on the microcontroller.
    How many interrupt lines do you think a PC keyboard takes up?

    Using a timer to mimic a keypad controller seems a poor hardware choice to me.

    > However whenever i disable and reinable the timer the button must be pressed twice before it works
    Maybe re-read the data sheets / errata for your chosen hardware?

    What do you do with the 2nd button then? How does the code recognise the difference between the two?

    Are there any other interrupt sources in the system?

    Since you neither posted code, nor any details of actual hardware, this is all wild guess-work.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jul 2007
    Posts
    5
    OK, here goes:

    The microcontroller is an mdm-1. RS Stock no. 351-7545

    One button is used to cycle through the various test modes. This button is connected to the microcontrollers external interrupt. By pressing the button the mode is incremented in the external interrupt’s ISR.

    The other button is used to start and in some cases stop the selected test. When the button is pressed the timer/ counter overflows, which generates an interrupt. The ISR for the timer/ counter overflow contains the code to start the relevant test and reset the count to FFFF.

    I’m pretty sure the only other way of generating an interrupt from an external source would be using the chips comparator to detect when the button is pressed.

    This is the timer ISR. It works fine with all tests and as you can see disables and re-enables the interrupt. This causes no problems.

    insert
    Code:
    // start button handling 
    
    #int_timer1
    void timer1_isr(void)
    {
    disable_interrupts(INT_TIMER1);
    
    
    if(start_flag==STOP)  //toggle start/stop of the test
    	start_flag=START;
    else
    	start_flag=STOP;
    
    set_timer1(0xFFFF);          //initial timer1 value ready for overflow from start button
    
    clear_interrupt(INT_TIMER1);
    enable_interrupts(INT_TIMER1);
    }
    This section does cause problems:

    insert
    Code:
    //enable all interrupts
    enable_interrupts(GLOBAL);
    
    //setup the timers that we require
    setup_timer_1(T1_EXTERNAL);   // external counter setup for start button
    
    set_timer1(0xFFFF);          //initial timer1 value ready for overflow from start button
    
    clear_interrupt(INT_TIMER1);
    enable_interrupts(INT_TIMER1);

    So… why does the start button need to be presses twice before it is registered first of all?
    After the ISR the button only needs to be pressed once, also enabling the timer/counter anywhere outside of the ISR caused the mentioned problem.






    Also if my company made me use this microcontroller operate with a full PC keyboard I would say ‘no’.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Why do you have
    enable_interrupts(GLOBAL);
    followed by
    enable_interrupts(INT_TIMER1);
    isn't that kinda redundant, since they're all enabled anyway?

    My only other thought is that when it works, then the functions are being called from within the context of an ISR, and not the main code.

    So does anything at all happen on the first button press after initialisation?
    Say use a scope / logic analyser to monitor some of the hardware lines to see if said interrupt happened (or is it all that logic on chip?)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    If you have freedom to redesign the hardware, I would connect BOTH buttons to the same interrupt line via some sort of latch that you can read to indicate WHICH of the two buttons is pressed (allowing both buttons at the same time can be used to give you a "third" button - just like on an older PC mouse).

    I would also use a simple mecahanism to indicate the key-pressed, and then poll it in the main loop, rather than perform the processing of the key in the interrupt handler - generally, interrupt handlers should return AS QUICKLY AS POSSIBLE!

    --
    Mats

  6. #6
    Registered User
    Join Date
    Jul 2007
    Posts
    5
    I put it there so it duplicated the ISR code, in the hope it would make it work. I should have taken it out when it didn't.

    All logic is within the chip.

    Do you know of a way to increment the timer from the code? so that rather than set it to FFFF i would set it to FFFE. Then i would internally increment it, hopefully 'waking it up' and then it would be on FFFF ready for the start button? Or is this not possible/ pointless?

    Best regards,

    Dan

  7. #7
    Registered User
    Join Date
    Jul 2007
    Posts
    5
    Quote Originally Posted by matsp View Post
    If you have freedom to redesign the hardware, I would connect BOTH buttons to the same interrupt line via some sort of latch that you can read to indicate WHICH of the two buttons is pressed (allowing both buttons at the same time can be used to give you a "third" button - just like on an older PC mouse).

    I would also use a simple mecahanism to indicate the key-pressed, and then poll it in the main loop, rather than perform the processing of the key in the interrupt handler - generally, interrupt handlers should return AS QUICKLY AS POSSIBLE!

    --
    Mats
    It's probably a bit too late for doing that. A couple of months ago it would have been a possibitliy, perhaps using a couple of cross coupled nand gands to produce the latch? Hardware is supposed to be kept to a minimum though. If i cant sort it i may go with your idea.

    Also i know it is good practice to keep ISRs short but the whole unit works absolutely perfect apart from this one last problem. How might the unit be effected by long ISRs out of interest?

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, the general principle is that you want to leave the current interrupt so that you don't hold up for another interrupt. This is of course more important when there are many interrupt sources, and/or when there is some interrupts that are time-sensitive.

    But that aside, have you tried setting your timer to 0xFFFE and see if it always needs THREE clicks on the button to make it register? Can you read the timer register? Perhaps one model would be to just leave the ISR out of it, and just check if the timer register has changed (that is, the button has been pressed).

    By the way, it isn't perhaps that the counter needs a second rising (or falling) edge to register that the button was pressed? Can you hook up a scope to the key and some output pin and see what exactly happens on the input in relation to the ISR?

    --
    Mats

  9. #9
    Registered User
    Join Date
    Jul 2007
    Posts
    5
    It's triggered on a rising edge. Once it works the first time it is fine after that. Ive fixed the problem by have the chip increment the counter itself as part of the initialisation procedure then reset the timer and clear the interrupt. Its not the ideal way to do it but it works.

    Just need to run through the test spec and makes sure everything is 100% ok. There are only going to be a few made so if I come across a better way when I get more experience it will be very easy to reprogram the units. But if it passes the test spec then i'm satisfied.

    Also it will pass the test spec.

    Thanks for your help.

    Best regards,

    Dan

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  3. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM
  4. debug to release modes
    By DavidP in forum Game Programming
    Replies: 5
    Last Post: 03-20-2003, 03:01 PM
  5. Ask about these "unresolved external symbol" error
    By ooosawaddee3 in forum C++ Programming
    Replies: 1
    Last Post: 06-29-2002, 11:39 AM