2022-07-03 01:10 PM
#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++) ;
}
Solved! Go to Solution.
2022-07-04 02:10 AM
> 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
2022-07-03 02:05 PM
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.
2022-07-03 02:38 PM
Blinky (blinking a LED using the delay you have here) works?
Delay needs variable i qualified as volatile.
JW
2022-07-04 12:42 AM
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
2022-07-04 02:10 AM
> 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
2022-07-04 06:11 AM
Thank you very much, it is working fine now