First of all, thanks very much for such a tool--an open source Linux and Windows PIC Basic compiler. I am trying to compile a simple servo demo program that I found in one of the forums here. The error message says something about not being able to use us (microseconds) for <=4MHz pieces. My question: Is it a limitation of 12F508 or GC Basic itself?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Most likely the 12F508. Consider the Pic at 4Mhz is only going to give you 1us instructions, without any overhead. You may be able to use a constant value(s)?, but certainately not a variable in this instance.
If possible, use a device with a 8Mhz internal or 20 Mhz external clock to handle the overhead and variable values.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The trouble is that the shortest delay loop possible using a variable takes 3 instruction cycles for each repetition, plus at least 4 to load the delay value and call the delay routine. On faster chips, this code can easily run and be accurate to within 1 us.
On slower chips, the time taken for each delay loop becomes more than 1 us. On a 4 MHz chip, each delay loop would take 3 us, plus 4 us to call the delay routine. Adding code to divide the input time by 3 would take (from memory) somewhere near 80 or 90 cycles. Adding code to subtract the time taken for the call and the delay would take 4 cycles. This could end up resulting in a value that goes below 0. If this occurs, and it would for any delay under 80 us on a 4 MHz, then the PIC would have spent 80 us working out how much time it has to waste for a 1 us delay. Even with delays of over 80 us, the delay routine would only be accurate to within 3 us.
If you use a constant value for the delay, such as Wait 3 us, then GCBASIC can generate the code to waste the correct number of clock cycles during compilation, which will give you accurate timing.
Another option is to use the "10us" delay. This time period is long enough for even slower chips to be able to loop at least once within the 10 us.
And as Kent mentioned, you can upgrade to a faster PIC. Unfortunately this is really the only way to get accurate 1 us delays from a variable.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you very much for your detailed explanations. It seems that I didn't make myself clear--for the servo control program that I am trying to compile
'A program to test a servo
#chip 12F508, 4
#config INTRC_OSC
dir GPIO b'001000'
Main:
FOR position = 100 to 200
PULSEOUT GPIO.0, position 1Ous
WAIT 10ms
NEXT
DO WHILE position >= 100
PULSEOUT GPIO.0, position 10us
position = position - 1
WAIT 5 10ms
LOOP
GOTO Main
I do not need a 1 us delays, but 1000, 1100,...,2000 us (or 1, 1.1, etc. miliseconds). And that is why I asked the question about the limitation--GC Basic or 12F508. At the moment, for my web camera tilt and pan project I am using 18F4550, but I realized that it definitely is an overkill (I am using only 6 bits of one port--4 switches and 2 servo signals). So, I thought, it would be a perfect use for such a humble piece. As I said in my initial post, the compiler and assembler refuse to create a hex file, due to my use of us in PULSOUT and WAIT statements. Again, thanks for your clarifications.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In the PULSEOUT line, it looks like you have a letter O in 10us, not the number.
Also, you need to specify a length for the delay, 10ms is just the unit. And finally, the 10ms routine calls the ms delay routine, which will overflow the stack on a limited chip like the 12F508, making it forget which bit of code called the delay in the first place. Wait 10 ms should have the desired effect, and you'll also need to change WAIT 5 10ms to WAIT 50 ms. This is something I will document, sorry for causing confusion by not mentioning it earlier!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
As Hugh has mentioned, the 12f508 is limited, you will be counting the variables till the COWS come home.....haha. The 12f683 would give you 4 times the variables and all the OSC options would be available. But for $1.18 at Newark its a little pricey. Was going to use that chip for an RC project, but not enough pins for any expansion.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
For beginners like me: Thanks to Hugh's and Kent's help, I made the simple servo control program to work. I've fixed the typos (letter "O" instead of digit "0") and added (or deleted) a space in front of time units (us and ms). The final form is:
#chip 12F508, 4
#config INTRC_OSC
dir GPIO b'001000'
Main:
FOR position = 100 to 200
PULSEOUT GPIO.0, position 10us
WAIT 10 ms
NEXT
DO WHILE position >= 100
PULSEOUT GPIO.0, position 10us
position = position - 1
WAIT 50 ms
LOOP
GOTO Main
=======================================
Hugh and Kent, thanks again.
vanneop at gmail
👍
1
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
First of all, thanks very much for such a tool--an open source Linux and Windows PIC Basic compiler. I am trying to compile a simple servo demo program that I found in one of the forums here. The error message says something about not being able to use us (microseconds) for <=4MHz pieces. My question: Is it a limitation of 12F508 or GC Basic itself?
Most likely the 12F508. Consider the Pic at 4Mhz is only going to give you 1us instructions, without any overhead. You may be able to use a constant value(s)?, but certainately not a variable in this instance.
If possible, use a device with a 8Mhz internal or 20 Mhz external clock to handle the overhead and variable values.
The trouble is that the shortest delay loop possible using a variable takes 3 instruction cycles for each repetition, plus at least 4 to load the delay value and call the delay routine. On faster chips, this code can easily run and be accurate to within 1 us.
On slower chips, the time taken for each delay loop becomes more than 1 us. On a 4 MHz chip, each delay loop would take 3 us, plus 4 us to call the delay routine. Adding code to divide the input time by 3 would take (from memory) somewhere near 80 or 90 cycles. Adding code to subtract the time taken for the call and the delay would take 4 cycles. This could end up resulting in a value that goes below 0. If this occurs, and it would for any delay under 80 us on a 4 MHz, then the PIC would have spent 80 us working out how much time it has to waste for a 1 us delay. Even with delays of over 80 us, the delay routine would only be accurate to within 3 us.
If you use a constant value for the delay, such as Wait 3 us, then GCBASIC can generate the code to waste the correct number of clock cycles during compilation, which will give you accurate timing.
Another option is to use the "10us" delay. This time period is long enough for even slower chips to be able to loop at least once within the 10 us.
And as Kent mentioned, you can upgrade to a faster PIC. Unfortunately this is really the only way to get accurate 1 us delays from a variable.
Kent and Hugh,
Thank you very much for your detailed explanations. It seems that I didn't make myself clear--for the servo control program that I am trying to compile
'A program to test a servo
#chip 12F508, 4
#config INTRC_OSC
dir GPIO b'001000'
Main:
FOR position = 100 to 200
PULSEOUT GPIO.0, position 1Ous
WAIT 10ms
NEXT
DO WHILE position >= 100
PULSEOUT GPIO.0, position 10us
position = position - 1
WAIT 5 10ms
LOOP
GOTO Main
I do not need a 1 us delays, but 1000, 1100,...,2000 us (or 1, 1.1, etc. miliseconds). And that is why I asked the question about the limitation--GC Basic or 12F508. At the moment, for my web camera tilt and pan project I am using 18F4550, but I realized that it definitely is an overkill (I am using only 6 bits of one port--4 switches and 2 servo signals). So, I thought, it would be a perfect use for such a humble piece. As I said in my initial post, the compiler and assembler refuse to create a hex file, due to my use of us in PULSOUT and WAIT statements. Again, thanks for your clarifications.
Could be Pulseout is not playing well? Why not try the equivalent:
Set GPIO.0 On
wait position 10us
Set GPIO.0 off
No compiler errors that I'm aware of, but then I don't have the very latest update either.
I think this code is the cause of the problem:
FOR position = 100 to 200
PULSEOUT GPIO.0, position 1Ous
WAIT 10ms
NEXT
In the PULSEOUT line, it looks like you have a letter O in 10us, not the number.
Also, you need to specify a length for the delay, 10ms is just the unit. And finally, the 10ms routine calls the ms delay routine, which will overflow the stack on a limited chip like the 12F508, making it forget which bit of code called the delay in the first place. Wait 10 ms should have the desired effect, and you'll also need to change WAIT 5 10ms to WAIT 50 ms. This is something I will document, sorry for causing confusion by not mentioning it earlier!
As Hugh has mentioned, the 12f508 is limited, you will be counting the variables till the COWS come home.....haha. The 12f683 would give you 4 times the variables and all the OSC options would be available. But for $1.18 at Newark its a little pricey. Was going to use that chip for an RC project, but not enough pins for any expansion.
For beginners like me: Thanks to Hugh's and Kent's help, I made the simple servo control program to work. I've fixed the typos (letter "O" instead of digit "0") and added (or deleted) a space in front of time units (us and ms). The final form is:
#chip 12F508, 4
#config INTRC_OSC
dir GPIO b'001000'
Main:
FOR position = 100 to 200
PULSEOUT GPIO.0, position 10us
WAIT 10 ms
NEXT
DO WHILE position >= 100
PULSEOUT GPIO.0, position 10us
position = position - 1
WAIT 50 ms
LOOP
GOTO Main
=======================================
Hugh and Kent, thanks again.
vanneop at gmail