Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

PIC16F877A programming problem(IntToStr)

Status
Not open for further replies.

nadre25

Member level 3
Joined
May 15, 2009
Messages
56
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,780
Hi, i have a problem in displaying to our LCD. I'm trying to display 2 values to our lcd while using the given algorithm.

The code below is working. But when i added the comments with the arrows especially the

IntToStr(ref,text3)
LCD_Custom_Out(2,10,text3)

the program is not working.

I tried replacing the

IntToStr(sp,text)
LCD_Custom_Out(2,7,text)

to

IntToStr(ref,text3)
LCD_Custom_Out(2,10,text3)

and it worked.

i was wondering if there is a rule with regarding to using IntToStr, if its not possible in using it consecutively.




Here's the code:

unsigned int temp_res;
float fl_res;
unsigned int unsign_pwm;
float pwm, temptemp;
char text[7];
int x;
int low;
int ref;
int high;
int sp;
char text2[7];
char text3[7];
char text4[7];
unsigned int pwmplus;

//void temp(){
//
//Lcd_Custom_Out(2,6,"text4");
//}
//
//void speed(){
//Lcd_Custom_Out(2,6,"speed");
//}


void main(){
PORTC=0;
TRISC=0xF0;
Pwm1_Init(5000);
Pwm1_start();
Pwm2_Init(5000);
Pwm2_start();
ADCON1 = 0x82; // Configure analog inputs and Vref
TRISA = 0xFF; // PORTA is input
TRISB = 0x00; // PORTB is output for LCD
Lcd_Custom_Config(&PORTB,7,6,5,4,&PORTB,2,0,3); // Initialize LCD on PORTB
Lcd_Custom_Cmd(Lcd_CURSOR_OFF); // Turn off cursor
PORTB=0;
TRISD = 0XFF;
PORTD = 0;

Lcd_Custom_Out(1,1,"Mode-Tmp-Spd-Pow");
Lcd_Custom_Out(2,4,"A");
while(1){
// initialize
temp_res = Adc_Read(4); // Get results of AD conversion
fl_res=temp_res;
pwm=fl_res/1023*255;
unsign_pwm=pwm;

x=0;
low=0;
high=25;
sp=0;
//ref=1; (<----)
do{
if((unsign_pwm>=low)&&(unsign_pwm<high))
{
x++;
}
else
{
sp=sp+10;
low=low+25;
high=high+25;
//ref=ref+3; (<-----)
}

}while(x==0);
//IntToStr(ref,text3); (<----)
IntToStr(sp,text);

//Lcd_Custom_Out(2,10,text3); (<-----)
Lcd_Custom_Out(2,7,text);

Pwm1_Change_Duty(unsign_pwm);
Pwm2_Change_Duty(0);
Delay_ms(8);
Pwm1_Change_Duty(0);
Pwm2_Change_Duty(0);
Delay_ms(100);
Pwm1_Change_Duty(0);
Pwm2_Change_Duty(unsign_pwm);
Delay_ms(8);
Pwm1_Change_Duty(0);
Pwm2_Change_Duty(0);
Delay_ms(100);


}
} // end main


thanks.
 

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,274
Trophy points
1,413
Location
Southwest, USA
Activity points
62,510
There are several problems with both IntToStr() and FloatToStr(). IntToStr() requires an array size of 7 elements and right justifies and FloatToStr() requires an array size of 14 elements and left justifies. Not to mention several peculiar behaviors which seem to exist.

I'm not an avid user of MikroC, but have used the compiler from time to time to modify legacy code. After rounding, then shifting and truncating the resulting string from either of these two functions to get it into a displayable format for an LCD, I have found the use of sprintf(), sprintl() and sprinti() a more convenient and efficient technique. The latter two functions are stripped down version of the ANSI Standard requiring less RAM and ROM.

An example of their use for serial comm:

Code:
double ww = -1.2587538e+1;
char buffer[15];
// Function for sending string to UART
void UartWriteText(char *txt) {
    while(*txt)
    UART1_Write(*txt++);
}

// Function for sending const string to UART
void UartWriteConstText(const char *txt) {
    while(*txt)
    UART1_Write(*txt++);
}

void main(){
   UART1_Init(4800); // Initialize UART module at 4800 bps
   Delay_ms(10);

   UartWriteConstText("Floating point number representation"); //Write message on UART

   sprintf(buffer, "%12e", ww); // Format ww and store it to buffer
   UartWriteConstText("\r\ne format:"); // Write message on UART
   UartWriteText(buffer); // Write buffer on UART

   sprintf(buffer, "%12f", ww); // Format ww and store it to buffer
   UartWriteConstText("\r\nf format:"); // Write message on UART
   UartWriteText(buffer); // Write buffer on UART

   sprintf(buffer, "%12g", ww); // Format ww and store it to buffer
   UartWriteConstText("\r\ng format:"); // Write message on UART
   UartWriteText(buffer); // Write buffer on UART
}

Reference pg596 of the MikroC Compiler Manual:

mikroC PRO for PIC User Manual

Try the sprinti() function, I'll think you'll agree.

Hope the tip helps with your project.
 

nadre25

Member level 3
Joined
May 15, 2009
Messages
56
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,780
hi. i tried using sprintf but i found out the PIC16 families doesn't support such function

i tried using sprintl, but I couldn't display it using LCD_Custom_Out(1,1,buffer);

are these functions only usable with UART? or is it possible using LCD_Custom_Out?

thanks for the reply:)
 

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,274
Trophy points
1,413
Location
Southwest, USA
Activity points
62,510
Absolutely not.

I just debugged someone's mikroC program and replaced IntToStr() with sprinti(), problem solved.

Try this snippet:

Code:
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_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;
// End LCD module connections

void main()
{
 
  int seconds = 30;
  char txt[3];

  Lcd_Init();                        // Initialize LCD

  Lcd_Cmd(_LCD_CLEAR);                   // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
  
  Lcd_Out(1, 14, "sec");
  
  do
  {
    sprinti(txt, "%2d", seconds);
    Lcd_Out(1, 11, txt);
    delay_ms(1000);

  }while(seconds--);

}

You've got total control over the size of the char array it works like a charm.

You just have to understand the field format specifications and it will convert and format your integers, longs, floats, etc, into any format you need.

Just try and keep the floats down to an absolute minimum, the consume lots of RAM, ROM and CPU cycles. Try and use only the sprinti() and sprintl() functions.

Find a good book on the Standard C Library or a website that discuss the field format specifications and it will be smooth sailing from that point on.

Run this snippet, I used similar code to fix a program on a 16F877A, they fought with IntToStr() and FloatToStr() for almost a week before they gave up.

Let me know if you need any other tips.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top