/* * Initialize LCD controller and flash "HELLO" on LCD. * * The LCD controller of EduBase board is connected to * the Nucleo board in parallel. * * The signals for LCD: * D4 - PB12 * D5 - PB13 * D6 - PB14 * D7 - PB15 * RS - PA11 * EN - PA12 * For simplicity, all delay below 1 ms uses 1 ms. */ #include "stm32f4xx.h" #define RS 1 /* reg select */ void delayMs(int n); void delayUs(int n); void LCD_nibble_write(char data, unsigned char control); void LCD_command(unsigned char command); void LCD_data(char data); void LCD_init(void); void PORTS_init(void); int main(void) { /* initialize LCD controller */ LCD_init(); while(1) { /* Write "HELLO" on LCD */ LCD_data('H'); LCD_data('E'); LCD_data('L'); LCD_data('L'); LCD_data('O'); delayMs(1000); /* clear LCD display */ LCD_command(1); delayMs(1000); } } /* initialize the ports then the LCD controller */ void LCD_init(void) { PORTS_init(); /* initialize the ports that connect to the LCD */ /* LCD controller reset sequence */ delayMs(20); LCD_nibble_write(0x30, 0); delayMs(5); LCD_nibble_write(0x30, 0); delayMs(1); LCD_nibble_write(0x30, 0); delayMs(1); LCD_nibble_write(0x20, 0); /* use 4-bit data mode */ delayMs(1); LCD_command(0x28); /* set 4-bit data, 2-line, 5x7 font */ LCD_command(0x06); /* move cursor right */ LCD_command(0x01); /* clear screen, move cursor to home */ LCD_command(0x0F); /* turn on display, cursor blinking */ } void PORTS_init(void) { RCC->AHB1ENR |= 1; /* enable GPIOA clock */ RCC->AHB1ENR |= 2; /* enable GPIOB clock */ GPIOB->MODER &= ~0xFF000000; /* clear pin mode */ GPIOB->MODER |= 0x55000000; /* set PB15-12 to output mode */ GPIOA->MODER &= ~0x00C00000; /* clear pin mode */ GPIOA->MODER |= 0x00400000; /* set PA11 to output mode */ GPIOA->MODER &= ~0x03000000; /* clear pin mode */ GPIOA->MODER |= 0x01000000; /* set PA12 to output mode */ } void LCD_nibble_write(char data, unsigned char control) { /* populate data bits */ GPIOB->BSRR = 0xF0000000; // clear D7-4 GPIOB->BSRR = data << 8; // set D7-4 /* set R/S bit */ if (control & RS) GPIOA->BSRR = 0x0800; else GPIOA->BSRR = 0x08000000; /* pulse E */ delayMs(0); GPIOA->BSRR = 0x00001000; delayMs(0); GPIOA->BSRR = 0x10000000; } void LCD_command(unsigned char command) { LCD_nibble_write(command & 0xF0, 0); /* upper nibble first */ LCD_nibble_write(command << 4, 0); /* then lower nibble */ if (command < 4) delayMs(2); /* command 1 and 2 needs up to 1.64ms */ else delayMs(1); /* all others 40 us */ } void LCD_data(char data) { LCD_nibble_write(data & 0xF0, RS); /* upper nibble first */ LCD_nibble_write(data << 4, RS); /* then lower nibble */ delayMs(1); } /* 16 MHz SYSCLK */ void delayMs(int n) { int i; for (; n > 0; n--) for (i = 0; i < 3195; i++) ; }