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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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 : )
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
"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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
;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
.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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.
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
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
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?
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.
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.
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'.
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.
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.
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.
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 : )
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
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
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
.
Rotate myAbits right 3 times and myCbits right twice and the bits should be in the correct position.
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).
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?