Author Topic: making a frequency meter with 7 segment dynamic display and pic18f4550  (Read 741 times)

0 Members and 1 Guest are viewing this topic.

Offline khatusTopic starter

  • Regular Contributor
  • *
  • Posts: 146
  • Country: gl
Code: [Select]
#define f_timer 2000000

const 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[U];
PORTA.F0=1;
delay_ms(10);
PORTA=0;
PORTB = DIGITOS[D];
PORTA.F1=1;
delay_ms(10);
PORTA=0;
PORTB = DIGITOS[C];
PORTA.F2=1;
delay_ms(10);
PORTA=0;
PORTB = DIGITOS[UM];
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
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
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?

Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14210
  • Country: de
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. 
 

Offline ggchab

  • Frequent Contributor
  • **
  • Posts: 276
  • Country: be
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.
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2550
  • Country: us
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 X

  • Add #define _XTAL_FREQ 8000000L  in order for __delay_ms()  to work.

  • Select "internal osc" in OSCCON = 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 second while(1)  statement.

  • Add an interrupt function.
Edit-  Your main loop doesn't look like it is using interrupts.  So, DO NOT enable them!

Code: [Select]
// CONFIGURATION BITS
// TODO:  Add config bits

#include <xc.h>

#define _XTAL_FREQ 8000000L

#define f_timer 2000000

const 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[U];
   LATAbits.LA0 = 1;          // Strobe A0
   __delay_ms(10);
   LATAbits.LA0 = 0;

   PORTB = DIGITOS[D];
   LATAbits.LA1 = 1;          // Strobe A1 
   __delay_ms(10);
   LATAbits.LA1 = 0;

   PORTB = DIGITOS[C];
   LATAbits.LA2 = 1;          // Strobe A2
   __delay_ms(10);
   LATAbits.LA2 = 0;

   PORTB = DIGITOS[UM];
   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 bits
   TRISB = 0b00000000;     // PortB direction bits
   TRISA = 0b00000000;     // PortA direction bits
   
   VerDisplay( Frequency );      // Initialize the display

   // Setup CCP1 configuration
   CCP1CON = 0x05;
   CCPR1 = 0x00;
   // Setup Timer1 configuration
   PIR1.TMR1IF = 0;
   T1CON = 0x80;
   TMR1H = 0;
   TMR1L = 0;
   T1CON.TMR1ON = 1;
   // Enable CCP1 interrupt
   PIR1.CCP1IF = 0;
//   PIE1.CCP1IE = 1;

   // Main Loop
   while( 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 interrupts
   if (PIE1bits.CCP1IE && PIR2bits.CCP1IF) {
      PIR1bits.CCP1IF = 0;    // clear CCP1 Interrupt Flag

      // TODO:  Process interrupt

   }
}


« Last Edit: June 23, 2019, 08:50:25 pm by MarkF »
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2550
  • Country: us
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.

   
« Last Edit: June 23, 2019, 04:02:50 pm by MarkF »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf