Hi Henrik,
Thank you for the sample code.
I will do some “hammering” tonight and report the results.
Regards,
Nick
Hi Henrik,
Thank you for the sample code.
I will do some “hammering” tonight and report the results.
Regards,
Nick
Results after the “hammering” session today.
Testing setup as follows:
One PIC12F683 acting as Tx module. It output bursts of 15 mS 500Khz carrier on CCP1 pin (pin 5) followed by 5mS no carrier. Pin 2 of the PIC is high when carrier ON and low when carrier is OFF.
Second PIC12F683 acting as Rx is connected to the same 5V supply and has its TOCKI pin (pin 5) connected to CCP1 pin of the Tx PIC. Pin 2 of this PIC drives a LED.
After adding some configuration lines and fix some oldCount speling I ran few simple tests to make sure the connections and configs are OK I ran the sample code.
Unfortunately it did not work and the problem was on the Rx side. Monitoring the signals from Tx they were what they should be. Rx will output some very random signals or no signals at all.
So I started messing with the code and try few alterations of the Rx program. I realized that some different handling of TMR0 and oldCount needs to be implemented. I have to confess that some of the results did not make sense to me at the time but by pure luck (I left a code line behind in the first WHILE / WEND loop got some meaningful results).
I do not know enough about the insides of the WHILE / WEND loop but, after violating its condition. I also think I broke few other rules of programming and according to the well known rule if something works there must be at least two mistakes that compensate each other.
The Rx and Tx codes that follow are working and my old analog scope shows perfectly matched signals on the Tx and Rx PICs.
Tx code:
Rx code:Code:@ device pic12F683, intrc_osc_noclkout, wdt_on, mclr_off, protect_off DEFINE OSC 8 ' We're running at 8 Mhz OSCCON=%01110111 ' 8MHz internal osc ANSEL = 0 ' Digital only for all PortA pins TRISIO=%00100000 ' Make PORTA outputs out var GPIO.5 CCP1CON = %00001100 ' Normal PWM PR2 = 3 ' 1MHz output @8MHz system clock CCPR1L = 2 ' 50% Dutycycle CCP1CON.5 = 0 CCP1CON.4 =0 T2CON.2 = 1 Main: high out T2CON.2=1 ' Osc ON PAUSE 15 low out T2CON.2=0 ' Osc OFF PAUSE 5 Goto Main
Can somebody explain me why this code is working?Code:@ device pic12F683, intrc_osc_noclkout, wdt_on, mclr_off, protect_off DEFINE OSC 8 ' We're running at 8 Mhz OSCCON=%01110111 ' 8MHz internal osc ANSEL = 0 ' Digital only for all pins TRISIO=%00100100 ' Make PORTA outputs oldCount VAR byte LED VAR GPIO.5 oldCount = 0 'Clear count LED = 0 ' Turn off LED ' Set TMR0 up as a counter, signal fed into T0CKI pin OPTION_REG.5 = 1 Main: While TMR0 <> oldCount ' There has been pulses since last time we checked high led oldCount = TMR0 ' Store current count Wend low led oldCount =0 TMR0=0 While oldCount=TMR0 low led wend GOTO main
Regards,
Nick
Hi Nick,
Sorry about the typo, told you I didn't test it though.
Currently I have no idea why my original code (less the typo) did not work while your new one does. I just tried it here, again with two 12F1840's so that MIGHT have something to do with it but I don't think so. I also figured out that once you've enabled PWM mode on the CCP pin you can't control that output manually. So in order to force the PWM output low during the OFF period of the carrier you have to disable the CCP module and THEN force it low, I've implemented that in the TX-code below:For the RX-side I did this, which is pretty much exactly like I wrote it earlier. I found that I could ditch the delay to speed up the response time since the exection time for the loop is longer than the PWM-period. If you change the frequency you may need to add some delay.Code:' *************************************************************** ' Device Fuses ' *************************************************************** #CONFIG __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF #ENDCONFIG ' *************************************************************** ' Compiler directives ' *************************************************************** DEFINE OSC 8 ; We're running at 8Mhz ' *************************************************************** ' Variables and aliases ' *************************************************************** i VAR BYTE LED VAR PortA.4 ' *************************************************************** ' Initialization ' *************************************************************** OSCCON = %01110000 ' 8MHz internal osc ANSELA = 0 ' Digital only for all PortA pins TRISA = %00000000 ' Make PORTA outputs CCP1CON = %00001100 ' Normal PWM PR2 = 3 ' 500kHz output @8MHz system clock CCPR1L = 2 ' 50% Dutycycle CCP1CON.5 = 0 CCP1CON.4 = 0 ' *************************************************************** ' Actual program ' *************************************************************** ' Show that we're up and running. For i = 0 to 9 Toggle LED Pause 200 NEXT Main: CCP1CON = %00001100 ' Normal PWM mode T2CON.2 = 1 ' Timebase ON PAUSE 15 T2CON.2 = 0 ' Timebase OFF CCP1CON = %00000000 ' Disable PWM to regain control of PortA.2 PortA.2 = 0 ' Force output low to prevent saturation of coil PAUSE 5 Goto MainI'm going to try to add two screen-grabs from the scope. Last time I did the uploader didn't work but hopefully that's fixed by now. Nope the bloody thing still doesn't work, sorry but you'll have to trust me that it does work here.Code:' *************************************************************** ' Device Fuses ' *************************************************************** #CONFIG __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF #ENDCONFIG ' *************************************************************** ' Compiler directives ' *************************************************************** DEFINE OSC 8 ; We're running at 8Mhz ' *************************************************************** ' Variables and aliases ' *************************************************************** oldCnt VAR BYTE i VAR BYTE LED VAR PortA.4 ' *************************************************************** ' Initialization ' *************************************************************** OSCCON = %01110000 ' 8MHz internal osc ANSELA = 0 ' Digital only for all PortA pins TRISA = %00000100 ' T0CKI is input, rest outputs ' *************************************************************** ' Actual program ' *************************************************************** OPTION_REG.5 = 1 ' TMR0 as counter oldCnt = 0 TMR0 = 0 ' Show the world that we're alive For i = 0 to 9 Toggle LED PAUSE 200 NEXT Main: IF TMR0 <> oldCnt THEN LED = 1 ELSE LED = 0 ENDIF oldCnt = TMR0 Goto Main
/Henrik.
Hi Henrik,
Thanks again for your patience with me.
Your code makes much more sense to me so I will try it again tonight. I can only guess that as long as the execution time of the main loop is longer than the carrier period we should be fine. If that is not true there should be short glitches during the carrier ON period. Increasing the carrier frequency should be fine while going lower might require some delay.
I can only hope that first time it might have been a stupid mistake on my side.
Now that the setup is fine-tuned there should be no reason why it should not work.
I will report the findings as soon as I have results.
Regards,
Nick
Hi Nick,
Yes, as long as the loop takes longer to exectute than the period time of the PWM signal (2us in this case) it'll work without additional delay in there. When running at 8MHz each ASM instruction takes 500ns so there's really only time 4 instructions in this case. The Goto Main takes 2 and the jump caused by the IF-THEN takes 2 so that's 4, then we have the rest so it's pretty safe to run it without any delay.
Here are the screenshots I mentioned:
/Henrik.
Hi Henrik,
I just can’t wait to try the code again (that will be in a couple of hours after I get off work).
The signals look really good. Only about 12 uS delay on the falling edge which is better than I need. Is it the same at the rising edge?
Thanks,
Nick
Hi Nick,
Yes and no....
Yes because it's going to be in the same ballpark.
No, because it's not going to be an absolute number (on the rising OR falling edge) because the carrier signal might "come on" (or off) at any time. If it happens to do that just before we check it the delay will be very short, if it happens to do it just after we just checked the delay will be a little longer.
I measured a couple of pulses here.
Delay on rising edge: 10, 7.5, 9.5, 10, 7.5, 6.5 us
Delay on falling edge: 9.5, 11.5, 12, 8, 8, 11 us
So I think you can consider 12us to be around the worst case for this particular code. Would you prefer constant delay at the cost of it being longer? (Not promising anything, just asking).
And, don't forget it's Programmers Day today - the 256th day of the year! :-)
/Henrik.
Bookmarks