Menu

I'm 'STUCK' Again!

Help
Keith
2012-06-18
2013-05-30
  • Keith

    Keith - 2012-06-18

    I'm still plodding away with this daft project of mine, but I have ran out of space on the chip. I am using 16F676's (have tons of them !) Ideally I would like to store some of the subroutines in the EEPROM but to be honest, I haven't a blind clue how to go on.

    Before I go off on another wild tangent, firstly is it possible? I want to write the subroutine to EEPROM then Call and run it.

    Once again any help at all would be really appreciated.

    Keith

     
  • joe rocci

    joe rocci - 2012-06-18

    1) You can't execute code out of EEPROM; it's for data only
    2) The '676 only has 128 bytes of EEPROM, so it probably wouldn't do much good anyway.

     
  • Nobody/Anonymous

    I am not sure how you would put subroutines into eeprom.  If it were me, I would look at reducing program data by looking at more efficient coding.  When playing with the 10f's, reusing variables, using inline code for one off routines, and doing away with wait routines helped a lot.  Using word variables is a big hog of program space, so look at alternate methods of handling in a byte format.

    On the wait routines for example a simple clr TMR0 and btfsc TMRO,7 will give 128 ticks of the clock and prescale.

    There is no direct answer without seeing some code snippets.  It is a process of verifying alternate methods and double checking the .LST file for improvements (i.e. lower program words used).  Make sure that there is no l- in the MAKEASM file, as it prevents the LST file from being generated.

    Kent

     
  • Keith

    Keith - 2012-06-18

    Oh Well…. Just a thought - A bad one but non the less a thought, I think I have enough to be going on with, thanks for the reply guys….

    ni- nite…

    Keith

     
  • Keith

    Keith - 2012-06-21

    Hi again, I'm back with anothor outragious enquiry, hopefull someone will have a half sensible answer to this one.

    To set up my program which has 8 subroutines I am using what I think is a very messy set of conditional strings. Basically I am reading 3 inputs in a binary combination and test ing each condition befor the trigger goes high. very, very crude but it works.

    '*** Binary 111
    if select_1=1 and select_2=1 and select_3=1 and  trigger = 1  then
    routine_1
    End If
    '*** Binary 110
    if select_1 =1 and select_2 = 1 and select_3 = 0 and trigger = 1 then
    routine_2
    End If
    '*** Binary 101
    if select_1 =1 and select_2 = 0 and select_3 = 1 and trigger= 1 then
    routine_3
    End If
    '*** Binary 100
    if select_1 =1 and select_2 = 0 and select_3 = 0 and trigger= 1 then
    routine_4
    End If
    '*** Binary 011
    if select_1 =0 and select_2 = 1 and select_3 = 1 and trigger= 1 then
    routine_5
    end if
    '*** Binary 010
    if select_1 =0 and select_2 = 1 and select_3 = 0 and trigger= 1 then
    routine_6
    End if
    '*** Binary 001
    if select_1 =0 and select_2 = 0 and select_3 = 1 and trigger= 1 then
    routine_7
    end if
    '*** Binary 001
    if select_1 =0 and select_2 = 0 and select_3 = 0 and trigger= 1then
    routine_8

    What I want to do is to expand this to 16  using a forth input pin but this will mean doubling the IFf conditions which in essence is a 'No Brainer'

    Can anyone think of a way I can read the four pins in a binary word and apply that as a option select?

       

     
  • kent_twt4

    kent_twt4 - 2012-06-21

    Line up the pins on  PORTA or PORTC and mask off the top four bits with a AND b'00001111'.  Then use the select case statements.

    routine = PortC AND b'00001111'
    Select Case routine
        case 0
            routine_0
        case 1
            routine_1
    ...
    ...
    ...
    end select
    
     
  • Keith

    Keith - 2012-06-22

    Wow ! thanks, this looks like the biz, can't wait to try it out.

    Thanks for that.

    Is it possible to combine the binary over PortA and PortC ? If so what would the AND Mask look like?

    Mechanical configurations of the pinouts favour RA 3 and RA4 with RC4 and RC5 in a conventional layout.

     
  • kent_twt4

    kent_twt4 - 2012-06-22

    In that case, one way would be to go back to the if's to evaluate the bit position of the Select Case variable 'routine'.

    routine = 0
    If PortA.3 On Then routine.0 = 1
    If PortA.4 On Then routine.1 = 1
    ...
    ...
    
     
  • Keith

    Keith - 2012-06-22

    I must be as thick as Rhino Dung…. I cannot see how this works nor can I get it to work. It compiles okay though.

     
  • kent_twt4

    kent_twt4 - 2012-06-22

    How what works?  The Select Case, or the IF statements?  Either way I forgot about the button press, the examples were only for determining the subroutines based on the state of the PORT pins.  The code samples are snippets, so for the IF statements you need to add on the Select Case, and a button press routine, I am not going to write the whole code for you.

    Context is everything, are the subroutines just a one shot instance?  Or, are the subs to be continuously repeated until another button press?  For the button press the port pin can be polled by continuously checking it in a loop, like using an IF statement.  Or, an interrupt pin can be used for the button, where the port pins are then evaluated in a interrupt sub.  Yet another option is to count the number of button presses to change the subroutines, like in a menu, the possibilities are endless.

     
  • Keith

    Keith - 2012-06-22

    Hi and once again I am extremely grateful for all your help and encouragement.
    What I am trying to do is to be able to run a predefined subroutine whenever the button is pressed. I have so far eight subroutines of which I want to be able to call 1 of them and run it only.
    I want the same subroutine only to be run until the binary word is changed and ideally the processor is reset.
    Secondly I would like to extend the vocabulary (subroutines) to 16 by adding the fourth bit. Currently I have it working with very crude, clunky and clumsy if statements, which I need to ‘Lean’ out and tighten up before I start on my space saving campaign. 
    Hope this makes sense to you. 

     
  • kent_twt4

    kent_twt4 - 2012-06-22

    Use the INT pin of the 16f676 for the change routine button, and the On Interrupt EXTInt0 command.  First try turning an led On and Off, then move on to evaluating the switches in the interrupt routine.  Oodles of fun : )

     
  • mmotte

    mmotte - 2012-06-22

    assignment:

    "Is it possible to combine the binary over PortA and PortC ? If so what would
    the AND Mask look like?

    Mechanical configurations of the pinouts favour RA 3 and RA4 with RC4 and RC5
    in a conventional layout."
    **********************************
    It would be easier to move some components on the board and use 4 adjacent bits on one port.

    But

    otherwise you need bit  manipulation - masking and rotates

    do   ' this is a do loop so it repeatedly checks if the selection changes

    myAbits = PortA and b'00001100'
    myCbits = PortC and b'00011000'
    ROTATE myAbits RIGHT SIMPLE
    ROTATE myAbits RIGHT SIMPLE   ' now in bits 0 and 1
    ROTATE myCbits RIGHT SIMPLE   ' now in bits 3 and 4
    myselection = myAbits or myCbits  ' combine for one selection
    ' so the selection numbers from 4 bits are 0-15

         SELECT CASE myselection

        CASE 1
            GOSUB Measure

        CASE 2
            GOSUB AdjLowFreq

         END SELECT
      wait 100 ms
    loop

    If you took a programming course,  this is called a "dispacher".

    73
    mike

     
  • Bert

    Bert - 2012-06-23

    Hey, if you're looking to save space, consider replacing the last 2 rotates in Mike's dispatcher with a single rotate of 'myselection' after the OR combination.

    Or for even more saving, eliminate them both entirely and use only even selection numbers from 2 to 30:
    CASE 2
       GOSUB…
    CASE 4
      GOSUB…
    etc.

    -Bert

     
  • Keith

    Keith - 2012-06-23

    Progress Report….
    Well, I appear to be making some progress with this SELECT and CASE bit of the program. It really looks quite well, and as always very grateful for everyone’s help
    .
    I am coming to a blind hump here though as the binary is not running true. I have a sneaky feeling there is something wrong with my DIR and Definitions as I had to make some changes to the snippet from Mike’s Dispatcher. Here is the project so far:

    #define Led_1 PORTA.0
    #define Led_2 PORTA.1
    #define LED_3 PORTA.2
    #define Led_4 PORTC.0
    #define LED_5 PORTC.1
    #define LED_6 PORTC.2

    ;Variables
    time = 255
    DIR PORTA b'011000' ' All Outputs except RA3 & RA4
    DIR PORTC b'110000' ' All Outputs except RC4 & 5
    Main:
    myAbits = PortA and b'011000'
    myCbits = PortC and b'110000'
    ROTATE myAbits RIGHT SIMPLE
    ROTATE myAbits RIGHT SIMPLE   ' now in bits 0 and 1
    ROTATE myCbits RIGHT SIMPLE   ' now in bits 3 and 4
    myselection = myAbits or myCbits  ' combine for one selection so
    'the selection numbers from 4 bits are 0-15

         SELECT CASE myselection
        CASE 0
             routine_0
        CASE 1
            routine_1
        CASE 2
            routine_2
        CASE 3
            routine_3
        CASE 4
            routine_4
        CASE 5
            routine_5
        CASE 6
            routine_6
        CASE 7
            routine_7

    etc.etc, (up to Case 15)

    I really need to sort out the binary word before I can make any progress

    Thanks again to all.

    Keith

    .

     
  • Nobody/Anonymous

    Rotate myAbits right 3 times and myCbits right twice and the bits should be in the correct position.

    ROTATE myAbits RIGHT SIMPLE
    ROTATE myAbits RIGHT SIMPLE
    ROTATE myAbits RIGHT SIMPLE         ' now in bits 0 and 1
    ROTATE myCbits RIGHT SIMPLE
    ROTATE myCbits RIGHT SIMPLE         ' now in bits 2 and 3
    
     
  • kent_twt4

    kent_twt4 - 2012-06-23

    Homework:  Future chewing the fat off program, and data variables if needed.  In words, the following first clears the "routine" register to zero, then tests the port bits and sets the "routine" register binary bits accordingly, which subsequently gets tested in the Select Case statements (tested and works on a 16f917).

    routine = 0
    If PortA.3 On Then routine.0 = 1
    If PortA.4 On Then routine.1 = 1
    If PortC.4 On Then routine.2 = 1
    If PortC.5 On Then routine.3 = 1
    

    Saves 2 data variables and 6 program words over previously stated optimized dispatcher.  This is not a critique of either method, and is but a small gain.  But, if program space (or data variables) is tight, then you will have to learn how the .LST file is your friend and know how to use it.

    Optimized dispatcher?

    MyPortA = PortA AND b'00011000'
    Rotate MyPortA Right Simple
    MyPortC = PortC AND b'00110000'
    routine = MyPortA OR MyPortC
    Rotate routine Right Simple
    Rotate routine Right Simple
    
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.