STM32-LCD-HD44780-I2C
STM32-LCD-HD44780-I2C copied to clipboard
LCD init before OS
Предположим такую ситуацию: MCU не смог перейти на внешний источник тактирования (сломался кварц) и программист в таком случае хочет, чтобы пользователь получил на экран сообщение и ничего более, то есть бизнес-логика приложения не запускается. То есть: 0. Инициализируем источник тактирования;
- Если ошибка на шаге 0., выводим сообщение на LCD и зависаем;
- Запускаем FreeRTOS, работаем согласно бизнес-логике.
Для такого случая было бы полезно иметь в библиотеке процедуру инициализации дисплея, не требующую запущенной FreeRTOS. А также weak функцию TM_HD44780_InitPins
Как вариант
/**
* @brief Turn display on and init it params
* @note We gonna make init steps according to datasheep page 46.
* There are 4 steps to turn 4-bits mode on,
* then we send initial params. Можно вызывать как при запущеном планировщике,
* так и при незапущенном.
* @param hi2c I2C struct to which display is connected
* @param address Display I2C 7-bit address
* @param lines Number of lines of display
* @param columns Number of colums
* @return true if success
*/
bool lcdInit(I2C_HandleTypeDef *hi2c, uint8_t address, uint8_t lines, uint8_t columns){
uint8_t lcdCommandBuffer[2];
uint8_t lcdData = LCD_BIT_5x8DOTS;
lcdParams.hi2c = hi2c;
lcdParams.address = address << 1;
lcdParams.lines = lines;
lcdParams.columns = columns;
lcdParams.backlight = LCD_BIT_BACKIGHT_ON;
lcdCommandBuffer[0] = LCD_BIT_E | (0x03 << 4) | LCD_BIT_P3_ON;
lcdCommandBuffer[1] = (0x03 << 4) | LCD_BIT_P3_ON;
//Try to set 4bit mode
HAL_I2C_Master_Transmit(lcdParams.hi2c, lcdParams.address, &lcdCommandBuffer[0], 2, 1000);
lcdDelay(5);//for(volatile uint32_t i=0;i<0xFFFF;i++);//HAL_Delay(5);
//Second try
HAL_I2C_Master_Transmit(lcdParams.hi2c, lcdParams.address, &lcdCommandBuffer[0], 2, 1000);
lcdDelay(5);//for(volatile uint32_t i=0;i<0xFFFF;i++);//HAL_Delay(5);
//Third goo!
HAL_I2C_Master_Transmit(lcdParams.hi2c, lcdParams.address, &lcdCommandBuffer[0], 2, 1000);
lcdDelay(5);//for(volatile uint32_t i=0;i<0xFFFF;i++);//HAL_Delay(5);
//Set 4-bit interface
lcdCommandBuffer[0] = LCD_BIT_E | (0x02 << 4) | LCD_BIT_P3_ON;
lcdCommandBuffer[1] = (0x02 << 4) | LCD_BIT_P3_ON;
HAL_I2C_Master_Transmit(lcdParams.hi2c, lcdParams.address, &lcdCommandBuffer[0], 2, 1000);
lcdDelay(5);//for(volatile uint32_t i=0;i<0xFFFF;i++);//HAL_Delay(5);
lcdCommandBuffer[0] = LCD_BIT_E | (0x02 << 4) | LCD_BIT_P3_ON;
lcdCommandBuffer[1] = (0x02 << 4) | LCD_BIT_P3_ON;
HAL_I2C_Master_Transmit(lcdParams.hi2c, lcdParams.address, &lcdCommandBuffer[0], 2, 1000);
lcdDelay(5);//for(volatile uint32_t i=0;i<0xFFFF;i++);//HAL_Delay(5); vTaskDelay(5);
/* Lets set display params */
/* First of all lets set display size */
lcdData |= LCD_MODE_4BITS;
if (lcdParams.lines > 1) {
lcdData |= LCD_BIT_2LINE;
}
lcdCommandBuffer[0] = LCD_BIT_E | (lcdData << 4)| LCD_BIT_P3_ON;
lcdCommandBuffer[1] = (lcdData << 4) | LCD_BIT_P3_ON;//LCD_BIT_2LINE LCD_MODE_4BITS
HAL_I2C_Master_Transmit(lcdParams.hi2c, lcdParams.address, &lcdCommandBuffer[0], 2, 1000);
lcdDelay(5);//for(volatile uint32_t i=0;i<0xFFFF;i++);//HAL_Delay(5);
// lcdWriteByte((uint8_t)0x00, &lcdData); // TODO: Make 5x10 dots font usable for some 1-line display
/* Now lets set display, cursor and blink all on */
lcdDisplayOn();
/* Set cursor moving to the right */
lcdCursorDirToRight();
/* Clear display and Set cursor at Home */
lcdDisplayClear();
lcdCursorHome();
//RW pin set to read mode (anti-EMI)
lcdCommandBuffer[0] = 0x02 | LCD_BIT_P3_ON;
HAL_I2C_Master_Transmit(lcdParams.hi2c, lcdParams.address, &lcdCommandBuffer[0], 1, 1000);
return true;
}