2011-11-08 12:15 PM
does any one has working 4b mode driver code for HD44780 lcd ?
can't find anything2011-11-10 02:48 AM
Please see if this is useful.
http://singamicro-63-stm32l152-k1.blogspot.com/p/lcd-page-32.html
Regards.2011-11-11 04:26 AM
That code uses a for() loop for timing, and doesn't describe what the assumptions are. It's both wrong and uninformative.
The command set for a HD44780-compatible display is very simple, but there are many ways to hook up the hardware and different ways to handle the slow timing. Trying to use generic code results in more complexity than just writing code for your specific configuration. The only slightly tricky part is the initial command sequence to switch from byte mode (the power-up default) to nibble mode, but that's well explained in every datasheet and article I've seen. More challenging is structuring your code to meet the application requirements and slow timing of the display. Simple projects often just do a busy-wait, but if you wanted to waste most of your processing time you wouldn't be using a STM32. The reference I've used in the past was http://home.iae.nl/users/pouweha/lcd/lcd.shtml It's still there, but their web server page generation is currently a little borked.2011-11-18 02:51 AM
since i found a way to turn on and off led, i rewrite LCD program from my last project (it was for MSP430)
and soon enough i was able to drive lcd :) ok, first file is lcd.h //*******************************************************************#include ''stm32f4xx.h''
#define LCM_OUT GPIOB->ODR // connect RW leg to GND, and power supply rails to +5V and gnd // Define symbolic LCM - MCU pin mappings // We've set DATA PIN TO 4,5,6,7 for easy translation // #define LCM_PIN_RS GPIO_Pin_0 // P1.0 #define LCM_PIN_EN GPIO_Pin_1 // P1.1 #define LCM_PIN_D7 GPIO_Pin_7 // P1.7 #define LCM_PIN_D6 GPIO_Pin_6 // P1.6 #define LCM_PIN_D5 GPIO_Pin_5 // P1.5 #define LCM_PIN_D4 GPIO_Pin_4 // P1.4 GPIO_InitTypeDef GPIO_InitStructure; #define LCM_PIN_MASK ((LCM_PIN_RS | LCM_PIN_EN | LCM_PIN_D7 | LCM_PIN_D6 | LCM_PIN_D5 | LCM_PIN_D4)) #define FALSE 0 #define TRUE 1 void __delay_cycles(int a) { int i = 0; int f = 0; while(f<a) { while(i<60) {i++;} f++; } } void PulseLcm() { LCM_OUT &= ~LCM_PIN_EN; __delay_cycles(220); LCM_OUT |= LCM_PIN_EN; __delay_cycles(220); LCM_OUT &= (~LCM_PIN_EN); __delay_cycles(220); } void SendByte(char ByteToSend, int IsData) { LCM_OUT &= (~LCM_PIN_MASK); LCM_OUT |= (ByteToSend & 0xF0);if (IsData == TRUE)
{ LCM_OUT |= LCM_PIN_RS; } else { LCM_OUT &= ~LCM_PIN_RS; } PulseLcm(); LCM_OUT &= (~LCM_PIN_MASK); LCM_OUT |= ((ByteToSend & 0x0F) << 4);if (IsData == TRUE)
{ LCM_OUT |= LCM_PIN_RS; } else { LCM_OUT &= ~LCM_PIN_RS; }PulseLcm();
} void Cursor(char Row, char Col) { char address; if (Row == 0) { address = 0; } else { address = 0x40; }address |= Col;
SendByte(0x80 | address, FALSE); } void ClearLcmScreen() { SendByte(0x01, FALSE); SendByte(0x02, FALSE); } void InitializeLcm(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure);LCM_OUT &= ~(LCM_PIN_MASK);
__delay_cycles(32000);
__delay_cycles(32000); __delay_cycles(32000);LCM_OUT &= ~LCM_PIN_RS;
LCM_OUT &= ~LCM_PIN_EN; LCM_OUT = 0x20; PulseLcm(); SendByte(0x28, FALSE); SendByte(0x0E, FALSE); SendByte(0x06, FALSE); } void PrintStr(char *Text) { char *c;c = Text;
while ((c != 0) && (*c != 0))
{ SendByte(*c, TRUE); c++; } } //*************************************************************** and main.c#include ''stm32f4xx.h''
#include ''lcd.h'' int main(void) { int a = 0; while(a<100) { __delay_cycles(32000); a++; }InitializeLcm();
__delay_cycles(32000); ClearLcmScreen(); __delay_cycles(32000); Cursor(0,0); PrintStr('' STM32F407VGT ''); Cursor(1,0); __delay_cycles(32000); PrintStr(''Hello World !!'');while(1);
} //****************************************************** in define you can set port and legs to drive it, same change must be done in GPIOinit part of program if code is not working, use more delay :) now working to print integer and maybe float.2011-11-20 08:17 AM
if any one know how to use sprintf function so i can print int, float and others, please post it here
2011-12-06 03:20 AM
This looks like a great initial example for the STM32F4 Discovery board.
I tried compiling it using Atollic's TrueStudio and I seem to be missing some necessary header files. I'd appreciate any help you can give me to get it working using Atollic. Thanks2011-12-06 03:59 AM
The C library standard describes the sprintf function as follows:
Synopsis int sprintf(char *s, const char *format, ...);Description The sprintf function is equivalent to fprintf, except that the argument s specifies an array into which the generated output is to be written, rather than to a stream. A null character is written at the end of the characters written, it is not counted as part of the returned sum.Returns The sprintf function returns the number of characters written in the array, not counting the terminating null character.2011-12-07 11:27 AM
look close.
first file is lcd.h second part of code is main.c main code is near the end, and first part is lcd.h2011-12-08 11:45 PM
Fine code. But...
It does't work in Release configuration with gcc optimization levels -O1, -O2, -O3. It seems like lcd doesn't configured. I can use it only with -Os (optimize for size). :) I think delay-functions optimized by compiler.2011-12-09 05:01 PM
That's the same problem that I pointed out in the code above. Software timing loops are unpredictable and unreliable.
The LCD modules have a Busy indication, available on data line D7 by reading. Which implies an extra STM32 pin for driving the R/W signal, although it can often be shared. If you aren't going to use the Busy signal, at least use a reliable timing base for a blind delay. The STM32 has a SysTick timer for this type of timing, or you can set up a down counter for an interrupt.