-
Re: Maximum frequency output from a PIC
As the wise man once said “necessity is the mother of invention”.
I’m sure that it will take you no time to build a “tool” to solve your problem. What about employing one more PIC to do the job for you? Set it up to count incoming pulses from your DUT for a set period of time and send the results to a LCD or to your preferred PC communication terminal for a visual. You just built yourself a home made, dirty cheap frequency counter ready to solve your problem now and help you in the future.
Just a thought.
Some experimenting and results in that matter were done in the beginning of this thread but unless you are starting with a really high clock flexibility is not that great. I’m not sure if the Assembly approach will bring any more advantage but, again it is out of my league.
Regards,
Nick
-
Re: Maximum frequency output from a PIC
Looks like I'll have to.
I always thought if I have a 5 Volt square wave,
that my multimeter would measure it as 2.5 Volts.
I never considered the sampling frequency of the multimeter has
no connection with the frequency of the signal being measured.
-
Re: Maximum frequency output from a PIC
Hi again,
I’m trying to move what I learned last week to a larger PIC (PIC16F819) which I have a lot of leftovers and I’m trying to make use of. I’m also trying to increase my output frequency by using a 16MHz oscillator.
Based on what the data sheet shows I should have about the same setup as I had with PIC12F683 except that I could select between RB2 and RB3 as my output.
With the above code I get good output on RB1 (led out which proves that the system is running) but I do not get any output on RB2 or RB3. I was hoping that it will go by default on one of them.
Code:
@ device pic16F819, wdt_off, hs_osc, pwrt_on, mclr_off, lvp_off, protect_on
DEFINE OSC 16 ' We're running at 16 Mhz
ADCON1=%01001110 ' Digital only for all pins
led var PORTB.1
i var byte
CCP1CON = %00001100 ' Normal PWM
PR2 = 3
CCPR1L =0
CCP1CON.5 = 1
CCP1CON.4 =1
For i = 0 to 9
Toggle LED
Pause 500
NEXT
Main:
high led
CCP1CON = %00001100 ' Normal PWM mode
T2CON.2 = 1 ' Timebase ON
PAUSE 15
low led
T2CON.2 = 0 ' Timebase OFF
CCP1CON = %00000000 ' Disable PWM to regain control of PortA.2
PAUSE 5
Goto Main
The data sheet states:
The CCP module’s input/output pin (CCP1) can be
configured as RB2 or RB3. This selection is set in bit 12
(CCPMX) of the Configuration Word register.
I have no idea how to change this setting and if this is the reason why I get no output.
Is there anything that I should do differently?
Thank you in advance for any input.
Nick
-
Re: Maximum frequency output from a PIC
Hi Nick,
1) Add _CCP1_RB2 or _CCP1_RB3 to your line of config directives in order to select which pin to be used as the CCP1-pin. But yes it WILL default to one of them.
2) When the PIC starts all pins are set to be input. You need to set RB2 or RB3 to be an output by clearing the coresponding bit in the TRISB register. The reason the LED works is because commands like TOGGLE, HIGH and LOW handles clears the TRIS-bit for you - each and every time the command is executed.....
3) Not that it matters but anyway, as far as I can see the 16F819 can not do 16MHz on its internal oscillator, up goes the partcount you said you want to keep low. If running at 16MHz is the main reason for switching to the 16F819 you could just as well stuck that 16MHz oscillator on the 12F683.
/Henrik.
-
Re: Maximum frequency output from a PIC
Hi Henrik,
Thank you for pointing out my stupid mistake. I knew it must be something I overlooked.
In my defense I have to say that after copying the code from 683 I made the necessary changes on the top of the code to apply it to 819. In the process I removed the TRISIO line from the old code and look up the corresponding line for 819. I got distracted (which is quite easy at my age) and did not finish it. My mind was set that I did it so I was looking for something else.
I will add extra configs and test it again after work tonight.
To answer your question why I’m using an external oscillator: I would like to experiment with higher frequencies and I have plenty of 819 (some of them on PCBs ready to use as prototyping boards).
I will order some more oscillators (or try to locate the ones I have somewhere in my garage) for all PBP supported frequencies and have a wide range of available frequencies in the range of 250KHz to 5MHz. Also I could not find any PIC supported by my setup that will do more than 8MHz on internal oscillator.
After Art’s post I realized that my signal generator outputs only signals lower than 2MHz so I have to compensate for the difference.
I’m doing the same thing with the 683 (recycling old rev boards) but the 683 version is extremely small (less than 1² inch) and they do not have the padding for the oscillator.
For the working project I’m still using the low part count concept.
Regards,
Nick
-
Re: Maximum frequency output from a PIC
I've added the two extra configs and I got output on RB2.
I did not have time to play more but I will do as soon as I will return from a two weeks vacation.
Regards,
Nick
-
Re: Maximum frequency output from a PIC
You could try putting the code you want to be called the fastest, closest to zero vector.
Labels called with a Goto command causes the program counter to start looking for your label from zero,
so the closest it is to zero, the faster it is found, and run.
So without looking at anything else about your code:
Code:
// the following is not run time code, so who cares…
@ device pic16F819, wdt_off, hs_osc, pwrt_on, mclr_off, lvp_off, protect_on
DEFINE OSC 16 ' We're running at 16 Mhz
led var PORTB.1
i var byte
// jump to config vector
Goto Config
Main:
high led
CCP1CON = %00001100 ' Normal PWM mode
T2CON.2 = 1 ' Timebase ON
PAUSE 15
low led
T2CON.2 = 0 ' Timebase OFF
CCP1CON = %00000000 ' Disable PWM to regain control of PortA.2
PAUSE 5
Goto Main
Config:
ADCON1=%01001110 ' Digital only for all pins
CCP1CON = %00001100 ' Normal PWM
PR2 = 3
CCPR1L =0
CCP1CON.5 = 1
CCP1CON.4 =1
For i = 0 to 9
Toggle LED
Pause 500
NEXT
// run main program
Goto Main
-
Re: Maximum frequency output from a PIC
This is a nice tip Art.
I will only have the chance to try it after my well overdue vacation, just for fun.
Just so I understand your tip correctly for the sample code presented it will make the GOTO jump in the main loop much faster in which case the main loop will be faster and the second half of the loop will be closer to the target 5 mS?
For my particular application this is not a big advantage but for time sensitive applications it might make a difference. All I need in this case is to create a 20 mS frame with a 15 / 5 mS ratio.
I can only guess that the Rx program might benefit from that but in my case the really fast action happens behind the scene and I think that the system is pushed to its maximum.
I was always under the impression that each PBP command has a fixed amount of execution time but your suggestion proves me wrong.
How is your project going?
One correction to my statements few posts ago: I mentioned that I will try to increase my available frequencies by employing a PIC16F819 with higher frequency external oscillators to cover 2 MHz – 5 MHz band but I just realized that my math was wrong. For some reason I was under the impression that you can get a maximum Fosc / 4 out of PWM module but the formula proves me wrong again, it is only Fosc / 8. I think that I was biased by the fact that the Fosc / 4 is available on clock out feature.
Anyway recycling few boards that will only collect dust in my garage is still good enough even though the expected results are a bit lower.
Regards,
Nick
-
Re: Maximum frequency output from a PIC
Yes, as I understand, the major delay per cycle is the "Goto Main".
It's not my suggestion that proves you wrong, it's you timing it ;)
Then if you work out how long the Goto takes to execute, you can
subtract that from the 5 value in your PAUSE 5 command, and you're
fine until you put anything between the start of your program and the
end of main, or also if you use a beefy command like sound, or serin/out
etc., as they put code in the front of your program for the same reasons
(they want to execute fast also).
-
Re: Maximum frequency output from a PIC
Hi,
I'm definitely no expert on the low level stuff but I do think there's some misunderstaning / confusion going on here.
When you execute a GOTO Label it's NOT like the program starts from the top and then "searches" thru the code until it finds the Label to which you want to GOTO.
The physical adress of the piece of code starting "at" Label is known when the program is compiled so the GOTO Label is simply replaced with GOTO $xxxx where xxxx is the physical adress in program memory where the particular piece of code is located. A GOTO always takes TWO instruction cycles, no more no less.
But, some PICs have its program memory divided into pages and when a GOTO is executed it's important that it GOTO's the adress in the correct page. The compiler handles this for you when needed (that's the warning you see sometimes, Code crosses page boundries or something like that). Making sure you're in the correct page does take a couple of instructions as well so all in all the GOTO CAN take more than 2 instruction cycles but not much. So it CAN make a (small) difference rearanging the routines so it doesn't need to jump across page boundires when executing a GOTO but most of the time you simply wouldn't care.
In this particular case the GOTO Main will take 2 cycles. Only if the Main routine would end up starting in one page and ending in the next would it take more than 2 cycles.
Interrupt service routines are one thing where it can matter. Since the hardware interrupt vector is at adress $0004 (IIRC) it makes sense (if you're looking for the absolute best performance) to place your interrupt service routine at the top of the program (and jump over it of course). If you don't do this it MIGHT end up in another memory page and you'll loose a few cycles every time it needs to set the correct page bits before jumping to the ISR.
Again, I'm no expert so I might very well have some details wrong - I'm happy to be corrected.
/Henrik.
-
Re: Maximum frequency output from a PIC
Henrik,
I don't have the definitive answer either, but I think that what Art is suggesting makes sense to me. I have tried moving to the beginning of the program subroutines that I use a lot in the program and the used programming code space is reduced by a good number of bytes. So, I assume that the program is also executing faster. I believe that this has something to do with the way the program memory is organized in pages in many PICs.
Robert
-
Re: Maximum frequency output from a PIC
Hi,
On the 12F683 and 16F819 there is only one page of program memory so it doesn't (or shouldn't if my reasoning is correct) matter where you put anything because there will never be a need to switch pages.
If I understand what Art wrote correctly he's basically claiming that the "further" the GOTO jump is, the longer it takes and the further "down the list" your subroutines are placed the longer it takes to GOSUB them because the program counter starts "searching for them" from the beginning of the program. I don't think that is correct - neither on PICs with a single memory page nor on those with multiple pages.
If using a PIC with the program memory spanning several pages and it has to jump (GOTO or GOSUB) from ona page to another then the compiler will insert code to make sure the correct page is selected before executing the GOTO but it either does that or it doesn't and that piece of code (to select the correct page) will be always take the same amount of time (a couple of cycles I imagine), it doesn't matter where or "how far" it is going to jump.
/Henrik.
EDIT: Robert, which PIC did you use in the project where you moved the subroutines?
-
Re: Maximum frequency output from a PIC
That is right sorry, I have my interpreted and compiled BASICs mixed up.
It's probably not bad practice anyway, so that your fast code is not kicked
out of the first page when you add picbasic's macro type commands such
as serin/out, DTMF, SOUND, pauseus, etc.
It also matters with C later on, to to avoid forward declarations.
It makes me wonder now, if every goto command also has the PCLATH
command with it, or if picbasic waits till the program extends past the 2K page (probably does).
You also turned off the watchdog, but didn't tell PBP not to insert clrwdt commands.
You would only need a single asm "@ clrwdt" inside the whole Main loop,
and calculate that into your subtract from the delay time,
but they are likely in the PAUSE commands, and factored into timing I think.
-
Re: Maximum frequency output from a PIC
Nope, not bad practice at all, I just don't see it making any difference in this application. But again, do try it - I might be wrong!
As for tweaking the delay time, it's a good thing to keep in mind for when timing is REALLY criticial but for this application, I don't know.... IMHO it's making things WAY more complicated than it is....
We're talking 20ms total period time here (ideal), 15ms 'carrier on', 5ms 'carrier off'. The PIC is running at 8MHz so each instruction is 500ns, it takes two instruction cycles to GOTO Main, add another couple of instructions for the rest, lets call it 20 in total - the actual period would be 20.01ms, an error in timing of 0.05%, I think that miniscule error will be swamped by the inacuracy of the internal oscillator. Of course, it MIGHT matter but then you need something better than the internal oscillator to run it.
/Henrik.
-
Re: Maximum frequency output from a PIC
Henrik,
I think used a PIC16F727 when I did that. I think I got that idea of moving the most used subroutines to the beginning of the program when reading a post by Melanie. It had something to do with saving programming space in a PIC. I will try to find that thread later.
-
Re: Maximum frequency output from a PIC
-
Re: Maximum frequency output from a PIC
Henrik was right there, I was selling PBP short.
It shouldn't matter with PBP programs under 2K anyway,
but you'll appreciate the practice if you use another language.
You remember the old interpreted BASIC with line numbers?
Code:
10 CLRSCREEN
20 PRINT "HELLO WORLD"
30 GOTO 20
It's the goto in that one that searches a list to find the line/label it's after.
In this case (30 GOTO 20), it searches from the beginning, but if the destination
line is after the GOTO command, it searches from the GOTO command onward.
Some interpreted Pic BASIC language (not PBP) probably does the same thing
even if you don't need to use the line numbers anymore.
If you just want to check a byte variable is in BANK0 to access it without switching,
you can increment it with inline assembler.
should be the same as
If byte B1 was not in BANK0, a different variable or some unassigned RAM will be incremented.
-
Re: Maximum frequency output from a PIC
Hi,
Robert,
Yes, the 16F727 has its program memory divided into four pages so I can see it making a difference on that one. But still, I'm not cyet onvinced that having them "first" is what actually helps, I believe it's more like where they (the subroutines that is) are relative to where the calls TO them are. I mean, calling subroutines in page 0 from Main in page 1 should be no different from calling subroutines in page 1 from Main in page 0....it needs to switch page in both cases.
Darrel or anyone - are you listening? Care to share some details?
Art,
If that interpreted BASIC, whichever it is, really works like that it kind of sucks - big time IMO.
As for the rest, you're now talking about RAM and not program memory.
/Henrik.
-
Re: Maximum frequency output from a PIC
Yes, unfortunately I don't know the facts either. It would be good if somebody else clarifies this point here.
-
Re: Maximum frequency output from a PIC
I've posted a question on the MELABS support forum. Hopefully Darrel or someone else will give us some insight.
/Henrik.
-
Re: Maximum frequency output from a PIC
Quote:
Originally Posted by
HenrikOlsson
Hi,
Art,
If that interpreted BASIC, whichever it is, really works like that it kind of sucks - big time IMO.
As for the rest, you're now talking about RAM and not program memory.
/Henrik.
The second part is in relation to the link posted (keeping vars in BANK0 - avoiding switch statements).
I will try to explain why it is important to put code you want to run fast at the beginning of your PBP program,
even though I was incorrect as to one of the reasons why, there are more, and PBP actually does this in the
compiled assembler program (with it's own function calls, not yours) whether you like it or not.
You want to keep most called functions (PBP routines) in the first 2K code space to avoid page switching.
You also want to keep most used variables in Bank0 to avoid bank switching (for RAM).
Say you fill up the first 2K page with code, and run into the second code page,
then introduce a serin or serout command in the second code page.
PBP doesn't put the serin command where you wrote it.
Every PBP macro command such as serial is placed at the beginning of the generated
assembler code, which kicks some of your your PBP code out of the first 2K code space.
What is placed where you wrote the serial command is a series of gosubs that pass
individual bytes to the assembler routine which has been placed at the beginning of the asm source.
You wil notice that if you use a second serial command, your code size doesn't massively increase again
because the original asm routine that was inserted by the first serial command is reused.
When you use a serin, and serout command, this is the decompiled assembler that is placed
at the beginning of your compiled code to deal with it:
Code:
SerialIN ;receive serial byte with pre-determined timeout
movf R6 ,W ;move timeout delay to temp
movwf R0 ;
movf R15 ,W ;
movwf R9 ;
movlw 0x01 ;
movwf R1 ;set inside loop counter
clrf R10 ;
serial_loop ;
clrwdt ;keep watchdog timer clear
call SerinX ;get one bit
btfss status ,C ;wait for start bit
goto serinstart ;
decfsz R1 ,F ;
goto serial_loop ;
movlw 0xFF ;
addwf R10 ,F ;
btfsc status ,C ;
goto serial_loop ;
addwf R0 ,F ;
btfss status ,C ;
addwf R9 ,F ;
btfss status ,C ;
goto DoneX ;time out
movlw 0x32 ;
movwf R1 ;reset inside loop counter
clrw ;
movwf R10 ;
goto serial_loop ;
SerialIN_notimeout ;
clrwdt ;receive byte serialy with no timeout
call SerinX ;get one bit
btfsc status ,C ;wait for start bit
goto SerialIN_notimeout ;
serinstart ;
call serialdelay ;wait 1/4 bit time
clrf R4 ;zero parity accumulator
movlw 0x08 ;number of bits in one byte
movwf R10 ;
serpar ;
call seroutdelay ;wait bit time
call SerinX ;get one bit
btfsc status ,C ;accumulate parity
incf R4 ,F ;
btfss R14 ,05 ;if no parity...
clrf R4 ;...keep it even
rrf R1 ,F ;move bit into byte
decfsz R10 ,F ;check for more bits
goto serpar ;
btfsc R14 ,05 ;if parity...
bcf R1 ,07 ;...clear top bit of result
call seroutdelay ;delay to stop bit
bsf status ,C ;carry shifts in clear
movf R1 ,W ;get char to W
return ;
SerinX ;
movf RR2 ,W ;receive one bit for serial in
movwf fsr ;
movf RR1 ,W ;
bsf fsr ,07 ;
iorwf indf ,F ;
bcf fsr ,07 ;
andwf indf ,W ;
btfsc R14 ,06 ;
xorwf RR1 ,W ;
addlw 0xFF ;
return ;
SerialIN_skipbyte ;
movf R13 ,W ;ignore received byte for serial in
bsf status ,C ;
btfsc status ,Z ;
goto DoneX ;
call skipX ;
btfss status ,C ;
return ;
decf R13 ,F ;
goto SerialIN_skipbyte ;
serialOUT ;transmit byte serialy from port pin
movwf R3 ;save byte to send
movf RR2 ,W ;get port to fsr
movwf fsr ;
movlw 0x80 ;zero parity accumulator (preserve blanking)
andwf RM2 ,F ;
movlw 0x08 ;1 start bit + 7 data bits
movwf R12 ;
bcf status ,C ;start bit low
seroutloop ;
btfsc status ,C ;accumulate parity bits
incf RM2 ,F ;
call seroutbit ;send a bit and delay bit time
rrf R3 ,F ;move to next bit
decfsz R12 ,F ;do next bit, if any
goto seroutloop ;
nop ;
btfsc R14 ,05 ;send parity
rrf RM2 ,W ;get parity to carry
call seroutbit ;send parity or last bit and delay bit time
call Done ;
bsf status ,C ;stop bit high
call seroutbit ;send stop bit and delay bit time
movf R16 ,W ;do pacing
movwf R10 ;
movf R7 ,W ;
goto DelayX ;
seroutbit ;
bcf fsr ,07 ;make sure we're pointing to the port
btfss R14 ,07 ;check for TRIS mode
goto seroutnorm ;handle normal mode
movf indf ,W ;get port data
iorwf RR1 ,W ;set bit on
btfss R14 ,06 ;bit matches invert mode
xorwf RR1 ,W ;set bit off
movwf indf ;write it out
bsf fsr ,07 ;point fsr to port tris
movf indf ,W ;get tris data
iorwf RR1 ,W ;make bit an input
btfss status ,C ;bit direction matches bit
xorwf RR1 ,W ;make bit an output
movwf indf ;write it out
goto seroutdelay ;wait remainder of bit time
seroutnorm ;
movf indf ,W ;get port data
iorwf RR1 ,W ;set bit on
btfss status ,C ;skip if bit should be on
xorwf RR1 ,W ;set bit off
btfsc R14 ,06 ;invert if 'N' mode
xorwf RR1 ,W ;flip for invert
movwf indf ;write it out
bsf fsr ,07 ;point fsr to port tris
comf RR1 ,W ;get complemented bit mask to W
andwf indf ,F ;clear tris bit to set output
goto seroutdelay ;wait remainder of bit time
serialdelay ;
bsf RM2 ,06 ;
seroutdelay ;
movf R14 ,W ;get high baud byte
andlw 0x1F ;mask to our bits
addlw 0xFF ;fix baud
movwf R9 ;save it
movf R5 ,W ;get low baud byte
addlw 0xF5 ;
btfsc status ,C ;bump up high byte if low overflowed
incf R9 ,F ;
btfss RM2 ,06 ;
goto pauseUSL ;
bcf RM2 ,06 ;clear short delay mark
movwf R0 ;save low part
movlw 0x02 ;divide time by 4
call shiftR ;
goto pauseUSL ;do 1/4 delay
That's quite a lot of code asking to be placed in the first 2K code space (and kicking your code out).
The serial always appears to be placed first, then SOUND, then EEPROM, then PAUSE.
If you use any PAUSE command, this is inserted:
Code:
Delay
clrf R10 ;delay 1
DelayX ;
movwf R1 ;delay 2
DelayXX ;
movlw 0xFF ;
addwf R1 ,F ;
btfss status ,C ;
addwf R10 ,F ;
btfss status ,C ;
goto DoneX ;
movlw 0x03 ;
movwf R9 ;
movlw 0xDF ;
call pauseUSL ;
goto DelayXX ;
clrf R9 ;
pauseUSL ;
addlw 0xE8 ;
movwf R0 ;
comf R9 ,F ;
movlw 0xFC ;
btfss status ,C ;
goto XpauseUSL ;
pauseX ;
addwf R0 ,F ;
btfsc status ,C ;
goto pauseX ;
XpauseUSL ;
addwf R0 ,F ;
clrwdt ;
incfsz R9 ,F ;
goto pauseX ;
btfsc R0 ,00 ;
goto pausedoneX ;
pausedoneX ;
btfss R0 ,01 ;
goto pausedone ;
goto Done ;
or on chip-EEPROM Read/Write:
Code:
EEPROMread ;read byte from on-chip EEPROM
bsf status ,rp0 ;for bank 1
movwf EEADR ;set the EEPROM address
bsf EECON1 ,0x0 ;EECON1 in bank 3
movf EEDATA ,W ;read from data memory
goto DoneX ;done
EEPROMwrite ;write byte to on-chip EEPROM
bsf status ,rp0 ;for EE in bank 1
movwf EEDATA ;set the EEPROM data
bsf EECON1 ,02 ;
movlw 0x55 ;unlock the door
movwf EECON2 ;
movlw 0xAA ;
movwf EECON2 ;
bsf EECON1 ,01 ;do the write
writeloop ;
btfsc EECON1 ,01 ;wait for the write to complete
goto writeloop ;
bcf EECON1 ,02 ;lock up when we're done
goto DoneX ;
So bottom line is if you are using any of these, insert them in your code once, straight away
before bothering with timing, or determining which bank you want your variables to be in.
Then you can add additional identical commands without worrying about anything else being added.
All of these commands reuse the code from the first time they were used in a PBP program.
Cheers, Art.
-
Re: Maximum frequency output from a PIC
Hi Art,
I know most of that, the thing I'm having proplem with is this
Quote:
You want to keep most called functions (PBP routines) in the first 2K code space to avoid page switching.
If the calling line (the GOSUB in your "main" routine) ends up in Page 1 while the sub is in Page 0 it STILL needs to switch pages - that's what I'm saying.
But...Darrel just responded to the post on the MELABS forum with some details and it turns out that GOSUBing from Page 1 to Page 0 does indeed take one instruction less than the other way around - go figure. But (again) if everything fits within the same page (Page 0) then that same GOSUB now takes 3 instructions instead of 2. Go figure...
/Henrik.
-
Re: Maximum frequency output from a PIC
I always thought the PBP author put his routines closest to zero vector
for the reason I gave. Now, since you sorted me out on that,
I think it's to avoid bank or page switching in his asm code to both
make it smaller, and if he didn't always know the internal variables were in bank0,
timings of the routines would be a pain, just as it can be here.
Quote:
If the calling line (the GOSUB in your "main" routine) ends up in Page 1 while the sub is in Page 0 it STILL needs to switch pages - that's what I'm saying.
There are often only a few loops where timing is an issue, like in the first example of this thread.
or, for example, something that is sending or receiving bytes at a time in a for next loop can be
called from anywhere and contained in the first 2K.
Quote:
Page 1 to Page 0 does indeed take one instruction less than the other way around - go figure.
I haven't found the post, but it's cheaper to write a zero value than anything else,
that is done with a single clrf instruction, but writing a one takes two instructions.
Quote:
if everything fits within the same page (Page 0) then that same GOSUB now takes 3 instructions instead of 2. Go figure.
That one's got me stumped. I would like to see the disassembly.
A jump from page 0 to page 0 should just be a gosub as if you are using a 2K chip.
You'll notice in the code above there are no asm gosubs.
Only returns to the gosubs that called the routines.
I think they must be more expensive, but that doesn't explain the difference.
-
Re: Maximum frequency output from a PIC
Quote:
Originally Posted by
HenrikOlsson
if everything fits within the same page (Page 0) then that same GOSUB now takes 3 instructions instead of 2. Go figure...
I think it is because it does not know if it is in page 0 or 1 or else, so a test must be done first?
Ioannis
-
Re: Maximum frequency output from a PIC
Hi,
Here's a link to the thread on MELABS forum. Darrel posted code there which he used to demonstrate, I'm sure you can disassemble that.
/Henrik.
-
Re: Maximum frequency output from a PIC
Quote:
Originally Posted by
HenrikOlsson
Hi,
Here's
a link to the thread on MELABS forum. Darrel posted code there which he used to demonstrate, I'm sure you can disassemble that.
/Henrik.
Hmm, I knew that the used programming space goes down, but I had no idea that it had to do with the GOSUBs. Also, it is good to know that the enhanced chips do not have this issue.
-
Re: Maximum frequency output from a PIC
Hi Team,
I am using the setup from post #43 and I need a clarification on how the duty cycle setting works.
If I understood the data sheet correctly for a 16 MHz main clock and an output frequency of 250 KHz I have access to 16 steps of duty cycle.
Also the manual states that you can use CCPR1L which is 8 bit wide and CCP1CON.5 plus CCP1CON.4 so you have access to a 10 bit wide setting.
My question is who keeps track of individual values and their place in the 10 bit variable.
Is the user supposed to do the logic or PBP takes care of it?
For example if I use something like this:
CCPR1L = 5
CCP1CON.5 = 1 (an 0 means 0 and an 1 means 2)
CCP1CON.4= 0 (an 0 means 0 and an 1 means 1)
Is the result 7 so we just add the two values or is it 21 which comes from 5 shifted twice and add 2 from CCP1CON.5 ?
Does one have to pick only multiple of 4 when choosing CCPR1L or whatever value is given is taken as a 10 bit value and added to CCP1CON 4 and 5?
Regards,
Nick
-
Re: Maximum frequency output from a PIC
Hi,
With 16MHz main clock there are three different prescaler ratios all giving you 250kHz but different number of bits of resolution.
If you set prescaler to 1:2 and load PR2 with 3 then you'll get 250kHz and 5 bits of resolution (not 5 "full" bits actually), ie you can set the dutycycle value anywhere between 0 and 16.
If you set the prescaler to 1:1 and load PR2 with 15 you'll get the same frequency but now you've got better resolution, 0-64 instead of 0-16.
Now, just write out whatever value you want in binary as a 10bit value: %0000010110
The two least significant bits goes to CCP1CON.5 and CCP1CON.4 and the remaining 8 bits goes to CCPR1L, in this case (as in your example) the result would be 21 which would result in either 100% or ~20% depending on the prescaler and PR2 setting as outlined above.
/Henrik.
-
Re: Maximum frequency output from a PIC
Thank you Henrik.
It makes more sense to me now.
Regards,
Nick