cancel
Showing results for 
Search instead for 
Did you mean: 

I am trying to print the word hello on the LCD screen, but it is not working and I don't know why, although I am copying the code from a book for Nucleo board. i know it is a silly question, but I have just started :)

IHJEI.1
Associate II
#include <stdio.h>
#include <stdint.h>
#include "stm32f4xx.h"
void delayMs(int n);
void LCD_init(void);
void PORTS_init(void);
void LCD_DATA(char DATA);
void LCD_commands(unsigned char commands);
int main(void){
	LCD_init();
	LCD_DATA('l');
	LCD_DATA('o');
	delayMs(1000);
	while(1) {
	/* Write "hello" on LCD */ LCD_DATA('h');
	LCD_DATA('e');
	LCD_DATA('l');
	/* clear LCD display */ LCD_commands(1);
	delayMs(500);
	}}
void LCD_init(void){
	PORTS_init();
	delayMs(30); /* initialization sequence */ LCD_commands(0x30);
	delayMs(10);
	LCD_commands(0x30);
	delayMs(1);
	LCD_commands(0x30);
	LCD_commands(0x38); /* set 8-bit data, 2-line, 5x7 font */
	LCD_commands(0x06); /* move cursor right after each char */
	LCD_commands(0x01); /* clear screen, move cursor to home */
	LCD_commands(0x0F);
 
 
}
void PORTS_init(){
	RCC->AHB1ENR 	 |=0x06;
	GPIOC->MODER	 &=!(0x0000FFFF);
	GPIOC->MODER	 |=  0x00005555;
	GPIOB->MODER	 &=!(0x0000FC00);
	GPIOB->MODER	 |= (0x00005400);
	GPIOB->BSRR		  = 0x00C00000;
 
}
void LCD_commands(unsigned char commands){
	GPIOB->BSRR	|=(0x60 << 16);
	GPIOC->ODR  |=commands;
	GPIOB->BSRR |=0x80;
	delayMs(0);
	GPIOB->BSRR |=0x80 << 16;
	if (commands < 4)
	delayMs(2); /* commands 1 and 2 needs up to 1.64ms */
	else
	delayMs(1);
}
void LCD_DATA(char DATA){
	GPIOB->BSRR |= (0x20);
	GPIOB->BSRR |= (0x40 <<16);
	GPIOC->ODR	|=DATA;
	GPIOB->BSRR |=0x80;
	delayMs(0);
	GPIOB->BSRR |=0x80 << 16;
}
void delayMs(int n) {
int i;
for (; n > 0; n--)
for (i = 0; i < 3195; i++) ;
}

1 ACCEPTED SOLUTION

Accepted Solutions

> GPIOC->MODER &=!(0x0000FFFF);

Certainly not. ! in C is logic negation, i.e. !whatever_nonzero results in zero. What you want here is bitwise negation, which in C is ~ (tilde):

GPIOC->MODER &= ~0x0000FFFF;

However, this is not the reason why your program does not work, as GPIOC_MODER is zero after reset, and GPIOB_MODER while not zero, if you don't use JTAG, clearing it does not matter much.

---------

> GPIOB->BSRR |=(0x60 << 16);

This is technically OK and works, but you should not |= into BSRR, you should directly write

GPIOB->BSRR	|=(0x60 << 16);

------

> void LCD_commands(unsigned char commands){

> [...]

> GPIOC->ODR |=commands;

This is certainly wrong. You set bits in ODR, but never clear.

JW

View solution in original post

5 REPLIES 5

Which STM32F4 NUCLEO?

What make/model of LCD screen are we talking about?

How is it wired exactly? Provide the wiring diagram you're using.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Blinky (blinking a LED using the delay you have here) works?

Delay needs variable i ​qualified as volatile.

JW​

IHJEI.1
Associate II

sorry for the lack of details,

i am using Nucleo-F411RE, and the LCD is LCD2004A.

the wiring is

* PC0-PC7 for LCD D0-D7, respectively.

* PB5 for LCD R/S

* PB6 for LCD R/W

* PB7 for LCD EN

The delay works for blinky but It counts 2.65 seconds rather than 1 second

> GPIOC->MODER &=!(0x0000FFFF);

Certainly not. ! in C is logic negation, i.e. !whatever_nonzero results in zero. What you want here is bitwise negation, which in C is ~ (tilde):

GPIOC->MODER &= ~0x0000FFFF;

However, this is not the reason why your program does not work, as GPIOC_MODER is zero after reset, and GPIOB_MODER while not zero, if you don't use JTAG, clearing it does not matter much.

---------

> GPIOB->BSRR |=(0x60 << 16);

This is technically OK and works, but you should not |= into BSRR, you should directly write

GPIOB->BSRR	|=(0x60 << 16);

------

> void LCD_commands(unsigned char commands){

> [...]

> GPIOC->ODR |=commands;

This is certainly wrong. You set bits in ODR, but never clear.

JW

IHJEI.1
Associate II

Thank you very much, it is working fine now