cancel
Showing results for 
Search instead for 
Did you mean: 

lcd1602+i2c+nucleo f401re don't work on stm32cubeide but works on keil uvision

veneneux
Associate

I run the same code with the same .ioc between stme32cubeide and keil uvision but lcd only show on keil and it shows nothing on cubeide. Anyone know why?
I use register due to requirement of my teacher.
Thank you!

#include "stm32f4xx.h" #inclide < stdio.h> #define LCD_ADDR (0x27 << 1) #define LCD_EN 0x04 #define LCD_RS 0x01 void Timer2_Init(void) { // Clock enable RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; } void delay_us(uint32_t us) { // Prescaler TIM2->PSC = 16 - 1; // Auto-reload value TIM2->ARR = us; // Forced update TIM2->EGR = TIM_EGR_UG; // Clear update flag TIM2->SR &= ~TIM_SR_UIF; // Timer enable TIM2->CR1 |= TIM_CR1_CEN; while (!(TIM2->SR & TIM_SR_UIF)) ; // wait till update flag is set // Clear update flag TIM2->SR &= ~TIM_SR_UIF; // Stop timer TIM2->CR1 &= ~TIM_CR1_CEN; } void I2C_Init(void) { // Clock RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // Analog mode GPIOB->MODER |= GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1; // Open drain GPIOB->OTYPER |= GPIO_OTYPER_OT_8 | GPIO_OTYPER_OT_9; // High speed output GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8 | GPIO_OSPEEDER_OSPEEDR9; // Pull up resistor GPIOB->PUPDR |= GPIO_PUPDR_PUPDR8_0 | GPIO_PUPDR_PUPDR9_0; // Alternative function for i2c GPIOB->AFR[1] |= (4 << (4 * 0)) | (4 << (4 * 1)); // Reset I2C I2C1->CR1 |= (1 << 15); I2C1->CR1 &= ~(1 << 15); // I2C clock bus I2C1->CR2 |= (42 << 0); I2C1->CCR = 210 << 0; I2C1->TRISE = 43; // I2C enable I2C1->CR1 |= I2C_CR1_PE; } void I2C_SendData(uint8_t address, uint8_t data) { // Acknowlegde enable I2C1->CR1 |= I2C_CR1_ACK; // Send start signal I2C1->CR1 |= I2C_CR1_START; while (!(I2C1->SR1 & I2C_SR1_SB)) ; // wait for start condition generation // Send slave address I2C1->DR = address; while (!(I2C1->SR1 & I2C_SR1_ADDR)) ; // wait for address matched // Dummy read the register to clear it before sending data (void)I2C1->SR1; (void)I2C1->SR2; // Send data while (!(I2C1->SR1 & I2C_SR1_TXE)) ; // wait for data register is empty I2C1->DR = data; while (!(I2C1->SR1 & I2C_SR1_BTF)) ; // wait for byte transfer // Send stop signal I2C1->CR1 |= I2C_CR1_STOP; } void LCD_SendCmd(uint8_t cmd) { uint8_t data_u, data_l; uint8_t data_t[4]; data_u = (cmd & 0xf0); data_l = ((cmd << 4) & 0xf0); data_t[0] = data_u | 0x0C; // en=1, rs=0 data_t[1] = data_u | 0x08; // en=0, rs=0 data_t[2] = data_l | 0x0C; // en=0, rs=0 data_t[3] = data_l | 0x08; // en=1, rs=0 for (int i = 0; i < 4; i++) { I2C_SendData(LCD_ADDR, data_t[i]); delay_us(20); } } void LCD_SendData(uint8_t data) { uint8_t data_u, data_l; uint8_t data_t[4]; data_u = (data & 0xf0); data_l = ((data << 4) & 0xf0); data_t[0] = data_u | 0x0D; // en=1, rs=1 data_t[1] = data_u | 0x09; // en=0, rs=1 data_t[2] = data_l | 0x0D; // en=1, rs=1 data_t[3] = data_l | 0x09; // en=0, rs=1 for (int i = 0; i < 4; i++) { I2C_SendData(LCD_ADDR, data_t[i]); delay_us(20); } } void LCD_Init(void) { LCD_SendCmd(0x33); // LCD 4-bit mode delay_us(10000); LCD_SendCmd(0x32); // LCD 4-bit mode delay_us(2000); LCD_SendCmd(0x06); // Cursor position auto increment after a character write delay_us(2000); LCD_SendCmd(0x0C); // No cursor and cursor blinking delay_us(2000); LCD_SendCmd(0x28); // 2 line mode and 5x8 mode delay_us(2000); LCD_SendCmd(0x01); // Clear screen delay_us(2000); } void LCD_PutString(char *string, int line) { if (line == 1) { LCD_SendCmd(0x80); // First line } else { LCD_SendCmd(0xC0); // Second line } while (*string) { LCD_SendData((uint8_t)(*string)); string++; } } void LCD_PutStringFloat(char *string, float value, int line) { char buffer[32]; sprintf(buffer, "%s%.1f", string, value); LCD_PutString(buffer, line); } int main() { Timer2_Init(); I2C_Init(); LCD_Init(); delay_us(100000); LCD_PutString("Hello", 1); while (1) { } }
View more

 

4 REPLIES 4
Andrew Neil
Super User

Have you used an oscilloscope and/or logic analyser to compare what's happening on the wires in the 2 cases?

Have you used the debuggers in the IDEs to compare what's happening within the code in the 2 cases?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
Pavel A.
Super User

Is using CubeIDE a requirement? Otherwise just use Keil and be happy.

There are differences in runtime libraries, compiler-specific behaviors (optimization) and so on. Save your time and nerve cells for the meaningful part of your project.

 

This is true but, when a project works on one IDE and not another, that's usually an indicator of problems in the code...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Nothing particularly is jumping out in a KEIL vs GNU sense

I'd probably simplify the micro-second delay stuff to initialize the counter once, in maximal 32-bit mode and then observe the delta in TIM2->CNT

Check the peripheral registers in one vs the other.

Check the I2C traffic with a logic-analyzer, type to understand if the issue is one of timing or signalling.

Confirm it's executing.

Ideally have a serial connection or SWV working so you can output diagnostic info in real-time

 

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