Hi, I did not like any library for handling the LCD so I write her but I do not know what to do next .... where's my mistake? Thank you very much.
#include <msp430g2452.h>#define LCD_DIR P1DIR#define LCD_OUT P1OUT#define LCD_PIN_RS BIT0#define LCD_PIN_EN BIT1#define LCD_PIN_D4 BIT2#define LCD_PIN_D5 BIT3#define LCD_PIN_D6 BIT4#define LCD_PIN_D7 BIT5void PulseLCD(void){ LCD_OUT |= LCD_PIN_EN; __delay_cycles(2000); LCD_OUT &= (~LCD_PIN_EN); __delay_cycles(2000);}void SendBite(char data){ if(data & 0x01) LCD_OUT |= LCD_PIN_D4; else LCD_OUT &= ~LCD_PIN_D4; __delay_cycles(2000); if(data & 0x02) LCD_OUT |= LCD_PIN_D5; else LCD_OUT &= ~LCD_PIN_D5; __delay_cycles(2000); if(data & 0x04) LCD_OUT |= LCD_PIN_D6; else LCD_OUT &= ~LCD_PIN_D6; __delay_cycles(2000); if(data & 0x08) LCD_OUT |= LCD_PIN_D7; else LCD_OUT &= ~LCD_PIN_D7; __delay_cycles(2000); PulseLCD();}void SendInstruction(char data){ LCD_OUT &= ~LCD_PIN_RS; SendBite((data>>4) & 0x0F); SendBite((data) & 0x0F);}void SendByte(char data){ LCD_OUT |= LCD_PIN_RS; SendBite((data>>4) & 0x0F); SendBite((data) & 0x0F);}void InitLCD(void){ LCD_OUT &= (~LCD_PIN_EN); LCD_OUT |= LCD_PIN_RS; __delay_cycles(100000); SendInstruction(0x02); SendInstruction(0x0C); SendInstruction(0x01); SendInstruction(0x06);}void LCDSetPosition(char Row, char Col){ char address; if (Row == 0) { address = 0; } else { address = 0x40; } address |= Col; SendInstruction(0x80 | address);}void LCDClear(void){ SendInstruction(0x01);}void LCDGoToHome(void){ SendInstruction(0x02);}void LCDShiftLeft(void){ SendInstruction(0x18);}void LCDShiftRight(void){ SendInstruction(0x1C);}void LCDBlinkCursor(void){ SendInstruction(0x0F);}void LCDPrintString(const char * Text){ while (*Text) SendByte(*Text++);}
Here is my current code. The circuit is not a problem because other library is functions.
Marek Prochazkavoid InitLCD(void){ LCD_OUT &= (~LCD_PIN_EN); //LCD_OUT |= LCD_PIN_RS; // useless __delay_cycles(100000); SendInstruction(0x02); <------ Init missing __delay_cycles(8000); <------- Init Setup SendInstruction(0x0C); // Make cursor invisible SendInstruction(0x01); // Clear Screen SendInstruction(0x06); // Increment Address Counter mode}
__delay_cycles(8000); <------- Init Setup SendInstruction(0x0C); // Make cursor invisible SendInstruction(0x01); // Clear Screen SendInstruction(0x06); // Increment Address Counter mode}
Hi Marek, refer this table for commands:
http://www.geocities.com/dinceraydin/lcd/commands.htm
I suppose your display is a single line from mistake so a 0x20 not 0x02 is required otherwise a 0x28 for 2 line display. Code 02 is executed by 01 too.
What happen on display when you launch this code?
Regards
Roberto
Please login & click Verify Answer if this post answered your question.
Here is my function. The display does nothing. My display is 2x16 char.
void InitLCD(void){ LCD_OUT &= (~LCD_PIN_EN); //LCD_OUT |= LCD_PIN_RS; __delay_cycles(100000); SendInstruction(0x28); __delay_cycles(8000); SendInstruction(0x0C); SendInstruction(0x01); SendInstruction(0x06);}
Marek Prochazkaoid InitLCD(void){ LCD_OUT &= (~LCD_PIN_EN); //LCD_OUT |= LCD_PIN_RS; __delay_cycles(100000); SendInstruction(0x28); __delay_cycles(8000); SendInstruction(0x0C); SendInstruction(0x01); SendInstruction(0x06);}
Hi Marek, you are missing a lot of things, timing and initiation, I setup a test and LCD started but a lot of cleaning has to be done...
http://meteosat.pessac.free.fr/Cd_elect/Doc-CI/LCD/lcd-htm/LCD%20Hitachi.htm
No DIR setting exist, on 4 bit some initiation needed so i loaded your code and debugged... It work after adding 8 bit set trick and setting port direction out:
If still doesn't work I am sorry but i lost too much time in this lib and hardware debug may be necessary.
Please start thinking in a good programmer way and comment code.
// ############################################### changed part to match hardware
#include "io430.h" //<msp430g2452.h> #define LCD_DIR P1DIR #define LCD_OUT P1OUT #define LCD_PIN_RS BIT4 #define LCD_PIN_EN BIT5 #define LCD_PIN_D4 BIT0 #define LCD_PIN_D5 BIT1 #define LCD_PIN_D6 BIT2 #define LCD_PIN_D7 BIT3
// ############################################################
void PulseLCD(void) { // Set Enable active LCD_OUT |= LCD_PIN_EN; __delay_cycles(20); // Release Strobe LCD_OUT &= (~LCD_PIN_EN); } void SendBite(char data) { if(data & 0x01) LCD_OUT |= LCD_PIN_D4; else LCD_OUT &= ~LCD_PIN_D4; if(data & 0x02) LCD_OUT |= LCD_PIN_D5; else LCD_OUT &= ~LCD_PIN_D5; if(data & 0x04) LCD_OUT |= LCD_PIN_D6; else LCD_OUT &= ~LCD_PIN_D6; if(data & 0x08) LCD_OUT |= LCD_PIN_D7; else LCD_OUT &= ~LCD_PIN_D7; PulseLCD(); __delay_cycles(50000); } void SendInstruction(char data) { LCD_OUT &= ~LCD_PIN_RS; SendBite((data>>4) & 0x0F); SendBite((data) & 0x0F); } void SendByte(char data) { LCD_OUT |= LCD_PIN_RS; SendBite((data>>4) & 0x0F); SendBite((data) & 0x0F); } void InitLCD(void) { LCD_OUT &= ~(LCD_PIN_EN|LCD_PIN_RS); //LCD_OUT &= ~LCD_PIN_RS; LCD_DIR |=(LCD_PIN_EN|LCD_PIN_RS|LCD_PIN_D4|LCD_PIN_D5|LCD_PIN_D6|LCD_PIN_D7); __delay_cycles(100000); SendBite(3); __delay_cycles(80000); SendBite(3); __delay_cycles(80000); SendBite(3); __delay_cycles(80000); SendBite(2); __delay_cycles(80000); SendInstruction(0x28); __delay_cycles(80000); SendInstruction(0x0C); SendInstruction(0x01); __delay_cycles(160000); SendInstruction(0x06); __delay_cycles(80000);
SendInstruction(0x80);__delay_cycles(80000);
} void LCDSetPosition(char Row, char Col) { if(Row) Col+=0x40; //0x28; SendInstruction(0x80 | Col); } void LCDClear(void) { SendInstruction(0x01); } void LCDGoToHome(void) { SendInstruction(0x02); } void LCDShiftLeft(void) { SendInstruction(0x18); } void LCDShiftRight(void) { SendInstruction(0x1C); } void LCDBlinkCursor(void) { SendInstruction(0x0F); } void LCDPrintString(const char * Text) { while (*Text) SendByte(*Text++); } void main (void) { char c; int i; // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; InitLCD(); LCDPrintString("Hello world"); c='0'; while(1) { LCDSetPosition(1,10); for(i=0;i<1000;i++) __delay_cycles(1000); SendByte(c); c++; if(c>'9') c='0'; } }
Hi Marek, I completely debugged your code, so set your pinout I changed to use on my hardware and tell me if it work also on your setup.
I hope can be of some help so I wish post on 43oh site, can I do that?
Here is final version of code, I hope you can learn from and get good programmer style.
Every time I hit reset or power up restart in the correct way.
/* This program is an example of HD44780 driver no busy check Original from Marek Prochazka, adapted and debugged then released to public domain in TI e2e. This program use a bit free assignment to lcd pinout so 6 free pin can be connected to LCD any way. uP selected from Project setting. Tested on an LCD 16x2 and MSP430G2231*/#include "io430.h"//<msp430g2452.h>// LCD Port assignement#define LCD_DIR P1DIR#define LCD_OUT P1OUT// Lcd Pin assignement#define LCD_PIN_RS BIT4//#define LCD_PIN_RW BIT7#define LCD_PIN_EN BIT5#define LCD_PIN_D4 BIT0#define LCD_PIN_D5 BIT1#define LCD_PIN_D6 BIT2#define LCD_PIN_D7 BIT3// Procedure to strobe data to LCD registervoid LCDPulseEN(void){ // Set Enable active __delay_cycles(20); LCD_OUT |= LCD_PIN_EN; __delay_cycles(20); // Release Strobe LCD_OUT &= (~LCD_PIN_EN);}// this send 4 bit of datavoid SendNibble(char data){ // Clear all data bit LCD_OUT &= ~(LCD_PIN_D4|LCD_PIN_D5|LCD_PIN_D6|LCD_PIN_D7); // Set data bit on port bit if(data & 0x01) LCD_OUT |= LCD_PIN_D4; if(data & 0x02) LCD_OUT |= LCD_PIN_D5; if(data & 0x04) LCD_OUT |= LCD_PIN_D6; if(data & 0x08) LCD_OUT |= LCD_PIN_D7; // Nibble set complete, send to LCD LCDPulseEN(); __delay_cycles(500);}// Send a byte of data to LCD registervoid SendByte(unsigned char data){ SendNibble((data>>4) & 0x0F); SendNibble((data) & 0x0F); __delay_cycles(500);}// send a byte to command registervoid SendInstruction(unsigned char data){ // Set Register to command LCD_OUT &= ~LCD_PIN_RS; SendByte(data); __delay_cycles(80000);}// Send a byte of data to LCD registervoid LCDputch(unsigned char data){ // Set Register to data LCD_OUT |= LCD_PIN_RS; SendByte(data); __delay_cycles(500);}void InitLCD(void){ // clear all bit of LCD control & data Lines LCD_OUT &= ~(LCD_PIN_EN|LCD_PIN_RS); //|LCD_PIN_RW); // Set LCD pins to output LCD_DIR |=(LCD_PIN_EN|LCD_PIN_RS|LCD_PIN_D4|LCD_PIN_D5|LCD_PIN_D6|LCD_PIN_D7); // |LCD_PIN_RW // wait Powerup __delay_cycles(100000); // LCD can be in an unknown state so set to a known state sending 3 times LCD set to 8 bit mode SendNibble(3); __delay_cycles(16000); // Wait for init SendNibble(3); __delay_cycles(400); SendNibble(3); __delay_cycles(400); // now is 8 bit, sending 2 set mode to 4 bit (0x2n) SendNibble(2); __delay_cycles(800); // Now set to mode 4 bit 2 line 5x7 char SendInstruction(0x28); __delay_cycles(8000); // Make cursor visible one line set to 0x0c to invisible cursor SendInstruction(0x0e);//c __delay_cycles(800); // Clear screen SendInstruction(0x01); __delay_cycles(8000); // Increment address mode SendInstruction(0x06); __delay_cycles(8000); // Set write data address to 0 SendInstruction(0x80);}// Set write cursor to Row and Colvoid LCDSetPosition(char Row, char Col){ // if row is not 0 add 0x40 (4 line models require adding 0 20 60 40) if(Row) Col+=0x40; SendInstruction(0x80 | Col); __delay_cycles(800);}// Clear LCDvoid LCDClear(void){SendInstruction(0x01); __delay_cycles(100000);}// Lcd cursor to first row first columnvoid LCDGoToHome(void){SendInstruction(0x02); __delay_cycles(100000);}// Shift left modevoid LCDShiftLeft(void){SendInstruction(0x18);}// Shift right modevoid LCDShiftRight(void){SendInstruction(0x1C);}// Cursor blinking modevoid LCDBlinkCursor(void){SendInstruction(0x0F);}// Print a text line to LCD screenvoid LCDPrintString(const char * Text){ while (*Text) LCDputch(*Text++);}void main (void){ char c; int i; // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; InitLCD(); LCDPrintString("Hello world"); c='0'; while(1) { LCDSetPosition(1,10); for(i=0;i<100;i++) __delay_cycles(1000); LCDputch(c); c++; if(c>'9') c='0'; }}
It works! Thank you very much.
c='0'; while(1) { LCDSetPosition(1,10); for(i=0;i<100;i++) __delay_cycles(1000); LCDputch(c); c++; if(c>'9') c='0'; }}
It also works without it. With this last position on the redrawing at random character.
Marek Prochazka LCDputch(c); c++; if(c>'9') c='0'; }} It also works without it. With this last position on the redrawing at random character.
LCDputch(c); c++; if(c>'9') c='0'; }}
I don't understand about random character..
It must appear like this with number 0..9 sequence only changing faster but not random
Last question was not answered, i wish publish this code on 430OH blog, can i leave your name and pubblish as is?
Original question .. #I hope can be of some help so I wish post on 43oh site, can I do that?#
I am happy to learn that finally it work, to finalize thread please click on Verify(ied) answer.
Yes of course-this is your code. Thank you very much.
Hi Roberto,
I was connecting the the circuit wrongly. Sorry to disturb you, actually I was keeping 2 different grounds for the circuit. One for the MSP and another for the LCD. So when I connected the ground line of the LCD with MSP some arbitiary characters started appearing. That's how I came to know that I was making a silly mistake. The code works fine without any correction. But i'll check your modifications and verify to you.
lovelesh Hi Roberto, I was connecting the the circuit wrongly. Sorry to disturb you, actually I was keeping 2 different grounds for the circuit. One for the MSP and another for the LCD. So when I connected the ground line of the LCD with MSP some arbitiary characters started appearing. That's how I came to know that I was making a silly mistake. The code works fine without any correction. But i'll check your modifications and verify to you.
Hi Lovelesh, I am not sure to fully understand your writing, your code or Marek code?
If you need help just ask, if I have some spare time I answer suddenly otherwise just wait or ask again on private conv.n
My problem is solved. Thanks. Now i am planning to put three hardware interrupts to my msp so that when any of the interrupts are on only messages related to that interrupt will be displayed. i am using msp430g2553 and planning to use push buttons as interrupts.
Plz suggest me some posts or discussions that will guide me.
Good morning Roberto Romano. I am a italian student and i'm working with a diplay in my project. I try your program and it works. I have to translate this program in assembly language, you can help me? I am desperate because i try to do this program from 3 weeks and I did not succeed. Thank you very much.
ps: I use a MSP430F5437A.
Hi Francesca, when I meet MSP430 on early 2K year I translated assembly to C, also during the hugest project, (interrupt real time filtering of audio signalling twin 10 frequency bank) I looked to assembly generated by C and just one or two useless instruction, analysis reported me code was no more than I can optimize on asm side so I decided to just use C.
Tell me why ASM needed and I can help you cure your trouble. I am not so much online this period, but try and I answer ASAP I have good ADSL carrier.
Hi Roberto, thank you for your interest. I have to pragram in assembly for academic reasons : can use assembly language is important because it can useful in many applications so prof. says us to use assembly. I would be grateful if you could help me.