LCD issue with PIC16F877A - Page 1
Forum section: electronics / general

author: VEGETA
author_rank: Super Contributor
timestamp: April 16, 2013, 06:53:45 pm
content: I connected the LCD as shown in the attachments.and the C program of PIC16F877A have the following:Code:// LCD module connectionssbit 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// LCD text variableschar txt1[] = "V1 = ";char txt2[] = "V2 = ";char txt3 = " ";char txt4 = " ";char txt5[] = "V RMS";The LCD gets launched and it's light is on, and there is some black things in the 1st row and I read it should be working like this.BUT, the readings never get shown!THEN, I tried the PIC without LCD and surprisingly it stopped working like before (it was working with other functions).So, what do you suggest?

author: PA0PBZ
author_rank: Super Contributor
timestamp: April 16, 2013, 07:01:02 pm
content: Quote from: VEGETA on April 16, 2013, 06:53:45 pmI don't see any code to get the text on the LCD.QuoteIf it stopped working you either did something to your program or you need a new PIC...

author: mariush
author_rank: Super Contributor
timestamp: April 16, 2013, 07:04:48 pm
content: Typically, there's a 10-20k potentiometer as a voltage divider for the contrast, if you use the same voltage for the contrast pin as for the lcd power supply, there may be too much contrast and you see nothing.Then you have to send some commands to the lcd and initialize it, then you can actually write stuff. Since you didn't add the rest of the code, I have no clue if that may be a problem.If you don't have a potentiometer, use 2 resistors

author: Skimask
author_rank: Super Contributor
timestamp: April 16, 2013, 07:12:24 pm
content: PIC16F877A datasheet, section 14.19

author: VEGETA
author_rank: Super Contributor
timestamp: April 16, 2013, 07:51:16 pm
content: here is the FULL code:Code:float v, v1, v2, v_peak;unsigned int adc1, adc2;unsigned char l_byte, h_byte;char ch1, ch2;float ADR, adc;unsigned short channel;unsigned short current_status, prev_status;/////* Definitions */////#define v_rms_min 200 // lowest alloable RMS voltage#define adc_rms_min 806 // 220v#define source_1 RD0_bit // source_1 @ pin RD0#define source_2 RD1_bit // source_2 @ pin RD1#define no_active_source RD2_bit // no_active_source indication LED @ pin RD2#define source_1_on RD3_bit // source_1_on indication LED @ pin RD3#define source_2_on RD4_bit // source_2_on indication LED @ pin RD4// LCD module connectionssbit 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// LCD text variableschar txt1[] = "V1 = ";char txt2[] = "V2 = ";char txt3 = " ";char txt4 = " ";char txt5[] = "V RMS";unsigned int ADCRead(unsigned short channel){if (channel == 0) {ADCON0 = 0x81;} // convert from channel0if (channel == 1) {ADCON0 = 0x89;} // convert from channel1delay_us(80); // Acquisition DelayGO_DONE_bit = 1; // Set GO_DONE bit to start conversionwhile (GO_DONE_bit == 1); // Wait for bit to be cleared// If bit is cleared, this means conversion is overl_byte = ADRESL;h_byte = ADRESH;ADR = (h_byte<<8)|l_byte;return ADR;}float RMS_calculator (unsigned short source) {channel = source;adc = ADCRead(channel);v_peak = (adc*396)/1023;v = v_peak/sqrt(2); // rms value for sinewavesreturn v;}unsigned short check_status() {/*if ( adc1 <= adc_rms_min ) {if ( adc2 >= adc_rms_min ){ current_status = 2; }else { current_status = 3; }}else { current_status = 1; }*/if ( v1 <= v_rms_min ) {if ( v2 <= v_rms_min ) { current_status = 3; }else { current_status = 2; }}else { current_status = 1; }return current_status;}void apply_status() {switch ( current_status ) {case 1:{source_2 = 0; // deactivate source_2delay_ms(10); // wait 5mssource_1 = 1; // activate source_1source_2_on = 0; // source_2_on LED is OFFsource_1_on = 1; // source_1_on LED is ONno_active_source = 0; // no_active_source LED is OFFbreak;}case 2:{source_1 = 0; // deactivate source_1delay_ms(10); // wait 5mssource_2 = 1; // activate source_2source_1_on = 0; // source_1_on LED is OFFsource_2_on = 1; // source_2_on LED is ONno_active_source = 0; // no_active_source LED is OFFbreak;}case 3:{source_1 = 0; // source_1 offsource_2 = 0; // source_2 offno_active_source = 1; // no_active_source LED is ONsource_1_on = 0; // source_1_on LED is OFFsource_2_on = 0; // source_2_on LED is OFFbreak;}}}void main() {CMCON = 7; //Disable comparatorPORTA = 0;TRISA = 0xff;PORTD = 0;TRISD = 0;PORTC = 0;TRISC = 0;PORTB = 0;TRISB = 0;ADCON0 = 0x81;ADCON1 = 0xC0; // all portA pins are analog // was 0xCEsource_1 = 0; // source_1 offsource_2 = 0; // source_2 offsource_1_on = 0; // source_1_on LED is OFFsource_2_on = 0; // source_2_on LED is OFFno_active_source = 1; // no_active_source LED is OFFv1 = 0;v2 = 0;adc1 = 0;adc2 = 0;current_status = 3;apply_status();/// LCD initialization ///Lcd_Init(); // Initialize LCDLcd_Cmd(_LCD_CLEAR); // Clear displayLcd_Cmd(_LCD_CURSOR_OFF); // Cursor offLcd_Out(1,1,txt1); // Write text in first rowLcd_Out(2,1,txt2); // Write text in second row// option_reg=0b00101111;while (1){prev_status = current_status;// calculate channel0 voltagev1 = RMS_calculator (0);//adc1 = ADR;// calculate channel1 voltagev2 = RMS_calculator (1);// adc2 = ADR;current_status = check_status();if ( current_status != prev_status ) { apply_status(); }delay_ms(100);// display v1floattostr(v1,ch1);txt3 = ch1;txt3 = ch1;txt3 = ch1;txt3 = ch1;txt3 = ch1;Lcd_Out(1,6,txt3);Lcd_Out(1,12,txt5);// display v2floattostr(v2,ch2);txt4 = ch2;txt4 = ch2;txt4 = ch2;txt4 = ch2;txt4 = ch2;Lcd_Out(2,6,txt4);Lcd_Out(2,12,txt5);}}the functions that stopped working are those of source1, source2 and no_source...____now, you say i need a new PIC... why?

author: VEGETA
author_rank: Super Contributor
timestamp: April 16, 2013, 08:12:12 pm
content: could it be because of RB0/INT pin? cuz it's for external interrupt.and it so, how can i disable that interrupt? if it will cause some problems I should just change the pin._________I didn't change or reprogram anything, so this bizarre new behavior is odd! and, could it be damaged? no any high power things in the connections.________I don't have any POT right now, so it's gonna be bad.

author: mariush
author_rank: Super Contributor
timestamp: April 16, 2013, 08:40:23 pm
content: I'm in the middle of an online game right now so can't reply but check your source code carefully, you have some mistakes.Make sure the pins are set properly, that they're either output or input, that the other functions those pins may have are disabled and so on, check the datasheet.... that you're reading the analog input from the proper pins... i see adcon variables are assigned different values... I'll check the code in more detail later.You probably don't need to replace the chip

author: VEGETA
author_rank: Super Contributor
timestamp: April 16, 2013, 09:07:54 pm
content: aha, so you play league of legends too.so you suggest that I change this RB0/INT pin to anything else... like portD? I think this is better cuz it's better than disabling global interrupt.about analog readings in AN0 and AN1... they performed good before putting LCD but after that the output signals didn't work.in this design there's a problem i faced, it's when AN0 and AN1 aren't connected to anything (or at least AN0)... here source1 output gets activated where it should be no_source!does 0v input analog is different than not connecting anything?these 2 channels will be connected to a rectifier+cap+voltage divider (5vmax) so it can read the 2 voltage sources (means and solar)... here, people told me that it will hurt the PIC and it's not well isolated... someone told me to use a voltage follower OP-AMP to isolate it.finish your league of legends and help me... xD

author: MikeK
author_rank: Super Contributor
timestamp: April 16, 2013, 09:10:49 pm
content: Don't try to debug a larger program with several (or many) features. Create a small program that does one thing, write a character to the LCD. Debugging a larger program with many features with only cause headaches. Get individual parts working separately, then you combine them.So get rid of all the ADC stuff and run it. Use the following program...Does it display anything?Code:// LCD module connectionssbit 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// LCD text variableschar txt1[] = "V1 = ";char txt2[] = "V2 = ";char txt3 = " ";char txt4 = " ";char txt5[] = "V RMS";void main() {CMCON = 7; //Disable comparatorADCON0 = 0x00ADCON1 = 0x07PORTA = 0;TRISA = 0xff;PORTD = 0;TRISD = 0;PORTC = 0;TRISC = 0;PORTB = 0;TRISB = 0;/// LCD initialization ///Lcd_Init(); // Initialize LCDLcd_Cmd(_LCD_CLEAR); // Clear displayLcd_Cmd(_LCD_CURSOR_OFF); // Cursor offLcd_Out(1,1,txt1); // Write text in first rowLcd_Out(2,1,txt2); // Write text in second rowwhile (1){}}EDIT: Another debugging technique...Connect LEDs to available PIC pins and turn them on at key spots in your code so you can see where it gets to (or doesn't).

author: VEGETA
author_rank: Super Contributor
timestamp: April 16, 2013, 09:47:28 pm
content: I don't have a programmer in handy so i can't do much programming.your code is just s piece of mine... Anyway, my code makes a handful of operation which doesn't really depend on each other.it can display the characters but with wrong voltage values... here LCD program works right and I should try better measurement of voltages.BTW, I don't have any POT right now.

author: MikeK
author_rank: Super Contributor
timestamp: April 17, 2013, 12:30:47 am
content: Yes, I whittled your program down to the minimal needed to run the LCD. You did say that the LCD isn't working, right?

author: VEGETA
author_rank: Super Contributor
timestamp: April 17, 2013, 12:33:03 am
content: I checked the datasheet and it appears that I did right about RB0/INT pin. It is 0 by default which disables the interrupt... so what should I do now?when I run the LCD I see those squares in the 1st row but I don't have any POT right now... When I connect the POT and adjust it, do you think the LCD's output characters will change?Quoteread my current post, I described it more.... these squares seems to be some kind of a sign that indicates LCD is running good or so... the left is contrast adjustment with POT.what do you think?

author: MikeK
author_rank: Super Contributor
timestamp: April 17, 2013, 01:00:51 am
content: That usually indicates that the comm is not working. If the comm was working and you wrote something to lines 1 and 2 you wouldn't see just one row of blocks.This is why I suggested using a simple program...No sense trying to debug pieces that aren't part of the problem.So now the questions become:* What fuse bits are you using?* What LCD library?...The timing may be wrong.* Your problem doesn't indicate the oscillator speed...So what is it? Are you using a crystal?* If you can't reprogram the PIC, how can you be sure it is even programmed? Or that the program is running? This would be a good place to turn on an attached LED.

author: VEGETA
author_rank: Super Contributor
timestamp: April 17, 2013, 01:08:01 am
content: "* What fuse bits are you using?"actually, I didn't touched those. Is there anything necessary to modify?"* What LCD library?...The timing may be wrong."I use the MikroC PRO for PIC compiler with it's libraries.I didn't quite understand what you said about timing... display update timing?"* Your problem doesn't indicate the oscillator speed...So what is it? Are you using a crystal?"20 MHz crystal."* If you can't reprogram the PIC, how can you be sure it is even programmed? Or that the program is running? This would be a good place to turn on an attached LED."My friend programmed it for me. The program was good until I put the LCD and then no matter how many times I rewire it, it never work the same.

author: Skimask
author_rank: Super Contributor
timestamp: April 17, 2013, 02:35:56 am
content: Quote from: VEGETA on April 17, 2013, 01:08:01 amAs I noticed since you obviously didn't read the datasheet...

author: VEGETA
author_rank: Super Contributor
timestamp: April 17, 2013, 12:29:53 pm
content: I made some configurations like selecting the external oscillator but what other things u want me to check?fuse settings I don't know them... but as I saw, the compiler (mikroC) takes care of them with the other config. bits....

author: Skimask
author_rank: Super Contributor
timestamp: April 18, 2013, 06:18:21 am
content: Quote from: VEGETA on April 17, 2013, 12:29:53 pmWhich is why I gave you the section/paragraph to look at in the datasheet and compare that with your schematic.And as far as the "compiler takes care of them with the other config bits"... I never trust that to be the case with any compiler or programmer.

author: VEGETA
author_rank: Super Contributor
timestamp: April 18, 2013, 02:46:36 pm
content: Quote from: Skimask on April 18, 2013, 06:18:21 amI made these new config bits (in attachments).the oscillator was HS before I made it XT cuz I use a crystal oscillator... so XT is the one right? what about HS?also, clock setting was 8MHz and now I made it 20MHz...any more settings need to be done?will that have any effect?__________are these config bits or fuse settings? cuz I don't differentiate between the 2 terms. ^_^

author: Skimask
author_rank: Super Contributor
timestamp: April 18, 2013, 03:10:49 pm
content: PIC16F877A datasheet, section 14.2

author: VEGETA
author_rank: Super Contributor
timestamp: April 18, 2013, 03:42:42 pm
content: well, in chapter 14.2 they said that HS is for crystal osc of 20MHz which I have so I re-choosed it. but the difference now is that I put 20MHz instead of 8MHz which was previously exist.so, having 8mhz setting instead of 20mhz can do that much error?

author: Skimask
author_rank: Super Contributor
timestamp: April 18, 2013, 06:23:23 pm
content: The LCD takes X amount of time to start up. The compiler "should" know this and compensate accordingly. Therefore, if you specified 8Mhz but ran it at 20Mhz, the "startup" period would end up being approximately 2.5 times shorter, and consequently, the LCD may or may not start up normally.And "fuse" = "config bits"...for the most part.

author: VEGETA
author_rank: Super Contributor
timestamp: April 18, 2013, 08:44:50 pm
content: aha so making 20mhz in config bits should fix the problem... I will try it tomorrow.

author: Skimask
author_rank: Super Contributor
timestamp: April 18, 2013, 09:09:45 pm
content: There are no "20Mhz config bits".All you are doing is telling the compiler what frequency you plan on using so the compiler can compensate appropriately when compiling for delays, timing, etc.(E.g. a 10ms delay loop is going to use X number of instructions at 4Mhz, but 5x that amount when running at 20Mhz.)But at the same time, you have to have to configuration set correctly to use the hardware you plan on using. In this case, when running at slower speeds, less than ~4Mhz, the "XT" setting in the config bits is appropriate due to the lower drive level for the crystal. At higher frequencies, you have to use the "HS" setting to provide a higher drive level for the crystal...just like it says in the datasheet in the paragraphs I eluded to earlier.And again, I eluded to the PGM pin earlier, also mentioned in the datasheet, because you said it did (or didn't) work with the LCD attached, andor vice-versa. If the config bits were set wrong, the LCD may have loaded down the PGM pin (or not), and if the config bits were set to utilize the low-voltage programming mode, it could have been the case that the PIC was expecting to be programmed with the LCD attached due to the logic level present on pin RB5 and appeared to be not operating correctly (when it actually was operating correctly, just not the way you expected) vs. actually running the program contained in the flash memory.Open up the datasheet and read it. Yes, it's a few hundred pages. No, you don't have to read each and every page and understand absolutely everything in each page that you do read.Save the rest of the world from questions that can be easily answered by simple searches...

author: mariush
author_rank: Super Contributor
timestamp: April 18, 2013, 09:23:09 pm
content: Make sure the delay functions are also taking the new frequency value in consideration. The lcd display library as well should be aware of the new clock frequency.The config bits only tell the microcontroller to set itself to 20mhz, they don't tell the code the new frequency (or maybe it does, I don't know how exactly it is in Mikroe, I'm using mplab-x and hitech c)Make sure your PIC actually runs at 20 Mhz... the datasheet also lists the crystal type as HS and you said in a previous post you set it as XT... the datasheet shows typical xt crystals are up to 4 Mhz. page 145, section 14.2Just put a led on a pin somewhere and do something like led on .. wait 250ms .. led off... wait 2 seconds ... led on .. wit 250ms ... led off, that way you can use a phone timer or something to make sure the delays work right.Most lcd controllers have the same parameters, they need a few ms at start to initialize (between consecutive init commands), get any lcd display datasheet and you should find the values there, though they're probably hidden inside the lcd display library from mikroe or whatever you use.Since you say you don't have a programmer and keep having to go to someone to do it, pay attention to the datasheet and the notes and double check everything and make sure your code is right. Don't just assume you can change something and it will work. The datasheets ARE good, IF you read them carefully.Personally, I would recommend to actually write the code without all kind of ready made libraries and crap, mplab-x or older mplab comes with hi-tech c compiler or xc8 or whatever it's called and it's easy to write a program and actually understand it. But without a programmer to just go on flashing and testing and fixing, it's hard to recommend this.

author: VEGETA
author_rank: Super Contributor
timestamp: April 18, 2013, 09:24:18 pm
content: you saw the image i posted earlier? crystal now is put to HS which in datasheet they say it's the one to use if you have a crystal > 4mhz which i do (20 mhz).BUT, you see the right most area? it says MCU and Oscillator... that number 20.0000 means 20 mhz crystal... but it was set to 8mhz when i compiled and downloaded the program... you understand that?that is what i meant by 20mhz config bits cuz the option is next to config bits ^_^although there's another option to choose 20 mhz in the IDE and that one is set to 20 mhz.___other config bits are disabled like you see in the image.___RB0/INT is the pin I talked about, it has the external interrupt but it's disabled by default.and yet i disabled it in code this time... and i wanna try it soon.___by these things said, i saw that putting 8.0000 mhz instead of 20.0000 mhz in that image was the problem... do you agree?

author: VEGETA
author_rank: Super Contributor
timestamp: April 18, 2013, 09:27:50 pm
content: " Make sure your PIC actually runs at 20 Mhz... the datasheet also lists the crystal type as HS and you said in a previous post you set it as XT... the datasheet shows typical xt crystals are up to 4 Mhz. page 145, section 14.2"the downloaded program on PIC used HS.... I changed it to XT then I read the datasheet and returned it to HS.

author: Unknown
author_rank: Unknown
timestamp: April 22, 2013, 10:54:59 am
content: In your circuit why are d0-d3 tied to ground, surely it's an 8 bit data bus?

author: baljemmett
author_rank: Unknown
timestamp: April 22, 2013, 12:37:18 pm
content: Quote from: jucole on April 22, 2013, 10:54:59 amThe ubiquitous HD44780-style controllers support a 4-bit mode using the top four bits of the bus only and doing two transfers per command/data byte. Can be handy when you're short of GPIOs, and is common enough that I'd expect any halfway-respectable LCD library to handle it; can't tell from the OP's code whether there's anything he has to do to tell the MikroeC library to use 4-bit mode, though.

author: VEGETA
author_rank: Super Contributor
timestamp: April 23, 2013, 11:40:42 pm
content: and how exactly can i tell it to use 4-bit mode?the whole project works fine now but this LCD thing is not......!!! although i checked the config bits again.note: means voltage (220v rms ac) is fed into bridge rectifier then a 100uF/400v filtering capacitor... then is fed into a voltage divider to make it 5v @ 280 rms (which is too much cuz rated will be about 200-230v).^but some of you here told me that this isn't isolated! so i used a voltage follower op-amp and a zener diode to enhance the input impedance to the PIC ADC pin and make some isolation... zener is to ensure 5v max.Do you see my choice a good one?

author: Rufus
author_rank: Super Contributor
timestamp: April 23, 2013, 11:56:27 pm
content: Quote from: VEGETA on April 23, 2013, 11:40:42 pmYour choice appears to show a complete lack of understanding of the problem. No one cares if you blow up your PIC, they care if someone gets electrocuted by touching it.

author: Unknown
author_rank: Unknown
timestamp: April 24, 2013, 09:42:09 am
content: Quote from: VEGETA on April 23, 2013, 11:40:42 pmAccording to the MikroC website you appear to be using the correct 4bit calls in your code.http://www.mikroe.com/download/eng/documents/compilers/mikroc/pro/pic/help/lcd_library.htmI must say I much prefer to bit-bash than use a 3rd party library as I always get a better understanding of what is going on which is great when things don't work as expected.

author: metalphreak
author_rank: Frequent Contributor
timestamp: April 24, 2013, 09:44:00 am
content: You need to initialize the LCD, set it to 4bit mode, and a few other things before it will work.A line of blocks on the first line indicates it hasn't been configured properly (and is probably still expecting 8bit commands). I suggest you read through a datasheet for the LCD properly and have a look at some example code written for PICs. Microchip actually have an LCD routine as part of their application library.There is a command, where the unused four bits are all 0's, which allows you to set 4bit mode (thus you can connect the unused ones to ground and are read as 0 for that one "use 4 bit mode" command). So essentially you can send that one 8bit command at the start.