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] adc_lcd programing in c for pic16f877A: In process woks fine but in the circuit it is not

Status
Not open for further replies.

vir_paksh@yahoo.co.in

Newbie level 6
Joined
Apr 8, 2013
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,444
adc_lcd programing in c for pic16f877A:In proteus woks fine but in circuit it is not

Please help me where is the problem in the below program, In proteaus simulation it works very fine and reads as I required, but when working with circuit it is not reading the adc but displaying some other junk values from where I don't know & being on change in values, totally it is not reading while working in circuit, anybody please correct the program to read adc in working circuit

Thanks & Regards


View attachment ADC sens2.pdf




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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
#include<htc.h>
#include<string.h>
#include<stdio.h>
#include<math.h>
 
 
 // __CONFIG(FOSC_EXTRC & WDTE_OFF & PWRTE_OFF & CP_OFF & BOREN_OFF & LVP_ON & CPD_OFF & WRT_ON);
//__CONFIG(FOSC0_RC & WDTE_OFF & PWRT_ON & CP0_OFF & BOREN_ON & LVP_OFF & CPD_OFF & WRT_ON & DEBUG_ON);
__CONFIG(0X3F72);
//__CONFIG( FOSC_HS & WDTE_OFF & PWRTE_ON & CP_OFF & BOREN_ON 
//      & LVP_OFF & CPD_OFF & WRT_ON & DEBUG_OFF);
 
volatile bit  Data @ (unsigned)&PORTD*8+7;
volatile bit  RS @ (unsigned)&PORTD*8+6;         
volatile bit  EN @ (unsigned)&PORTD*8+5;
volatile bit  Clk @ (unsigned)&PORTD*8+4;
 
volatile bit GODONE @ (unsigned)&ADCON0*8+2;
 
#define FCY 4000000
#define MILLISEC (FCY/10000)
 
#define AN0 ((Ch0/1024.0))      //for i/p value = 4V
#define AN1 ((Ch1/1024.0))      //for value = 2
#define AN2  ((Ch2/1024.0))     // for o/p value = 1.2V
#define AN3 ((Ch3/1024.0))     //for value = 1.8
#define AN4 ((Ch4/1024.0))      //for i/p value = 4V
#define AN5 ((Ch5/1024.0))      //for value = 2
#define AN6 ((Ch6/1024.0))     // for o/p value = 1.2V
#define AN7 ((Ch7/1024.0))     //for value = 1.8
#define ANSEL 0
#define OFFSET 10 
 
#define SIGNAL1 PORTBbits.RB0
 
int;
 
void DelayN1mSec(unsigned int S1);
void Write_LCD_Nibble(unsigned int);
void Write_LCD_Data(unsigned int);
void Write_LCD_Cmd(unsigned int);
void Initialize_LCD(void);
void Position_LCD(unsigned int, unsigned int);
void Write_LCD_Text(char*);
//void Write_LCD_String(s*);
void Load_Msg(float v,unsigned char OutD[]);
unsigned int ADCRead(unsigned char channel);
 void SetPWMDutyCycle1(void);
 
void DelayN2mSec(unsigned int S2);
void DelayNmSec(unsigned int S3);
 
 
 
unsigned int Nibble, p, q, Mask, t;
unsigned int Ch0, Ch1, Ch2, Ch3,Ch4,Ch5,Ch6,Ch7; 
long int Outvalue,Outvalue1,Outvalue2,Outvalue3,Outvalue4,Outvalue5,Outvalue6,Outvalue7;
unsigned int temp1,temp2,DataX1,DataX2,temp3,temp4,DataX3,DataX4,temp5,temp6,DataX5,DataX6,temp7,temp8,DataX7,DataX8,Name,UPS,Freq;
        
 
 
 
 
       char Message1[] = {"Input_PP: 000.0V "};    //ADCRead(2);
       char Message2[] = {"Output_PP:000.0V "};
       char Message3[] = {"R_ph_out: 000.0A  "};
       char Message4[] = {"Y_ph_out: 000.0A  "};    
       char Message5[] = {" B_ph_out:000.0A  "};
       char Message6[] = {" Bat_Volt:000.0V  "};
       char Message7[] = {" Ba_ch_cnt:00.0A  "};
       char Message8[] = {" Tempr:     0.0C  "};
       char Message9[] = {"VIRUPAKSH9 7    "};    //ADCRead(2);
       char Message10[]= {"OnLineUPS:      "};
       char Message11[]= {" 50Hz,Sine      "};
       char Message12[]= {"SineWave:       "};
 
 void main()
 {
 
 
  TRISD = 0b00000000;  // All Outputs except GP3
//  TRISA = 0b00000000;
  PORTD = 0b00000000;
//  PORTA = 0b00000000;
  PORTB = 0b00000000;
  TRISB = 0b00000000; 
  PORTC = 0b00000000;
  TRISC = 0b00000000;
 
//   ANSEL = 0x00; // No analog i/p
  //GPIO = 0b00000000;         
//CMCON = 7; //Disable ADC
         
 
     do
       {   
           Initialize_LCD();
          TRISA = 0b10111111;
          PORTA = 0b10111111;
          TRISE = 0b00000111; 
          PORTE = 0b00000111;
           PORTD = 0;
           TRISD = 0;
           PORTB = 0;
           TRISB = 0;
           TRISC = 0;
           PORTC = 0;
           
           ADCON0 = 0xC7; 
           ADCON1 = 0x80;    //check this value
          Outvalue1 =AN0;
           DataX1 = Ch0*5;
           Outvalue2 =AN1;
           DataX2 = Ch1*1;
           Outvalue3 =AN2;
           DataX3 = Ch2*1;
           Outvalue4 =AN3;
           DataX4 = Ch3*1;
           Outvalue5 =AN4;
           DataX5 = Ch4*1;
           Outvalue6 =AN5;
           DataX6 = Ch5*1;
           Outvalue7 =AN6;
           DataX7 = Ch6*1;
           Outvalue =AN7;
           DataX8 = Ch7*1;
 
           temp1 = (unsigned int)DataX1;   // 
           temp2 = (unsigned int)DataX2;
           temp3 = (unsigned int)DataX3;   // 
           temp4 = (unsigned int)DataX4;
           temp5 = (unsigned int)DataX5;   // 
           temp6 = (unsigned int)DataX6;
           temp7 = (unsigned int)DataX7;   // 
           temp8 = (unsigned int)DataX8;
 
                  Ch0 =ADCRead(0x81); //ok
                  Ch1 =ADCRead(0x89);  //ok
                  Ch2 =ADCRead(0x91);  //ok
                  Ch3 =ADCRead(0x99);  //ok
                  Ch4 =ADCRead(0xA1);  //ok
                  Ch5 =ADCRead(0xA9);  //ok
                  Ch6 =ADCRead(0xB1);  //ok
                  Ch7 =ADCRead(0xB9); //ok
 
 
     Write_LCD_Cmd(0x01);  // Clear LCD
     DelayNmSec(3);
     Load_Msg(DataX1,Message1);
     DelayNmSec(3); 
Write_LCD_Cmd(0xC0);  // Clear LCD
     DelayNmSec(3);
     Load_Msg(DataX2,Message2);
     DelayNmSec(3); 
Write_LCD_Cmd(0x93);  // Clear LCD
     DelayNmSec(3);
     Load_Msg(DataX6,Message6);
     DelayNmSec(3); 
Write_LCD_Cmd(0xD3);  // Clear LCD
     DelayNmSec(3);
     Load_Msg(DataX7,Message7);
     DelayNmSec(300); 
Write_LCD_Cmd(0x01);  // Clear LCD
     DelayNmSec(3);
     Load_Msg(DataX3,Message3);
     DelayNmSec(3); 
Write_LCD_Cmd(0xC0);  // Clear LCD
     DelayNmSec(3);
     Load_Msg(DataX4,Message4);
     DelayNmSec(3); 
Write_LCD_Cmd(0x93);  // Clear LCD
     DelayNmSec(3);
     Load_Msg(DataX5,Message5);
     DelayNmSec(3); 
Write_LCD_Cmd(0xD3);  // Clear LCD
     DelayNmSec(3);
     Load_Msg(DataX8,Message8);
     DelayNmSec(300); 
Write_LCD_Cmd(0x01);  // Clear LCD
     DelayNmSec(3);
Load_Msg(Name,Message9);
     DelayNmSec(3); 
Write_LCD_Cmd(0xC0);  // Clear LCD
     DelayNmSec(3);
Load_Msg(UPS,Message10);
     DelayNmSec(3); 
Write_LCD_Cmd(0x93);  // Clear LCD
     DelayNmSec(3);
Load_Msg(Freq,Message11);
     DelayNmSec(300); 
}
     while(1);
    }            
            
  
 
unsigned int ADCRead(unsigned char channel)
    { 
    unsigned char l_byte, h_byte; 
    unsigned int ADR; 
    ADCON0 = channel; //Change channel 
    //delay_us(50);
    DelayNmSec(25);    //Acquisition Delay 
    GODONE = 1;       //Set GO_DONE bit to start conversion 
    while(GODONE == 1); //Wait for bit to be cleared 
    //If bit is cleared, this means conversion is over 
    l_byte = ADRESL; 
    h_byte = ADRESH; 
    ADR = (h_byte<<8)|l_byte; 
    return ADR; 
    }
 
void DelayN1mSec(unsigned int S1)
     {
         unsigned long int j1;
         while(S1--)
         for(j1=0;j1<MILLISEC;j1++);
     }
void DelayN2mSec(unsigned int S2)
     {
         unsigned long int j2;
         while(S2--)
         for(j2=0;j2<MILLISEC;j2++);
     }
void DelayNmSec(unsigned int S3)
     {
         
         unsigned long int j3;
         while(S3--)
         for(j3=0;j3<MILLISEC;j3++);
     }
 
 
void Write_LCD_Nibble(unsigned int N)
{
     
     unsigned int Flag;
                     // ****** Write RS *********
      EN = 0;   
      Clk = 0;
      Clk = 1;      
      Clk = 0;
               // ****** End RS Write
 
 // Shift in 8 bits
  for (t=0; t<8; t++)
  {
     switch(t)
  {
     case 0 : Mask=8;break;
     case 1 : Mask=128;break;
     case 2 : Mask=64;break;
     case 3 : Mask=32;break;
     case 4 : Mask=16;break;
     case 5 : Mask=4;break;
     case 6 : Mask=2;break;
     case 7 : Mask=1;break;
  } 
    
     Flag = N & Mask;
     if(Flag==0)
     {
        Data = 0;
     }  
     else 
     {
        Data = 1;
     } 
     Clk = 1;
     Clk = 0;   
  }
               
  //Data = 0;       
    EN = 1; 
    EN = 0;
}
 
// ******* Write Nibble Ends
 
 void Write_LCD_Data(unsigned int D)
 {
   RS = 1; // It is Data, not command
   Nibble = D;
   Write_LCD_Nibble(Nibble);
  
 }
 
void Write_LCD_Cmd(unsigned int C)
 {
   RS = 0; // It is command, not data
   Nibble = C;
   Write_LCD_Nibble(Nibble);
 }
 
void Initialize_LCD()
{
   
   Write_LCD_Cmd(0x30); // Wake-Up Sequence
   DelayNmSec(2);
   Write_LCD_Cmd(0x30);
   DelayNmSec(2);        
   Write_LCD_Cmd(0x30);
   DelayNmSec(2);
   Write_LCD_Cmd(0x0F);
   DelayNmSec(2);
   Write_LCD_Cmd(0x38); // 8-bits, 2 lines, 5x7 font
   DelayNmSec(2);
   Write_LCD_Cmd(0x0C); // Display ON, No cursors
   DelayNmSec(2);
   Write_LCD_Cmd(0x06); // Entry mode- Auto-increment, No Display shifting
   DelayNmSec(2);
   Write_LCD_Cmd(0x01);
   DelayNmSec(2);
}
 
void Position_LCD(unsigned int x, unsigned int y)
{
  unsigned int temp;
  temp = 127 + y;
  if (x == 2) { temp = temp + 64; }
  Write_LCD_Cmd(temp);
}
 
void Write_LCD_Text( char *StrData)
{
  unsigned int temp;
  q = strlen(StrData);
  for (p = 0; p<q; p++)
  {
    temp = StrData[p];
    Write_LCD_Data(temp);
  }
} 
void Load_Msg(float v,unsigned char OutD[])
 
{
    v *= 10.0;
    unsigned int k1 = (int)v;
    unsigned char c;
 
    c = k1/1000;
    if(c > 0)
    k1 = k1 - c*1000;
    OutD[OFFSET] = (c + 0x30);
 
    c = k1/100;
    if(c > 0)
    k1 = k1 - c*100;
    OutD[OFFSET+1] = (c + 0x30);
 
    c = k1/10;
    if(c > 0)
    k1 = k1 - c*10;
    OutD[OFFSET+2] = (c + 0x30);
    OutD[OFFSET+4] = (char)(k1 + 0x30);
    Write_LCD_Text(OutD);
 
}

 
Last edited by a moderator:

vir_paksh@yahoo.co.in

Newbie level 6
Joined
Apr 8, 2013
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,444
Re: adc_lcd programing in c for pic16f877A:In proteus woks fine but in circuit it is

Can you correct my program
 

milan.rajik

Banned
Joined
Apr 1, 2013
Messages
2,528
Helped
540
Reputation
1,078
Reaction score
523
Trophy points
1,393
Activity points
0
Re: adc_lcd programing in c for pic16f877A:In proteus woks fine but in circuit it is

You get junk on LCD because you have a lot of strings stored in RAM and memory bank switching is a problem in PIC16F devices and you have to manualkly switch the banks in the code. My advice is you use a PIC18F device or you could place all the constant strings in ROM and bring the string from ROM to RAM when needed for LCD printing.

- - - Updated - - -

Try this method.

https://www.mikroe.com/forum/viewtopic.php?f=13&t=23669&p=119155&hilit=CopyConst2Ram#p119155
 

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
Re: adc_lcd programing in c for pic16f877A:In proteus woks fine but in circuit it is

You get junk on LCD because you have a lot of strings stored in RAM and memory bank switching is a problem in PIC16F devices and you have to manualkly switch the banks in the code.

I'm not sure to what you are referring. The compiler typically takes care of the required bank switching, bank switching becomes an issue if assembly language is used.

@vir_paksh@yahoo.co.in

The primary problem appears to be that your program exceeds the PIC16F877A available RAM. In fact, if you attempt to compile your code in the XC8 compiler, an error message is generated, clearly indicating the available RAM has been exceed. The PIC16F877A only has 368 bytes of data RAM available and the following message strings consume almost 60% of it:

Code:
       char Message1[] = {"Input_PP: 000.0V "};    //ADCRead(2);
       char Message2[] = {"Output_PP:000.0V "};
       char Message3[] = {"R_ph_out: 000.0A  "};
       char Message4[] = {"Y_ph_out: 000.0A  "};    
       char Message5[] = {" B_ph_out:000.0A  "};
       char Message6[] = {" Bat_Volt:000.0V  "};
       char Message7[] = {" Ba_ch_cnt:00.0A  "};
       char Message8[] = {" Tempr:     0.0C  "};
       char Message9[] = {"VIRUPAKSH9 7    "};    //ADCRead(2);
       char Message10[]= {"OnLineUPS:      "};
       char Message11[]= {" 50Hz,Sine      "};
       char Message12[]= {"SineWave:       "};

One possible option is to declare these as constant, which then loads them into ROM (Flash) rather than RAM:

Code:
       [COLOR="#FF0000"]const[/COLOR] char Message1[] = {"Input_PP: 000.0V "};    //ADCRead(2);
       [COLOR="#FF0000"]const[/COLOR] char Message2[] = {"Output_PP:000.0V "};
       [COLOR="#FF0000"]const[/COLOR] char Message3[] = {"R_ph_out: 000.0A  "};
       [COLOR="#FF0000"]const[/COLOR] char Message4[] = {"Y_ph_out: 000.0A  "};
       [COLOR="#FF0000"]const[/COLOR] char Message5[] = {" B_ph_out:000.0A  "};
       [COLOR="#FF0000"]const[/COLOR] char Message6[] = {" Bat_Volt:000.0V  "};
       [COLOR="#FF0000"]const[/COLOR] char Message7[] = {" Ba_ch_cnt:00.0A  "};
       [COLOR="#FF0000"]const[/COLOR] char Message8[] = {" Tempr:     0.0C  "};
       [COLOR="#FF0000"]const[/COLOR] char Message9[] = {"VIRUPAKSH9 7    "};    //ADCRead(2);
       [COLOR="#FF0000"]const[/COLOR] char Message10[]= {"OnLineUPS:      "};
       [COLOR="#FF0000"]const[/COLOR] char Message11[]= {" 50Hz,Sine      "};
       [COLOR="#FF0000"]const[/COLOR] char Message12[]= {"SineWave:       "};

Then utilize a string buffer to copy the const char message into for modification in your Load_Msg() routine:

Code:
    void Load_Msg(float v, const char message[])
    {
        v *= 10.0;
        unsigned int k1 = (int)v;
        unsigned char c;
        [COLOR="#FF0000"]unsigned char OutD[20];[/COLOR]

        [COLOR="#FF0000"]strcpy(OutD,  message);[/COLOR]

        c = k1/1000;
        if(c > 0)
        k1 = k1 - c*1000;
        OutD[OFFSET] = (c + 0x30);

        c = k1/100;
        if(c > 0)
        k1 = k1 - c*100;
        OutD[OFFSET+1] = (c + 0x30);

        c = k1/10;
        if(c > 0)
        k1 = k1 - c*10;
        OutD[OFFSET+2] = (c + 0x30);
        OutD[OFFSET+4] = (char)(k1 + 0x30);
        Write_LCD_Text(OutD);

    }

These steps will reduce RAM consumption to less than 48%, which will leave room for additional tasks if needed. The code can be further optimized by reducing the const char message strings to the bare minimum and utilizing available string routines to augment the output message buffer to the required length. If you are using a 16x2 LCD, there is no point in utilizing messages and buffers which exceed 17 bytes in length. You also have an inordinate amount of unused variables which are declared in your code, removing those which are not utilized will also greatly reduce the consumption of available RAM.

The following is the compiler messages from the HiTech PICC Pro Compiler compiling your code with the modifications posted above, with high optimization enabled, which alleviates any storage for unused variables:

HI-TECH C Compiler for PIC10/12/16 MCUs (PRO Mode) V9.83
Copyright (C) 2011 Microchip Technology Inc.
Serial number: XXXXXX-XXXXX (PRO)
main.c:75 warning: variable "_Message12" is not used
main.c:57 warning: variable "_Outvalue" is not used
main.c:57 warning: variable "_Outvalue1" is not used
main.c:57 warning: variable "_Outvalue2" is not used
main.c:57 warning: variable "_Outvalue3" is not used
main.c:57 warning: variable "_Outvalue4" is not used
main.c:57 warning: variable "_Outvalue5" is not used
main.c:57 warning: variable "_Outvalue6" is not used
main.c:57 warning: variable "_Outvalue7" is not used
main.c:58 warning: variable "_temp1" is not used
main.c:58 warning: variable "_temp2" is not used
main.c:58 warning: variable "_temp3" is not used
main.c:58 warning: variable "_temp4" is not used
main.c:58 warning: variable "_temp5" is not used
main.c:58 warning: variable "_temp6" is not used
main.c:58 warning: variable "_temp7" is not used
main.c:58 warning: variable "_temp8" is not used
main.c:58 warning: variable "_Freq" is not used
main.c:58 warning: variable "_Name" is not used
main.c:58 warning: variable "_UPS" is not used

Memory Summary:
Program space used 844h ( 2116) of 2000h words ( 25.8%)
Data space used 61h ( 97) of 170h bytes ( 26.4%)
EEPROM space used 0h ( 0) of 100h bytes ( 0.0%)
Configuration bits used 1h ( 1) of 1h word (100.0%)
ID Location space used 0h ( 0) of 4h bytes ( 0.0%)

I have not thoroughly examined the rest of your code, therefore there maybe other issues.

BigDog
 

milan.rajik

Banned
Joined
Apr 1, 2013
Messages
2,528
Helped
540
Reputation
1,078
Reaction score
523
Trophy points
1,393
Activity points
0
Re: adc_lcd programing in c for pic16f877A:In proteus woks fine but in circuit it is

I'm not sure to what you are referring. The compiler typically takes care of the required bank switching, bank switching becomes an issue if assembly language is used.

mikroC PRO PIC compiler doesn't generate code for bank switching. I don't know about other Compilers.
 

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
Re: adc_lcd programing in c for pic16f877A:In proteus woks fine but in circuit it is

Firstly, the OP is clearly not utilizing the MikroC compiler, therefore your comment is irrelevant and off topic.

Secondly, if true that certainly is another reason, on top of many other reasons, not to use a MikroC compiler.

mikroC PRO PIC compiler doesn't generate code for bank switching. I don't know about other Compilers.

Then I suggest you concentrate your efforts on MikroC related threads and leave questions concerning other compilers to those whom are familiar with that specific compiler.


BigDog
 

vir_paksh@yahoo.co.in

Newbie level 6
Joined
Apr 8, 2013
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,444
Re: adc_lcd programing in c for pic16f877A:In proteus woks fine but in circuit it is

Thanks for your guidance I will try with your suggested correction,
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top