Have you seen this?
http://www.rentron.com/Infrared_Communication.htm
Have you seen this?
http://www.rentron.com/Infrared_Communication.htm
Dave
Always wear safety glasses while programming.
Hi,
I think that the highest frequency you can get out of the CCP module is 2.5Mhz when the chip running at 20Mhz. Even so I don't think it's going to do what you want since there's no easy way to control the number of cycles or "pulses" that is going out and as far I understand you need exactly 4096 "pulses".
Perhaps it's possible to connect the CCP output back into a counter input and set that up to generate an interrupt which stops the CCP module at the right spot but it seems like a long shot.
I'm definetly no "ASM-guy" but to set and reset a pin (or rather the port latch) in ASM you can do:But even if you put 4096 of those in a row you won't get more that 2.5Mhz because each instruction takes one cycle and one cycle is Fosc/4 meaning 200ns per cycle @20MHz so the frequency would be 1/400ns=2.5Mhz. Not to mention you'd fill up the flash memory of the 16F88....Code:@ BSF PORTA, 3 @ BCF PORTA, 3
How about this, I THINK it should run faster than your For i = 0 to 4095 loop.If I'm right that inner loop seems to execute in 7 cycles and the outer loop seems to take another 12 for a total of (7*256*16)+(12*16)=28864 cycles @ 200ns each. A total of 5772.8us for 4096 pulses or an average frequency of ~709kHz. There will be some jitter in the pulsestream when it goes from the inner to outer loop but I guess it doesn't matter(?)Code:i VAR BYTE j VAR BYTE For i = 1 to 16 '16*256=4096 For j = 0 to 255 @ BSF PORTA, 3 @ BCF PORTA, 3 NEXT NEXT
/Henrik.
Here's a neat trick to get 1MHz with a 20MHz oscillator. This takes 5 instruction cycles to toggle the pin, and Timer1 keeps track of the toggle count for you.
You don't need to use any incrementing or decremeting loops or variables.
1. Set T1CKI pin, and make the pin an output.
2. Load Timer1 low & high registers with 65,536 - the number of clocks to output & count.
3. Setup Timer1 for external clock, 1:1 prescaler, and turn it on.
T1CKI outputs your clock while Timer1 count increments on every low-to-high transition on T1CKI.
When PIR1,TMR1IF = 1 you have 4096 clocks. I tested this on a 16F877A, so just change the T1CKI pin to whatever it is on your PIC type.Code:PORTC.0 = 1 ' set pin so 1st low-to-high increments count TRISC.0 = 0 ' make pin an output Main: TMR1H = $F0 ' 65,536 - 4096 = 61,440 = $F000 TMR1L = $00 ' so 4096 toggles will set TMR1IF T1CON = %00000011 ' 1:1 prescaler, external clock, Timer1 on ASM Pulse BCF PORTC,0 ; clear T1CKI pin BSF PORTC,0 ; set T1CKI pin BTFSS PIR1,TMR1IF ; when TMR1 overflows, count is complete GOTO Pulse ; loop until Timer1 overflow BCF PIR1,TMR1IF ; clear TMR1 overflow flag bit ENDASM
Last edited by Bruce; - 18th May 2010 at 15:52. Reason: A better way
Son of a gun, that works (please note that T0CKI is RB6 on a 16F88).
The three cycle loop 'overhead' (BTFSS & GOTO) is a bottleneck. You could get better performance if you spread it out over more pulses. If you were to produce 16 pulses within the loop then you could use a single byte variable counter instead of Timer 1 and bump the output up to 2+ MHz.
Regards, Mike
Last edited by Mike, K8LH; - 18th May 2010 at 07:13.
Thank You Bruce for the code!!! I will try to get it loaded and tested tonight.
Mike are you saying Use a FOR Loop ouside of the ASM like this or is there an ASM FOR Loop I should be using for it (Keep in mind I dont know ASM):
Code:PORTB.6 = 1 ' set pin so 1st low-to-high increments count TRISB.6 = 0 ' make pin an output T1CON = %00000011 ' 1:1 prescaler, external clock, Timer1 on C1 VAR BYTE FOR C1 = 0 to 255 ASM Pulse BCF PORTB,6 ; clear T1CKI pin / 1 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 2 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 3 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 4 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 5 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 6 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 7 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 8 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 9 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 10 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 11 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 12 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 13 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 14 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 15 BSF PORTB,6 ; set T1CKI pin BCF PORTB,6 ; clear T1CKI pin / 16 BSF PORTB,6 ; set T1CKI pin ENDASM NEXT
I think this is what Mike was talking about?
This will give you 2.5MHz with every 16th logic 1 bit stretched to 4 cycles VS 1. If you can live with this bit being a tad longer, it will definitely speed things up.
With either version, make sure you have WDT disabled.Code:' define port & pin use in _Pulse @ #DEFINE PORT PORTB ' use any port you prefer, but declare it here @ #DEFINE PIN 6 ' same as above PORTB.6 = 1 ' initialize pin to idle state TRISB.6 = 0 ' make the pin an output C1 VAR BYTE BANK0 SYSTEM Main: C1 = 0 ' clear loop count CALL Pulse ' generate 4096 pulses GOTO Main ASM _Pulse BCF PORT,PIN ; clear pin / 1 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 2 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 3 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 4 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 5 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 6 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 7 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 8 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 9 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 10 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 11 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 12 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 13 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 14 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 15 BSF PORT,PIN ; set pin BCF PORT,PIN ; clear pin / 16 BSF PORT,PIN ; set pin DECFSZ C1,F ; decrement count, skip if 0 GOTO _Pulse ; not done, keep going RETURN ENDASM
I didn't have to turn off the WDT, I think its off by default but could not find where it tells me in the manual. What will happen if its on? Would I notice it?
I do have one issue but it might just be an issue with it being on a bread board but when I use the Define OSC 20 with the 20 MHz clock it freaks out and does what ever it feels like and is sensitive to the touch but when I use no Define or Define OSC 4MHz but run it with the 20MHz clock it runs fine...I don't get it haha
Thanks again everyone, I am very grateful for all your help and suggestions
Bookmarks