lucas_mur
Newbie

Hey, It's been a while that I'm trying to display character in my LCD HD44780 which is connected to Nucleo STM32F103RB board, but without any success. That's why I'm here to find any suggestion or solution about that. For the connection, I connect the LCD with the board via :
VSS = GND
VDD = 5V
VO = with the resistance 10Kohm
RS = PB0
RW = GND
E = PB1
D4 = PB2
D5 = PB3
D6 = PB4
D7 = PB5
Everthing is Ok with pins, the LCD turn On. when I change the resistance, I see the black rectangles in the first line. Here the code that I'm using for the LCD according to the datasheet found in the LCD vendor webiste, the code explanation is bellow the code.
For my code, I started by configuring the board clock which I use 36Mhz, then I initialize the the port (Port B) and the pins used in LCD (PB0 to PB5). I also use Timer 2 in order to create a delay function, the delay is in microsecond unit. Finally I follow the the datasheet to initialize the LCD and display the characters. So if anyone could highlight me about the issue or suggested solution.
VSS = GND
VDD = 5V
VO = with the resistance 10Kohm
RS = PB0
RW = GND
E = PB1
D4 = PB2
D5 = PB3
D6 = PB4
D7 = PB5
Everthing is Ok with pins, the LCD turn On. when I change the resistance, I see the black rectangles in the first line. Here the code that I'm using for the LCD according to the datasheet found in the LCD vendor webiste, the code explanation is bellow the code.
C:
#include "stm32f103xb.h"
#include <unistd.h>
#define LCD_RS_ON() GPIOB->ODR |= 1<<0;
#define LCD_RS_OFF() GPIOB->ODR &= ~(1<<0);
#define LCD_E_ON() GPIOB->ODR |= 1<<1;
#define LCD_E_OFF() GPIOB->ODR &= ~(1<<1);
#define LCD_PB2_ON() GPIOB->ODR |= 1<<2;
#define LCD_PB2_OFF() GPIOB->ODR &= ~(1<<2);
#define LCD_PB3_ON() GPIOB->ODR |= 1<<3;
#define LCD_PB3_OFF() GPIOB->ODR &= ~(1<<3);
#define LCD_PB4_ON() GPIOB->ODR |= 1<<4;
#define LCD_PB4_OFF() GPIOB->ODR &= ~(1<<4);
#define LCD_PB5_ON() GPIOB->ODR |= 1<<5;
#define LCD_PB5_OFF() GPIOB->ODR &= ~(1<<5);
void SystemClockConfig(void);
void init_Timer(void);
void init_GPIO(void);
void _lcdWrite8bits(uint8_t data, uint8_t rs);
void lcdInit();
void lcdPutc(char c, uint8_t line);
static void delay_us(int us);
void lcd_toggle_enable (void);
int main(void){
SystemClockConfig();
init_Timer();
init_GPIO();
lcdInit();
lcdPutc('A',0);
while(1);
return 0;
}
void _lcdWrite8bits(uint8_t data, uint8_t rs){
if(rs){
LCD_RS_ON();
}
else{
LCD_RS_OFF();
}
LCD_PB2_OFF();
LCD_PB3_OFF();
LCD_PB4_OFF();
LCD_PB5_OFF();
if((data & 0x10) == 0x10){
LCD_PB2_ON();
}
if((data & 0x20) == 0x20){
LCD_PB3_ON();
}
if((data & 0x40) == 0x40){
LCD_PB4_ON();
}
if((data & 0x80) == 0x80){
LCD_PB5_ON();
}
lcd_toggle_enable();
LCD_PB2_OFF();
LCD_PB3_OFF();
LCD_PB4_OFF();
LCD_PB5_OFF();
if((data & 0x01) == 0x01){
LCD_PB2_ON();
}
if((data & 0x02) == 0x02){
LCD_PB3_ON();
}
if((data & 0x04) == 0x04){
LCD_PB4_ON();
}
if((data & 0x08) == 0x08){
LCD_PB5_ON();
}
lcd_toggle_enable();
}
void lcd_toggle_enable (void){
delay_us(500);
LCD_E_ON();
delay_us(500);
LCD_E_OFF();
delay_us(500);
}
void lcdInit(){
delay_us(20000);
_lcdWrite8bits(0x33,0);
_lcdWrite8bits(0x32,0);
_lcdWrite8bits(0x06,0);
_lcdWrite8bits(0x0C,0);
_lcdWrite8bits(0x28,0);
_lcdWrite8bits(0x01,0);
delay_us(500);
}
void lcdPutc(char c, uint8_t line){
uint8_t LIGNE_1 = 0x80;
uint8_t LIGNE_2 = 0xC0;
if(line ==0){
_lcdWrite8bits(LIGNE_1, 0);
}
else if (line==1){
_lcdWrite8bits(LIGNE_2, 0);
}
_lcdWrite8bits(c, 1);
}
void SystemClockConfig(){
//activation HSI -> HSION
RCC->CR &= 0;
RCC->CR |= 1;
/*Attender la mise en place de HSI HSIRDY*/
while (!(RCC->CR & (1<<1))){}
// PLL prendre un facteur 9
RCC->CFGR |= (0b0111 << 18);
//Activer le PLL -> PLLON
RCC->CR |= (1 << 24);
/*Attendre l'activation de PLL-> PLLRDY*/
while (!(RCC->CR & (1<<25))){}
/*Metre PLL comme clock source*/
RCC->CFGR &= ~0b11;
RCC->CFGR |= 0b10;
/*Attendre le changement de clock source */
while (!(RCC->CFGR & (0b10<<2))){}
/*Prescaler 2 pour APB1*/
RCC->CFGR &= ~(0b111 << 8);
RCC->CFGR |= 0b100 << 8;
}
void init_GPIO(void){
RCC->APB2ENR &=~(1 << 3); // clear RCC for GPIOB
RCC->APB2ENR |= (1 << 3); // Enable RCC for GPIOB
GPIOB->CRL &= ~((1 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); // Clear GPIO PB0 MODE
GPIOB->CRL &= ~((1 << 6) | (1 << 5) | (1 << 7) | (1 << 4)); // Clear GPIO PB1 MODE
GPIOB->CRL &= ~((1 << 11) | (1 << 10) | (1 << 9) | (1 << 8)); // Clear GPIO PB2 MODE
GPIOB->CRL &= ~((1 << 15) | (1 << 14) | (1 << 13) | (1 << 12)); // Clear GPIO PB3 MODE
GPIOB->CRL &= ~((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19)); // Clear GPIO PB4 MODE
GPIOB->CRL &= ~((1 << 20) | (1 << 21) | (1 << 22) | (1 << 23)); // Clear GPIO PB5 MODE
GPIOB->CRL |= 0x00222222; // Set GPIO PB0--->5 MODE (01 : output)
}
void init_Timer(void){
RCC->APB1ENR &= 0 << 0;
RCC->APB1ENR |= 1 << 0;
TIM2->PSC = 35;
TIM2->ARR = 30000;
TIM2->EGR |= 1;
TIM2->CR1 |= 1;
}
static void delay_us(int us)
{
TIM2->CNT = 0;
while(TIM2->CNT <= us );
}
For my code, I started by configuring the board clock which I use 36Mhz, then I initialize the the port (Port B) and the pins used in LCD (PB0 to PB5). I also use Timer 2 in order to create a delay function, the delay is in microsecond unit. Finally I follow the the datasheet to initialize the LCD and display the characters. So if anyone could highlight me about the issue or suggested solution.