Testing Capture module functionality in pic 18f4550 - Page 1
Forum section: electronics / beginners

author: khatus
author_rank: Regular Contributor
timestamp: November 23, 2019, 05:55:57 pm
content: Hello guys i am a beginner in pic microcontroller programming. i have a code for frequency measurement using pic 18f4550 microcontroller.but the problem is although the code sometimes works in real hardware but it did not simuate i proteus simulation software. This code is very important for me since I want to understand how capture module works in pic.Can any guys fix this code as well as post the simulation file in this forum so that i can download them and simulate it.Or provide some alternative code for Testing capture module functionality of pic 18f4550.Code:// some random garbage uncommented code found on forum// 20MHz external crystal with no PLL to give 20MHz system clock// a 5 kHz test square wave is provided on RC1 - link RC1 to RC2 to test operation#define f_timer 5000000 // T1 clock is Fosc/4sbit LCD_RS at LATB4_bit;sbit LCD_EN at LATB5_bit;sbit LCD_D4 at LATB0_bit;sbit LCD_D5 at LATB1_bit;sbit LCD_D6 at LATB2_bit;sbit LCD_D7 at LATB3_bit;sbit LCD_RS_Direction at TRISB4_bit;sbit LCD_EN_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB0_bit;sbit LCD_D5_Direction at TRISB1_bit;sbit LCD_D6_Direction at TRISB2_bit;sbit LCD_D7_Direction at TRISB3_bit;void main ( void ){unsigned long signal_period,data1,data2;char frequency_Hz;float Frequency;Lcd_Init();TRISC.TRISC1 = 1;OSCCON = 0b1110000;PIE1.CCP1IE = 1;PIR1.CCP1IF = 0;CCP1CON = 0x05;CCPR1 = 0x00;PIR1.TMR1IF = 0;T1CON = 0x80;T1CON.TMR1ON = 1;TRISB = 0;TRISA = 0; // all outputsLATA = 0; // all low to start withTMR1H = 0;TMR1L = 0;PWM2_Init(5000); // provide test frequency output on RC1PWM2_Set_Duty(127); // square wavePWM2_Start();while( 1 ){while(!(PIR1.CCP1IF));PIR1.CCP1IF=0;data1 = CCPR1;while(!(PIR1.CCP1IF));PIR1.CCP1IF = 0;data2 = CCPR1;if(data1 < data2){Lcd_Cmd(_LCD_CLEAR); // clear out old informationsignal_period = data2 - data1;Frequency = ((float)f_timer / (float)signal_period);FloatToStr( Frequency,frequency_Hz );///LongWordToStrWithZeros(Frequency, frequency_Hz);Lcd_Out(1, 1, frequency_Hz); // display new frequency valueTMR1H = 0;TMR1L = 0;}Delay_ms(500); // Limit display rate to reduce flicker}}

author: Ian.M
author_rank: Super Contributor
timestamp: November 24, 2019, 02:52:05 pm
content: Don't trust Proteus! If it works on real hardware but not in the simulator that usually indicates the simulated device isn't accurate, i.e. in this case the timers and CCP peripherals don't work the same as in the real chip.The timer 1 handling is deeply suspect in your sample code. Zeroing it after a successful period measurement then waiting 500ms is asking for trouble. *IF* the timer needs zeroing it should be immediately before the wait for the first capture.Also checking if the first capture is less than the second one is dumb, and may well be the root cause of the code failing under certain circumstances. It can only be less if there's been a timer rollover between the two captures. If so, the difference will still be valid if its less than one timer rollover period and you use 16 bit unsigned maths (i.e. modulo 655336).It gets more complex if you need to extend the capture width in software using the overflow interrupt flag, as you need to handle the case of rollover very near the moment of capture, and determine which came first.