Continue to Site

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.

pic 16f877 ans LCD 16*2 programming C mikroc liquide level

Status
Not open for further replies.

zapollon

Newbie level 3
Joined
May 31, 2014
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
35
hello ,
I am new to this forum and I do not speak much anglai, here is my setup is a pic 16f877 connected a variable resistor 2 and 2 and a bargraph LCD 16 * 2 to display the liquid level,
Forum2.jpg
this is my schema
and my program code :

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
unsigned int niv_bac1;
unsigned int niv_bac2;
unsigned char i,j;
unsigned int  niveaux[8] = {127, 254, 382, 510, 638, 776, 894, 1022};
 
unsigned char VnDuNiveau(unsigned int val) {
   unsigned char i = 0;
   while (i < sizeof(niveaux)) {
      if (val < niveaux[i])
         return i;
      else i++;
   }
   }
 
   void main() {
   // Configuration des pins 2 et 3 en analogique
 
  TRISA  = 0xFF;  // programmtion du PORTA en entrée
  TRISB  = 0;  // programmtion du PORTB en sortie
  TRISC  = 0;  // programmtion du PORTC en sortie
  TRISD  = 0;  // programmtion du PORTD en sortie
  OPTION_REG.NOT_RBPU = 0;
 
  do {
  adcon0=0x80;
  niv_bac1= Adc_Read(0); // lecture du niveau de fluide du bac1
  //portB=niv_bac1>>2;  //Affichage en binaire du niveau de fluide
  j= VnDuNiveau(niv_bac1);
 
   switch ( j ) {
   case 0:
        // Code
        portB = 0x01;
     break;
 
   case 1:
        // Code
        portB = 0x03;
        break;
   case 2:
        // Code
        portB = 0x07;
   break;
 
   case 3:
        // Code
        portB = 0x0F;
   break;
   case 4:
    // Code
    portB = 0x1F;
   break;
   case 5:
    // Code
    portB = 0x3F;
   break;
   case 6:
    // Code
    portB = 0x7F;
   break;
   case 7:
    // Code
    portB = 0xFF;
   break;
 
        }
 
 
 
   adcon0=0x88;                    //du bac1 sur le portB
   niv_bac2= Adc_Read(1);   // lecture du niveau de fluide du bac2
 
 
 
   //PORTC = niv_bac2>>2;  //Affichage en binaire du niveau de fluide
                           //du bac2 sur le portC
    j= VnDuNiveau(niv_bac2);
 
   switch ( j ) {
   case 0:
        // Code
        portC = 0x01;
     break;
 
   case 1:
        // Code
        portC = 0x03;
        break;
   case 2:
        // Code
        portC = 0x07;
   break;
 
   case 3:
        // Code
        portC = 0x0F;
   break;
   case 4:
    // Code
    portC = 0x1F;
   break;
   case 5:
    // Code
    portC = 0x3F;
   break;
   case 6:
    // Code
    portC = 0x7F;
   break;
   case 7:
    // Code
    portC = 0xFF;
   break;
 
        }
               } while(1);
 }



So i need the program code Mikro C for pic to lcd 16*2 please , i need it so help me please
 
Last edited by a moderator:

hello,


the following code , can be included in your main loop, to display value on LCD
this example show ADC0 on line#2.. so to adapt to your case..
ADC_Read(0) gives the average of 32 elementary meaurements.. you can adapt to 16 or use only Raw measure..
I use a different function to display floating point as the MikroC floatToStr because result width is variable ..

Code:
char CRam1[32]; // for float conversion
char CRam0[6];   // for int conversion
float F1;
unsigned int M1;  // raw  ADC0 measure


void ADC_Init(void);
unsigned int ADC_Read(unsigned char channel)   ;
void Volt_Display(float Fx,int l,int c);


 unsigned char *Float2Ascii (float x, unsigned char *str,char precision)
{
 /* converts a floating point number to an ascii string */
 /* x is stored into str, which should be at least 30 chars long */
 unsigned char *adpt;
 int ie, i, k, ndig;
 double y;
 adpt=str;
 ndig = ( precision<=0) ? 7 : (precision > 22 ? 23 : precision+1);
 ie = 0;
 /* if x negative, write minus and reverse */
 if ( x < 0)
 {
   *str++ = '-';
   x = -x;
 }
 /* put x in range 1 <= x < 10 */
 if (x > 0.0) while (x < 1.0)
 {
   x *= 10.0;                // a la place de =*
   ie--;
 }
 while (x >= 10.0)
 {
   x = x/10.0;
   ie++;
 }
 // in f format, number of digits is related to size
 ndig += ie;                                // a la place de =+
 //round. x is between 1 and 10 and ndig will be printed to
 // right of decimal point so rounding is ...
 for (y = i = 1; i < ndig; i++)
 y = y/10.;
 x += y/2.;
 if (x >= 10.0) {x = 1.0; ie++;}
 if (ie<0)
 {
   *str++ = '0'; *str++ = '.';
   if (ndig < 0) ie = ie-ndig;
   for (i = -1; i > ie; i--)  *str++ = '0';
 }
 for (i=0; i < ndig; i++)
 {
   k = x;
   *str++ = k + '0';
   if (i ==  ie ) *str++ = '.';
   x -= (y=k);
   x *= 10.0;
  }
 *str = '\0';
return (adpt);
}

 // LCD 4x20 
void Volt_Display(float Fx,int l,int c)
 {
 int i,j,k;
 CRam1[0]=0;
 Float2Ascii(Fx,CRam1,l)  ;
 /*
  if (l==1) Lcd_Cmd(0x80+c);
  if (l==2) Lcd_Cmd(0xC0+c);
   if (l==3) Lcd_Cmd(0x94+c);
     if (l==4) Lcd_Cmd(0xD4+c);
*/
 j=strlen(CRam1);
  // cadrage fin du resultat à la 14em position du LCD
 k=14-(j+c);  // commence donc  à la position
 for (i=0;i<c;i++) Lcd_Cmd( _LCD_MOVE_CURSOR_RIGHT );
 for (i=0;i<k;i++)
 {
  Lcd_Chr_CP(' ');  // remplissage par des blancs
  //Lcd_cmd(_LCD_MOVE_CURSOR_RIGHT);//ou deplacement du cursor
 }
 // terminaison de la ligne
  Lcd_Out_CP(CRam1);  // floating value itself
  Lcd_Chr_CP(' ');
  Lcd_Chr_CP('V');
}


void main()
{

... etc .....

   ADCON0 = 0x81;
   M1= ADC_Read(0);      // result is the average on 32 meaures
   F1=(float)M1*0.0048828125;   // coeff= 5.00V/1024

   Lcd_Cmd(_LCD_SECOND_ROW );
   WordToStr(M1,CRam0); // attention le buffer ne doit pas etre trop long !!   sinon deborde du LCD...
   Lcd_Out_CP(CRam0);  
   Lcd_Cmd(_LCD_SECOND_ROW ); // affichage cadre à droite , avec 'V' en 16em position
   Volt_Display(F1,3,8);      // 3 digits apres la virgule  en 8em position
..........
 

this program is for lcd ?
 

this program is for lcd ?

Yes, just add LCD mickroC library
and
Code:
// in declaration part
// check it with your Schematic

// Lcd OCULAR OM16241   2 lignes de 16 cars pinout settings
sbit LCD_RS at RB1_bit;
sbit LCD_RW at RB2_bit;
sbit LCD_EN at RB0_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D5 at RB5_bi²t;
sbit LCD_D4 at RB4_bit;


// Pin direction
sbit LCD_RS_Direction at TRISB1_bit;
sbit LCD_RW_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB0_bit;
sbit LCD_D7_Direction at TRISB7_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB4_bit;


// and in the main programm

 Lcd_Init();  // only once time !

....
// in your main loop

........
ADCON0 = 0x81;
   M1= ADC_Read(0);      // result is the average on 32 meaures
   F1=(float)M1*0.0048828125;   // coeff= 5.00V/1024

   Lcd_Cmd(_LCD_SECOND_ROW );
   WordToStr(M1,CRam0); // attention le buffer ne doit pas etre trop long !!   sinon deborde du LCD...
   Lcd_Out_CP(CRam0);  
   Lcd_Cmd(_LCD_SECOND_ROW ); // affichage cadre à droite , avec 'V' en 16em position
   Volt_Display(F1,3,8);      // 3 digits apres la virgule  en 8em position
 ......
 

I wrote another code but on Barregraph currently the first 7 LED that turns on when it is normally 8 premieres, and the LCD displays its bizzare figure
forum.jpg
and the new code :
Code:
float niv_bac1;
float niv_bac2;
unsigned char i,j;
float  niveaux[8] = {127, 255, 383, 511, 639, 777, 895, 1023};
sbit LCD_RS at RD1_bit ;
sbit LCD_EN at RD0_bit ;
sbit LCD_D4 at RD4_bit ;
sbit LCD_D5 at RD5_bit ;
sbit LCD_D6 at RD6_bit ;
sbit LCD_D7 at RD7_bit ;

sbit LCD_RS_Direction at TRISD1_bit ;
sbit LCD_EN_Direction at TRISD0_bit ;
sbit LCD_D4_Direction at TRISD4_bit ;
sbit LCD_D5_Direction at TRISD5_bit ;
sbit LCD_D6_Direction at TRISD6_bit ;
sbit LCD_D7_Direction at TRISD7_bit ;



char niveau1[4];
char niveau2[4];
unsigned char VnDuNiveau(float  val) {
   unsigned char i = 0;
   while (i <= sizeof(niveaux)) {
      if (val <= niveaux[i])
         return i;
      else i++;
   }
   }




  void initialisation(){
TRISA  = 0xFF;  // programmtion du PORTA en entrée
TRISB  = 0;  // programmtion du PORTB en sortie
TRISC  = 0;  // programmtion du PORTC en sortie
TRISD  = 0;  // programmtion du PORTD en sortie
OPTION_REG.NOT_RBPU = 0;
lcd_init() ;
lcd_cmd(_lcd_clear) ;
lcd_cmd(_lcd_cursor_off) ;
lcd_out(1,1,"Bac1: ") ;
lcd_out(2,1,"Bac2: ") ;
adc_init() ;
portd=0X00 ;

}

   void main() {
    initialisation() ;
    OPTION_REG.NOT_RBPU = 0;

  do {
  adcon0=0x80;
  niv_bac1= Adc_Read(0); // lecture du niveau de fluide du bac1

  j= VnDuNiveau(niv_bac1);

   switch ( j ) {
   case 0:
        // Code
        portB = 0x00;
     break;

   case 1:
        // Code
        portB = 0x01;
        break;
   case 2:
        // Code
        portB = 0x03;
   break;

   case 3:
        // Code
        portB = 0x07;
   break;
   case 4:
    // Code
    portB = 0x0F;
   break;
   case 5:
    // Code
    portB = 0x1F;
   break;
   case 6:
    // Code
    portB = 0x3F;
   break;
   case 7:
    // Code
    portB = 0x7F;
   break;
  case 8:
    // Code
    portB = 0xFF;
   break;
        }

  floattostr(niv_bac1,niveau1) ;
  lcd_out(1,6,niveau1) ;

   adcon0=0x88;
   niv_bac2= Adc_Read(1);   // lecture du niveau de fluide du bac2

   j= VnDuNiveau(niv_bac2);

   switch ( j ) {
   case 0:
        // Code
        portC = 0x00;
     break;

   case 1:
        // Code
        portC = 0x01;
        break;
   case 2:
        // Code
        portC = 0x03;
   break;

   case 3:
        // Code
        portC = 0x07;
   break;
   case 4:
    // Code
    portC = 0x0F;
   break;
   case 5:
    // Code
    portC = 0x1F;
   break;
   case 6:
    // Code
    portC = 0x3F;
   break;
   case 7:
    // Code
    portC = 0x7F;
   break;
   case 8:
    // Code
    portC = 0xFF;
   break;

  }


  floattostr(niv_Bac2,niveau2) ;
  lcd_out(2,6,niveau2) ;


 } while(1);
 }
so please help me in this small problem
 

Code:
char niveau1[4];
char niveau2[4];

size of table is too short : 4 chars !... must be 15 chars wide .. see explanation in mikroC help
a float is made by 4 bytes, but ascci representation is many chars .. 1023.999999999
and you have overwriting of table .. so program is affected.

Check also if you get IRP bit warning..
in this case .. bad behavior of the programm can occurs..

I am working now on a 16F877 IrdaBoard and facing on this kind of problem due to a lack of RAM memory
with 16F877...and some bug in mikroC : oblige to manage RAM MANUALLY with an IRP Bit value to change of Bank.
A pity for a C complier.. even it is normal for ASM compiler.
so i strongly recommand to use 18F serie ..my preffered is 18F46K22 with > 3500 bytes of RAM
and a bit disappointed after buying Mikroc licence..


if also prefere to use "Float2Ascii " instead of "FloatToStr" , but it's up to you...
 
Last edited:

you can wrote me the code ?
thanks
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top