Odd behavior if too many instructions


Closed Thread
Results 1 to 14 of 14
  1. #1
    Join Date
    Feb 2010
    Posts
    11

    Default Odd behavior if too many instructions

    I'm using a 16f877a on a Lab X-2 board, at 20mhz. I'm using microcode studio plus w/PBP and MicroCode Loader bootloader.

    My program has an assembly interrupt routine, which to my knowledge is correct. I have a simple:

    main:

    LED = 1
    pause 50
    LED = 0

    goto Main

    Other_Routines:
    ...
    End

    Although right now my program DOES NOT use "Other Routines"... they somehow affect my program. If I move my encoder, which triggers the assembly interrupt, and I have not commented out "Other Routines", there is considerable lag in the time the LED blinks on off. If I delete a large portion of my unused routine (other routine) then the LED blinks on/off normally dispite the huge number of interrupts, which don't take a long time to process.

    I am totally lost. Without the "other routines" my code only takes ~800 words. With it, it's over 1100. I'm wondering if I'm going into a different page, but then I"m not sure because my code is still less than 2k words... if I did go into a new page... what are the consequences of that?

    Matt

  2. #2
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,613


    Did you find this post helpful? Yes | No

    Wink

    Hi, Matt

    Without your "Faulty" code ... no luck to tell you something usable ...

    could be as simple as an Interrupt flag you've forgotten to reset ...

    COULD be ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  3. #3
    Join Date
    Feb 2010
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Here is my code:

    http://pastebin.com/f456e5db

    Sorry it's a bit of a mess. If I comment the "IF" on Line 343, with the corresponding ENDIF, the code runs much more consistently. Also, "Encoder_Counting" at 395 disabled interrupts to do some processing, but only for a few lines while it copies a buffer. If I disable interrupts for the entire routine, one of my problems goes away. The problem was that "Current_Position" got changed randomly. I guessed that my interrupt was screwing with it, so I disabled interrupts for that entire routine. Theoretically, my interrupt shouldn't interfere with that at all. None of the variables there are used by the interrupt. When I copy from the variables which are used during the interrupt, I disable global interrupts. ::Confused::

    About assembly interrupts, when I use them I only restore the W register. Do I need to do anything with wsave1, wsave2, or wsave3? I know I have to declare them, but I"m not sure where they get used.

    Thanks,
    MAtt

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by dksoba
    I'm using microcode studio plus w/PBP and MicroCode Loader bootloader.
    Try adding ...
    Code:
    DEFINE LOADER_USED 1 ' Bootloader Used
    DT

  5. #5
    Join Date
    Feb 2010
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    Try adding ...
    Code:
    DEFINE LOADER_USED 1 ' Bootloader Used
    That is defined in generic_include.inc. I moved it to my main pbp file and removed that include, and it still does the same thing.

    Does this have something to do with stacksize? If you overflow the stack... what happens?

    Matt

  6. #6
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by dksoba View Post
    Does this have something to do with stacksize? If you overflow the stack... what happens?
    It has nothing to do with the stack.
    It just makes sure nothing is in the first 4 words.
    Those locations are needed for the Bootloader.

    And when you overflow the stack on 16F's ... Nothing happens.
    It's when you return, that you may end up in the wrong place.

    What else is in your Includes?
    Can you post them too?
    <br>
    DT

  7. #7
    Join Date
    Feb 2010
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    My main code (updated):

    http://pastebin.com/m7513a97d

    Includes:

    generic_include.inc:
    http://pastebin.com/m1be5ca8f

    LCD_Init_PortD.inc:
    http://pastebin.com/m17a1888d

    ADC10:
    http://pastebin.com/m3b596568


    In my updated code, something bizarre happens. My setup has an optical encoder w/channels A/B. When I start my program, it drops into "Main" after initializing variables and such. Main displays the current position of the encoder. As my code stands, it's fast and normal. The LCD updates w/the correct position at the speed it's supposed to. If I make ONE simple modification, if I comment out DEBUG_STACK declaration on line 30, all of a sudden for no apparent reason, the update rate of the LCD will be 0.5-1s. No idea what's going on. This isn't the only thing to trigger that. If I then comment out the PID_Loop routine, it'll be fast again... I'm so confused and frustrated and I'm not sure wtf is happening. Oh yea, Even if the LCD updates slowly, it still displays the correct position, which tells me that the interrupt service routine is working.

    Thanks,
    Matt

  8. #8
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Ok, this is probably what's happening.

    You've got just enough variables that 1 or 2 are getting pushed into BANK1.
    In particular _portb_masked.

    _portb_masked is used in the interrupt handler, but the Bank isn't being changed. So it ends up overwriting memory in BANK0.
    Where it's located makes it overwrite PBP's system registers at R1.

    If you comment out the DEBUG_STACK variable like you mentioned, the _portb_masked variable moves and then overwrites PBP's R0 system var.

    As the placement of the variable moves, so does the apparent problem that it causes, which corresponds with your symptoms.
    If you were to remove two more variables, _portb_masked would no longer be in BANK1, and it would probably run correctly.

    Unless you are handling the Banking, any variables you use at the ASM level should be declared in BANK0.
    Code:
    encoder_history VAR BYTE BANK0:encoder_history = 0 'Store the current and last state of channelA/B of the encoder
    portb_masked VAR BYTE BANK0:portb_masked = 0 'Masked port B to have only the encoder channels
    interrupt_debug           VAR BYTE BANK0: interrupt_debug = 0
    HTH,
    DT

  9. #9
    Join Date
    Feb 2010
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Thanks! That seems to have done the trick. I'm using MicroCode Studio Plus, is there anyway to see what variables are stored in what banks?

    Also, more importantly, I'm not currently saving/restoring the FSR register when I go into my interrupt service routine. I'm not sure if any of the PBP commands use indirect addressing, do they?

    If they do, I can do the following:

    Code:
    'create fsrsave
    fsrsave VAR byte bank0 system 'What does the "system" do anyways?
    
    ...
    
    ASM
    ...
    movf FSR,W
    movwf fsrsave
    
    ...do the routine
    
    ...at the end, restore stuff, and then before retfie
    movf fsrsave,W
    movwf FSR
    retfie
    Right? I'm learning so damn much from this project. It's not even an electrical engineering project, it's a mechanical engineering project, but I like to take it to the next level to learn more .

    Thanks,
    Matt

  10. #10
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    You can look in the .LST file to see the addresses where each variable is assigned.

    You can also File > Import the .cof file into MPLAB then View > File Registers > Symbolic Tab.
    It's a lot easier to read than the .lst file.
    Of course, you need the datasheet to figure out where the banks are.

    And there are many PBP commands that use the FSR.
    But none of the statements in your ISR do, so right now there's no need to save/restore it.

    Cheers,
    DT

  11. #11
    Join Date
    Feb 2010
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    If I go over 1 page of code (2k words, right?) is there anything I need to worry about w/my current code? I know the pbp code will take care of itself, but my ASM ISR might not. I do use PCLATH for the table jump, so that should be fine. And my GOTO's should be fine so long as the entire ISR is in page0, right?

    Thanks,
    Matt

  12. #12
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I do use PCLATH for the table jump, so that should be fine. And my GOTO's should be fine so long as the entire ISR is in page0, right?
    You do have PCLATH pointing to the Jump Table. But it doesn't take into account the Jump it makes FROM the table.

    If _No_Change, _Decrement, _Increment or _Error end up on the other side of a boundary, it will jump to the wrong place.

    As long as the entire ISR is in the same page (doesn't have to be page 0), then it won't have a problem.
    The trick is knowing when there is a problem, which you can do easily by adding these lines to the end of the ISR ...

    Code:
            retfie                  ; Return from interrupt
      if ((high($) & 18h) != (high(ISR) & 18h))
        error ISR crosses page boundary
      endif
    ENDASM
    If the ISR ends up crossing a boundary, that will flag an error to let you know something needs to be moved.

    HTH,
    DT

  13. #13
    Join Date
    Feb 2010
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Thanks for all the help. Because of it I was able to finish the robot project I was working on using optical encoders (instead of potentiometers... PID + nonlinear, 270 degree pots ==slow || messy).

    The robot contest was for my senior design class at UCSD (Mechanical Engineering). We had to build a robot to move small pieces of PVC pipe from one rotary table to another rotary table, as fast as possible. The recieving table was at least 1 inch higher than the starting table. Also, the receiving table started out with some positions filled, so you had to at least detect if there was space to move cargo there.

    My turntables were stacked. IR sensors were used to detect the presence of pipes on both the top and bottom tables. As soon as a PVC pipe was detected (bottom) or an empty slot detected (top), the PIC would rotate the turntable to that position to align with an air nozzle. The air nozzle shot air between 45-60 PSI at the PVC pipe (there was a round cover for the bottom to prevent the air from just going through the pipe).

    My PID was very slow (I was running my motor at around 40% duty cycle MAX) because I was having problems getting my derivative term working well at high speed (worked fine at low speed). I've identified the problem, but it's too late. Our robot was the fastest in the class anyways . We transferred 3 PVC pipes in 1.19-1.86 seconds. I think the second fastest time was on the order of 6 seconds.

    Here is a highspeed video of our robot (I think this was our 1.86 second time).



    Thanks so much,
    Matt

  14. #14
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Congratulations on the Win!

    Looks like it was fun.
    Maybe I should go back to school. (Just for the challenges)
    <br>
    DT

Similar Threads

  1. PBP Using too many instructions
    By The Master in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 21st December 2009, 23:24
  2. Difference between modes in serial instructions
    By amindzo in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 16th September 2008, 15:40
  3. Is Number Odd?
    By T.Jackson in forum Off Topic
    Replies: 29
    Last Post: - 11th June 2008, 17:53
  4. List of instructions used in PBP ?
    By AndrewC in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 2nd November 2007, 11:22
  5. Need more speed in Lookdown and Branchl instructions
    By Pedro Santos in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 18th August 2006, 23:04

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts