Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

proplem with digits

Status
Not open for further replies.

lakis

New Member
Hi guys. After long time I managed to count the period and the high time of a rectangular waveform .
My problem now is that although the period and the high Time are display ok in the screen when I try to calculate the duty cycle (dutycycle = (Thigh *100)/period (the 100 is to get a 2 digit integer) ) I have the following .

If high time is until 330 -350μs I get the first two digits as I suppose to .
If the high time is greater than 350 μs I get a screen full of numbers and unknown symbols.

this is my code
Code:
#include<p18f452.h>
#include<xlcd.h>// Include function definitions for the External LCD Library library
#include<delays.h>// Include function definitions for built in Delay routines
#include <stdio.h>
#include <timers.h>
#include <capture.h>
#include <stdlib.h> /**********tin aferesa epeidi ekane problima sto itoa. Kanonika auti einai bibliothiki poy exei to idoa mesa tin ebala otan ebla ton ADC kodika Den ipirxe prin. Douleue sosta xvris ayti*/

#include <math.h>

#pragma config LVP=OFF
#pragma config OSC=HS
#pragma config WDT=OFF// Use internal Oscillator, Watchdog off, LVP off
#pragma config DEBUG=ON

 






void DelaySTRING(void);
void main(void)
{




	int i,z,t,x;
 unsigned    int period,per1; // unsigned
unsigned int total;
 unsigned int thigh;
unsigned int th;
float dutycycle;
int dekadikos;
int c2=22;
 float y,c1;

char str[5];

	unsigned char newlineadd=0x40; // Line 2 addresses are 40h to 4Fh
    
	ADCON1=0X7F;//Make all ports Digital	

	
	while( BusyXLCD());// Wait till LCD finishes executing command
TRISCbits.TRISC2 = 1; /* configure CCP1 pin for input */
T3CON = 0x81; /* use Timer1 as the time base for CCP1 capture */
PIE1bits.CCP1IE = 0; /* disable CCP1 capture interrupt */
PIR1bits.CCP1IF = 0; /* clear the CCP1IF flag */
T1CON = 0x81; /* enable 16-bit Timer1, prescaler set to 1 */
CCP1CON = 0x05; /* capture on every rising edge */
while (!(PIR1bits.CCP1IF)); /* wait for 1st rising edge */
PIR1bits.CCP1IF = 0;
per1 = CCPR1; /* save the first edge (CCPR1 is accessed as a 16-bit value) */
PIE1bits.CCP1IE = 0;
CCP1CON = 0x04;
while (!(PIR1bits.CCP1IF)); /* wait for the 2nd rising edge */
PIR1bits.CCP1IF = 0;
thigh=CCPR1;
PIE1bits.CCP1IE = 0;
CCP1CON = 0x05;
while (!(PIR1bits.CCP1IF));
CCP1CON = 0x00; //disable CCP1 capture */
period = CCPR1 -per1 ;
thigh=thigh-per1;
total=period*0.2;  // o,2   convert to  us  from  clock  cyckle
 th=thigh*0.2;
z=th*100;
t=total;
dutycycle=z/t;
dekadikos=dutycycle ;



ultoa(total,str);// convert integer in to string
	
putsXLCD(str);

	
	
ultoa(th,str);// convert integer in to string

    	putsXLCD(str);

DelaySTRING();


ultoa( dutycycle,str);  // convert integer in to string

	putsXLCD(str);
DelaySTRING();



    while(1);// Wait here
}





void DelayFor18TCY(void)
{
Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();

}


/****************************************************************/
//  DelayPORXLCD  =15 ms.
/****************************************************************/

void DelayPORXLCD(void)
{
Delay1KTCYx(75);
}

/****************************************************************/
//  DelayXLCD  =5 ms.
/****************************************************************/

void DelayXLCD(void)
{
Delay1KTCYx(25);
}

/****************************************************************/
//  DelayString  =250 ms.
/****************************************************************/

void DelaySTRING(void)
{
Delay10KTCYx(456);//450//1562
}

i haven't add most of the lcd functions so the code is more readable .

Can anyone help me fix that problem

thank you.
 
You haven't added any code functions! :eek: Please post the actual math code, and the variable initialisation.

Without that info we can only guess, so here's a guess;
doing (Thigh * 100) is probably overflowing the variable size once Thigh gets large enough. You need to switch to a 16bit or 32bit variable to do the *100 math. Once finished you can copy the result back to your normal variable for display as duty %.
 
thank you for answer
i forgot mention that i 'm working with c18 lite
this is the full code
Code:
#include<p18f452.h>
#include<xlcd.h>// Include function definitions for the External LCD Library library
#include<delays.h>// Include function definitions for built in Delay routines
#include <stdio.h>
#include <timers.h>
#include <capture.h>
#include <stdlib.h> /**********tin aferesa epeidi ekane problima sto itoa. Kanonika auti einai bibliothiki poy exei to idoa mesa tin ebala otan ebla ton ADC kodika Den ipirxe prin. Douleue sosta xvris ayti*/

#include <math.h>

#pragma config LVP=OFF
#pragma config OSC=HS
#pragma config WDT=OFF// Use internal Oscillator, Watchdog off, LVP off
#pragma config DEBUG=ON

 






void DelaySTRING(void);
void main(void)
{




	int i,z,t,x;
 unsigned    int period,per1; // unsigned
unsigned int total;
 unsigned int thigh;
unsigned int th;
float dutycycle;
int dekadikos;
int c2=22;
 float y,c1;

   overlay   char data[]="total time ";
	static const char data1[]="in us";
     overlay  char start[]="thigh in us ";
unsigned char  duty[]="duty cycle in % ";
char str[5];

	unsigned char newlineadd=0x40; // Line 2 addresses are 40h to 4Fh
    
	ADCON1=0X7F;//Make all ports Digital	

	OpenXLCD( EIGHT_BIT & LINES_5X7 );// Use 8 bit Data, 5x7 pixel Matrix per character
	while( BusyXLCD());// Wait till LCD finishes executing command
	WriteCmdXLCD( CURSOR_ON);// Turn cursor ON
    WriteCmdXLCD(0x83); // Force curson to the begining of 1st line
	while( BusyXLCD() );// Wait till LCD finishes executing command
   WriteCmdXLCD( SHIFT_DISP_LEFT );//Shift Cursor Display Left
	while( BusyXLCD());// Wait till LCD finishes executing command
     
	putsXLCD(data);// Write the String data to the LCD
DelaySTRING();
WriteCmdXLCD(0b00000001);
	while( BusyXLCD() );
   WriteCmdXLCD( 0xC0);// Force curson to the begining of 2nd line
  
	while( BusyXLCD() );

    putsXLCD(data1);// Write the String data to the LCD
   while( BusyXLCD());
  DelaySTRING();
WriteCmdXLCD(0b00000001);
	while( BusyXLCD());// Wait till LCD finishes executing command
TRISCbits.TRISC2 = 1; /* configure CCP1 pin for input */
T3CON = 0x81; /* use Timer1 as the time base for CCP1 capture */
PIE1bits.CCP1IE = 0; /* disable CCP1 capture interrupt */
PIR1bits.CCP1IF = 0; /* clear the CCP1IF flag */
T1CON = 0x81; /* enable 16-bit Timer1, prescaler set to 1 */
CCP1CON = 0x05; /* capture on every rising edge */
while (!(PIR1bits.CCP1IF)); /* wait for 1st rising edge */
PIR1bits.CCP1IF = 0;
per1 = CCPR1; /* save the first edge (CCPR1 is accessed as a 16-bit value) */
PIE1bits.CCP1IE = 0;
CCP1CON = 0x04;
while (!(PIR1bits.CCP1IF)); /* wait for the 2nd rising edge */
PIR1bits.CCP1IF = 0;
thigh=CCPR1;
PIE1bits.CCP1IE = 0;
CCP1CON = 0x05;
while (!(PIR1bits.CCP1IF));
CCP1CON = 0x00; //disable CCP1 capture */
period = CCPR1 -per1 ;
thigh=thigh-per1;
total=period*0.2;
th=thigh*0.2;
z=th*100;
t=total;
dutycycle=z/t;
dekadikos=dutycycle ;


while( BusyXLCD() );


WriteCmdXLCD( 0xC5);//
while( BusyXLCD() );

ultoa(total,str);// convert integer in to string
SetDDRamAddr( newlineadd );
	while( BusyXLCD() );	
putsXLCD(str);
DelaySTRING();
DelaySTRING();
	while( BusyXLCD() );
DelaySTRING();
WriteCmdXLCD(0b00000001);
	while( BusyXLCD() );
 WriteCmdXLCD(0x80); // Force curson to the begining of 1st line
	while( BusyXLCD() );// Wait till LCD finishes executing command
     putsXLCD(start);	
	while( BusyXLCD() );
 WriteCmdXLCD(0xC4); // Force curson to the begining of 1st line
	while( BusyXLCD() );// Wait till LCD finishes executing command
ultoa(th,str);// convert integer in to string
SetDDRamAddr( newlineadd );
	while( BusyXLCD() );
    	putsXLCD(str);
DelaySTRING();
	while( BusyXLCD() );
DelaySTRING();
WriteCmdXLCD(0b00000001);
while( BusyXLCD() );
 WriteCmdXLCD(0x80);
putsXLCD(duty);
DelaySTRING();
	while( BusyXLCD() );
 WriteCmdXLCD(0xC2); // Force curson to the begining of 1st line
	while( BusyXLCD() );// Wait till LCD finishes executing command
ultoa(dekadikos,str);// convert integer in to string
//SetDDRamAddr( newlineadd );
	while( BusyXLCD() );
	putsXLCD(str);
DelaySTRING();
while( BusyXLCD() );
x=dekadikos;
c1=c2*x;
c1=c1/10;


WriteCmdXLCD(0xC8); // Force curson to the begining of 1st line
	while( BusyXLCD() );// Wait till LCD finishes executing command
ultoa(c1,str);// convert integer in to string
//SetDDRamAddr( newlineadd );
	while( BusyXLCD() );
	putsXLCD(str);

    while(1);// Wait here
}





void DelayFor18TCY(void)
{
Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();

}


/****************************************************************/
//  DelayPORXLCD  =15 ms.
/****************************************************************/

void DelayPORXLCD(void)
{
Delay1KTCYx(75);
}

/****************************************************************/
//  DelayXLCD  =5 ms.
/****************************************************************/

void DelayXLCD(void)
{
Delay1KTCYx(25);
}

/****************************************************************/
//  DelayString  =250 ms.
/****************************************************************/

void DelaySTRING(void)
{
Delay10KTCYx(456);//450//1562
}

How to i switch it to 16 bit?
 
Sorry I must aplologise! I re-installed by web browser and now it seems broken, it is only showing the top 16 lines of the CODE PANEL, so I can't see any of your code below that! To me it looked like you only posted the top few lines. :(

The best I can give you is a general technique.

If you multiply something by 100, you must do it within a variable that is large enough to hold the result.

You said you are using;
dutycycle = (Thigh *100)/period;

To be safe, you can force all the math to be done inside a 32bit variable;
unsigned long math32; // this is the variable you will use

math32 = Thigh; // after this point all the math is done inside the 32bit variable!
dutycycle = (math32 *100)/period; // your same calc, but now is safe to 32bits (largest number about 4 billion)
 
Status
Not open for further replies.
Back
Top