View previous topic :: View next topic |
Author |
Message |
janbbeck
Joined: 23 Dec 2010 Posts: 7
|
PIC12LF1822 and PIC16LF1823 clock problems |
Posted: Thu Dec 23, 2010 10:59 am |
|
|
I cannot figure out how to get the delay_ms function to work. I can get delays by using the delay_cycles only.
The long version:
I am using the 12lf1822 and make a sample program using the pic wizard. I am simply trying to blink an LED.
first, the .h file produces a mess with the fuses:
Code: |
#include <12LF1822.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES WDT_SW #FUSES NOPUT //No Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOCLKOUT #FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOWRT //Program memory not write protected
#FUSES PLL #FUSES NOSTVREN //Stack full/underflow will not cause reset
#FUSES BORV19 #FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(int=4000000)
#define LED PIN_A5
#define DELAY 1000
|
which I fixed like this:
Code: |
#include <12LF1822.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES WDT_SW
#FUSES NOPUT //No Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOCLKOUT
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOWRT //Program memory not write protected
#FUSES PLL
#FUSES NOSTVREN //Stack full/underflow will not cause reset
#FUSES BORV19
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(int=4000000)
#define LED PIN_A5
#define DELAY 1000
|
the main program reads:
Code: |
void main()
{
//setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
//Example blinking LED program
while(true){
output_low(LED);
delay_ms(DELAY);
output_high(LED);
delay_ms(DELAY);
}
}
|
where I commented out the setup_comparator, because it would give a compiler error as well.
This then builds, but the frequency on the led as measured by oscilloscope is 7.4 KHz.
I can get this to work just fine on an 12F683.
Has anyone else got difficulty to set up the clock on these PICs?
I have a feeling the #use delay(int=4000000) is to blame, because if I modify the program to do nothing but
Code: |
void main()
{
//setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
//Example blinking LED program
while(true){
output_low(LED);
output_high(LED);
}
}
|
the LED pin switches at 100KHz. At a 4 MHz clock, this should switch much faster.
Any help at all would be greatly appreciated. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Dec 23, 2010 3:42 pm |
|
|
No....
4MHz = 1MIPS.
Each output, involves four instructions (two updating the TRIS, and two updating the output register). Total of 8 instruction times. Then the loop, involves a jump, which is two instruction times, so the expected rate, would be 100KHz exactly. You'd expect the LED to be on for 6uSec, and off for 4uSec.
You are getting exactly the speed expected.
You can improve this to 166KHz, by choosing fast_io, and setting this pin as an output (with a tris statement) before the loop.
The loop would be two instructions faster on a PIC16 chip, in the first case, since these support single instruction bit set/reset operations, not available on the PIC12...
Best Wishes |
|
|
janbbeck
Joined: 23 Dec 2010 Posts: 7
|
|
Posted: Thu Dec 23, 2010 5:13 pm |
|
|
Thank you for that. At least I know that I am running at the right clock rate.
Still the delay_ms does not work, and now my number of theories is down to 0.
Any ideas?
Ttelmah wrote: | No....
4MHz = 1MIPS.
Each output, involves four instructions (two updating the TRIS, and two updating the output register). Total of 8 instruction times. Then the loop, involves a jump, which is two instruction times, so the expected rate, would be 100KHz exactly. You'd expect the LED to be on for 6uSec, and off for 4uSec.
You are getting exactly the speed expected.
You can improve this to 166KHz, by choosing fast_io, and setting this pin as an output (with a tris statement) before the loop.
The loop would be two instructions faster on a PIC16 chip, in the first case, since these support single instruction bit set/reset operations, not available on the PIC12...
Best Wishes |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 23, 2010 5:16 pm |
|
|
Post your compiler version. |
|
|
janbbeck
Joined: 23 Dec 2010 Posts: 7
|
|
Posted: Thu Dec 23, 2010 5:50 pm |
|
|
PCM programmer wrote: | Post your compiler version. |
4.114
I also want to point out that delay_us works as advertised, as I just tested on the scope. Delay_ms does not.
if it helps, here is the assembly:
Code: |
.................... delay_ms(2);
001C: MOVLW 02
001D: MOVLB 00
001E: MOVWF 25
001F: GOTO 003
.................... output_low(LED);
0020: MOVLB 01
0021: BCF 0C.5
0022: MOVLB 02
0023: BCF 0C.5
.................... delay_us(200);
0024: MOVLW 21
0025: MOVLB 00
0026: MOVWF 20
0027: DECFSZ 20,F
0028: GOTO 027
.................... output_high(LED);
0029: MOVLB 01
002A: BCF 0C.5
002B: MOVLB 02
002C: BSF 0C.5
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Dec 24, 2010 1:25 pm |
|
|
I looked at the problem using the MPLAB simulator. It actually fails with
delay_us(). If the parameter is 765 or below, the compiler does a simple
loop to count the microseconds. That works OK. But with a delay of 766
or higher, as in
then it doesn't work correctly. It calls a delay routine, and it doesn't work.
The delay_ms() function also doesn't work. It fails with a parameter
of 1 or 1000. I didn't test any more values. These tests were done
with vs. 4.114.
Since delay_us(500) does work, you could create a work-around function
for delay_ms() as shown below. Note: This was only tested at 4 MHz.
Code: |
#include <12LF1822.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
void my_delay_ms(int16 delay)
{
while(delay--)
{
delay_us(500);
delay_us(500);
}
}
//================================
void main()
{
my_delay_ms(1000); // 1 second delay
while(1);
} |
The problem appears to be fixed in vs. 4.116, so if you have download
rights in effect, you could upgrade. If your download rights just ran out
recently, it's possible that you could report this bug to CCS and maybe
they would give you a free upgrade to 4.116. It's worth trying. But you
have to own the compiler to do this. |
|
|
janbbeck
Joined: 23 Dec 2010 Posts: 7
|
|
Posted: Wed Dec 29, 2010 1:43 pm |
|
|
Thanks for looking into this for me, but the delay_ms does not work for me with 4.116 either.
I am planning to use the touch sensor functions, and they use a ms delay as well, so I don't think the work around will do anything for me.
any other ideas? |
|
|
janbbeck
Joined: 23 Dec 2010 Posts: 7
|
|
Posted: Wed Dec 29, 2010 1:47 pm |
|
|
scratch my previous post. I had an evironment variable pointing to the old compiler.
4.116 in deed solves the problem.
Thanks again! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 29, 2010 1:49 pm |
|
|
What delay time are you using that fails in vs. 4.116 ?
Post the delay_ms() statement that fails. Also post your #use delay(). |
|
|
janbbeck
Joined: 23 Dec 2010 Posts: 7
|
|
Posted: Wed Dec 29, 2010 2:14 pm |
|
|
PCM programmer wrote: | What delay time are you using that fails in vs. 4.116 ?
Post the delay_ms() statement that fails. Also post your #use delay(). |
No, it does work now. Thanks a lot. Now I cannot get the sample code to work that is supposed to do a touch sensing, but I will start a new topic for that.
Thanks again! |
|
|
|