making a frequency  meter with 7 segment dynamic display and pic18f4550 - Page 1
Forum section: electronics / beginners

author: khatus
author_rank: Regular Contributor
timestamp: June 23, 2019, 07:44:33 am
content: Code:#define f_timer 2000000const unsigned short DIGITOS[] ={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,};void VerDisplay( int Frequency ){unsigned short U;unsigned short D;unsigned short C;unsigned short UM;UM = Frequency/1000;C = (Frequency-UM*1000)/100;D = (Frequency-UM*1000-C*100)/10;U = (Frequency-UM*1000-C*100-D*10);PORTB = DIGITOS;PORTA.F0=1;delay_ms(10);PORTA=0;PORTB = DIGITOS;PORTA.F1=1;delay_ms(10);PORTA=0;PORTB = DIGITOS;PORTA.F2=1;delay_ms(10);PORTA=0;PORTB = DIGITOS;PORTA.F3=1;delay_ms(10);PORTA=0;}void main ( void ){unsigned long signal_period,data1,data2;int Frequency=150;TRISC.TRISC2=1;OSCCON=0b1110000;PIE1.CCP1IE=1;PIR1.CCP1IF=0;CCP1CON=0x05;CCPR1=0x00;PIR1.TMR1IF=0;T1CON=0x80;TMR1H=0;TMR1L=0;T1CON.TMR1ON=1;TRISB = 0;TRISA = 0;PORTA = 0;while( 1 ){void VerDisplay( Frequency );while(!(PIR1.CCP1IF));PIR1.CCP1IF=0;data1 = CCPR1;while(!(PIR1.CCP1IF));PIR1.CCP1IF=0;data2 = CCPR1;if(data1 < data2){signal_period = data2 - data1;Frequency = ((float)f_timer / (float)signal_period);while(1){VerDisplay( Frequency );}TMR1H=0;TMR1L=0;}}}Hello guys i am a beginner in programming .I want to build a frequency measurement meter with 7 segment dynamic display and pic18f4550 mcu. The above code compiled successfully while the display showing nothing.i need help for this project

author: hamster_nz
author_rank: Super Contributor
timestamp: June 23, 2019, 07:54:37 am
content: Have you tried calling VertDisplay() by itself, without the code that collect the timing info? Does it work?If the timing code is buggy it could be stuck forever and never update the display?

author: Kleinstein
author_rank: Super Contributor
timestamp: June 23, 2019, 08:06:02 am
content: I don't know the PIC's , but it looks like the is no initialization to define the IO pins as outputs.The first test would be just display a number, maybe count.

author: ggchab
author_rank: Frequent Contributor
timestamp: June 23, 2019, 08:33:15 am
content: Calls to "vertDisplay()" function seems to depend on the frequency of CCP1IF events. As the 7 segments displays are activated during 10 ms only, this is most probably too short to be visible. The function should be called at a fixed frequency, high enough to make display visible.It's also possible the function is never called twice with the same frequency value. This will probably never give a stable reading.

author: MarkF
author_rank: Super Contributor
timestamp: June 23, 2019, 03:30:00 pm
content: I hope you have only shown part of your code. There is a lot missing.From what you have shown, I doubt your code is running.MPLAB X and XC8???More consistent format will help readability.Add configuration bits.I use: "Window -> Target Memory Views -> Configuration Bits" within MPLAB XAdd#define _XTAL_FREQ 8000000Lin order for__delay_ms()to work.Select "internal osc" inOSCCON = 0b01110010;statement.It is good practice to always include leading zeros if you use the binary definition to avoid errors.Don't enable interrupts before initialization is complete.Move interrupt enable to just before main loop (while(1);).Remove the secondwhile(1)statement.Add an interrupt function.Edit-Your main loop doesn't look like it is using interrupts. So, DO NOT enable them!Code:// CONFIGURATION BITS// TODO: Add config bits#include <xc.h>#define _XTAL_FREQ 8000000L#define f_timer 2000000const unsigned short DIGITOS[] ={ 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F };//============================================================void VerDisplay( int Frequency ){unsigned short U;unsigned short D;unsigned short C;unsigned short UM;UM = Frequency/1000;C = (Frequency-UM*1000)/100;D = (Frequency-UM*1000-C*100)/10;U = (Frequency-UM*1000-C*100-D*10);PORTB = DIGITOS;LATAbits.LA0 = 1; // Strobe A0__delay_ms(10);LATAbits.LA0 = 0;PORTB = DIGITOS;LATAbits.LA1 = 1; // Strobe A1__delay_ms(10);LATAbits.LA1 = 0;PORTB = DIGITOS;LATAbits.LA2 = 1; // Strobe A2__delay_ms(10);LATAbits.LA2 = 0;PORTB = DIGITOS;LATAbits.LA3 = 1; // Strobe A3__delay_ms(10);LATAbits.LA3 = 0;}//============================================================void main ( void ){unsigned long signal_period, data1, data2;int Frequency = 150;OSCCON = 0b01110010; // IRCF2:IRCF0 = 8 MHz, SCS1:SCS0 = Internal Osc.PORTA = 0;TRISC = 0b11111111; // PortC direction bitsTRISB = 0b00000000; // PortB direction bitsTRISA = 0b00000000; // PortA direction bitsVerDisplay( Frequency ); // Initialize the display// Setup CCP1 configurationCCP1CON = 0x05;CCPR1 = 0x00;// Setup Timer1 configurationPIR1.TMR1IF = 0;T1CON = 0x80;TMR1H = 0;TMR1L = 0;T1CON.TMR1ON = 1;// Enable CCP1 interruptPIR1.CCP1IF = 0;// PIE1.CCP1IE = 1;// Main Loopwhile( 1 ){/*void VerDisplay( Frequency ); // It looks like this should be part of initialization and be outside of the main loop// You would only want to update the display when it changed???// Plus, this should NOT be a definition. Remove the "void"// I moved this to the beginning*/while( !(PIR1.CCP1IF) );PIR1.CCP1IF = 0;data1 = CCPR1;while( !(PIR1.CCP1IF) );PIR1.CCP1IF = 0;data2 = CCPR1;if(data1 < data2){signal_period = data2 - data1;Frequency = ((float)f_timer / (float)signal_period);// REMOVED the while(1). It was an infinite loop.VerDisplay( Frequency );TMR1H = 0;TMR1L = 0;}}}//============================================================void __interrupt() isr(void){// TODO: Handle CCP1 interruptsif (PIE1bits.CCP1IE && PIR2bits.CCP1IF) {PIR1bits.CCP1IF = 0; // clear CCP1 Interrupt Flag// TODO: Process interrupt}}

author: MarkF
author_rank: Super Contributor
timestamp: June 23, 2019, 03:38:52 pm
content: When you use:PORTA.F0 = 1;PORTA.F1 = 1;PORTA.F2 = 1;do you mean (i.e. should be):LATAbits.LA0 = 1;LATAbits.LA1 = 1;LATAbits.LA2 = 1;You should read from PORTA and write to LATA.