STM32 UART : HAL_UART_Transmit_IT Not working with Task - stm32

My UART tx Working with blocking mode and before FreeRtoss kernel start. But if I try to transmit inside task Not working( see below code ). Is any special code needed ?
enter code here
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN 5 */
/* Infinite loop */
for(;;)
{
HAL_UART_Transmit_IT(&huart2, hi, sizeof(hi));
osDelay(1000);
}
/* USER CODE END 5 */
}

Related

Using DMA with two UART peripherals - is it possible?

I want to connect two UART peripherals using STM32G0 microcontroller via DMA. Not knowing the length of the messages in forward, I'm using function HAL_UARTEx_ReceiveToIdle_DMA() in order to receive them. Here is the part of my code:
main.h
.
.
.
StartDMAReceptionOverUART1();
StartDMAReceptionOverUART4();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(10);
}
.
.
.
void StartDMAReceptionOverUART1(void)
{
if (HAL_UARTEx_ReceiveToIdle_DMA(m_modulePort.huart, m_modulePort.rxBuffer, m_modulePort.rxBufferSize) != HAL_OK)
{
Error_Handler();
}
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_TC);
}
void StartDMAReceptionOverUART4(void)
{
if (HAL_UARTEx_ReceiveToIdle_DMA(m_meterPort.huart, m_meterPort.rxBuffer, m_meterPort.rxBufferSize) != HAL_OK)
{
Error_Handler();
}
__HAL_DMA_DISABLE_IT(&hdma_usart4_rx, DMA_IT_HT);
__HAL_DMA_DISABLE_IT(&hdma_usart4_rx, DMA_IT_TC);
}
.
.
.
These functions are similar: first HAL_UARTEx_ReceiveToIdle_DMA() is checked, then Half Transfer and Transfer Complete interrupts are disabled in order to relieve processor (I need only IDLE interrupt). The problem is inside StartDMAReceptionOverUART1() function, HAL_UARTEx_ReceiveToIdle_DMA() never returns HAL_OK and program jumps on Error_Handler(). On the other hand, StartDMAReceptionOverUART4() works perfectly fine. What could be the problem?
Also, here is the receive callback function, also written inside main.h:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart->Instance == m_meterPort.huart->Instance) // huart == UART4
{
memcpy(m_modulePort.txBuffer, m_meterPort.rxBuffer, Size);
HAL_UART_Transmit_DMA(m_modulePort.huart, m_modulePort.txBuffer, Size);
StartDMAReceptionOverUART4();
}
else if (huart->Instance == m_modulePort.huart->Instance) // huart == UART1
{
memcpy(m_meterPort.txBuffer, m_modulePort.rxBuffer, Size);
HAL_UART_Transmit_DMA(m_meterPort.huart, m_meterPort.txBuffer, Size);
}
else
{
return;
}
}
Callback function, in dependence of the periphery, will copy received data to a buffer and send it to the other periphery (functions memcpy() and HAL_UART_Transmit_DMA()). DMA over UART4 is in Normal mode, therefore StartDMAReceptionOverUART4() is called, inside which is HAL_UARTEx_ReceiveToIdle_DMA(). On the other hand, DMA over UART1 is in Circular mode, so there is no need for calling StartDMAReceptionOverUART4().

writing data on sd card

I use a simple code in stm32 for SD card.
The code is written in "int main(void)" section. I am trying to configure a SD card so that as soon as the STM32F750vbt6 turn on, a file is created in the SD card and a text is written in the file.
when I turn the STM32F750vbt6 on, this does not happen and nothing is written in the SD card but when the code reaches to the "while" section (I have written an LED blink code inside the while section) and I reset the micro controller using RST pin of the STM32F750vbt6, the device works properly and a text is written in the sd card.
How can I fix this? Why is there a need for resetting the device for the code to work?
this is my code :
const char wtext[] = "hi world";
int main(void)
{
FRESULT res; /* FatFs function common result code */
uint32_t byteswritten, bytesread; /* File write/read counts */
MPU_Config();
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SDMMC1_SD_Init();
MX_FATFS_Init();
if(retSD == 0)
{
if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) == FR_OK)
{
if(f_open(&MyFile, "file.txt", FA_CREATE_ALWAYS | FA_WRITE) ==FR_OK)
{
f_write(&MyFile, wtext, sizeof(wtext), (void*)&byteswritten);
f_close(&MyFile);
}
}
}
FATFS_UnLinkDriver(SDPath);
while (1)
{
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
HAL_Delay(2000);
HAL_GPIO_WritePin(LED1_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
HAL_Delay(2000);
}
}
The problem was that the device did not work from the ports. The data and CMD ports must be connected as pull-up

Does HAL_NVIC_SetPendingIRQ call the ISR to execute?

I am really new to STM32 world so I came across this while reading:
void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn);
This will cause the interrupt to fire, as it would be generated by the hardware. A distinctive feature
of Cortex-M processors it that it is possible to programmatically fire an interrupt inside the ISR
routine of another interrupt.
I got this from the book Mastering STM32 (by Carmine Noviello page 208). From this I have understood that If we set this pending bit even from the main function, then the interrupt is generated.
So to try this out, I have written this code:
while (1)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
for(int i = 0; i <10000000; i++);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
for(int i = 0; i <10000000; i++);
HAL_NVIC_SetPendingIRQ(EXTI0_IRQn);
}
}
along with this call back function
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_PIN){
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
}
I have programmed GPIO_PIN_0 as source of interrupt and when I press the push button connected to PA0 the Interrupt works perfectly i.e. ISR is executed. To my surprice HAL_NVIC_SetPendingIRQ function doesn't generate interrupt. I don't understand why?
More Info:
I am using STM32F411VET6 DISCO board
I am using STM32CubeIDE to program the board
Thank you #Tagli. I have found the function HAL_GPIO_EXTI_IRQHandler inside stm32f4xx_hal_gpio.c file. Defalult definition was like this:
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
I got why the GPIO was not being toggled. It was the same reason you have commented above.
I have modified to prove it.
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
HAL_GPIO_EXTI_Callback(GPIO_Pin);
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
Now the callback function is called when the HAL_NVIC_SetPendingIRQ(EXTI0_IRQn); is being called

STM32F103 UART button event delay slow

I'm testing very basic transmission with UART1 on my STM32F103C8T6 using CUBE MX and Keil v5.
I've prepared project in CUBE MX enabling UART and went to Keil.
All is working fine to be honest, if I press button on board (PA0), transmitted string changes correctly from stringa1 to stringa2, but it stays on stringa2 for 3 or 4 cycles even if I press and release the button very quickly.
It seems like a problem of synchronization or sort of timing, in shorts, even if button has been released, HAL is sending stringa2 like I have still my finger on button PA0.
What could be the problem?
int main(void)
{
/* USER CODE BEGIN 1 */
char *stringa1 = "ciao\r\n";
char *stringa2 = "pressed\r\n";
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/*
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(500);
*/
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)){
HAL_UART_Transmit(&huart1, (uint8_t*) stringa1, strlen(stringa1), 10);
} else {
HAL_UART_Transmit(&huart1, (uint8_t*) stringa2, strlen(stringa2), 10);
}
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

uVision Led lights

This is the first time i am programming a mikrokontroler, i'm using uVison and have an stm32 to program on.,
I have two LED light on it on the pins: PIN_4 and PIN_5 with a tutorial i know how to make one blink (the code below) but i dont know how to make them bot blink with not the same delay. Like i want to make PIN_4 led be wit a delay of 100ms and PIN:5 led with a delay of 50ms. The code below is the code for one Led light.
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4); //Toggle the state of pin PC9
HAL_Delay(100); //delay 100ms
}
/* USER CODE END 3 */
}
You have 2 options.
First, you can set a timer for counting milliseconds. You can generate a code from STMCubeMX for 50ms timer. Then, in timer callback function, you should set pins to high or low.
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
timer_counter++; //50ms
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
if(timer_counter>=2) //100ms
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4);
timer_counter = 0;
}
}
Second option is that delay in main.
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5); //Toggle the state of pin PB5
HAL_Delay(50); //delay 50ms
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4); //Toggle the state of pin PB4
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5); //Toggle the state of pin PB5
HAL_Delay(50); // delay 50ms
}
/* USER CODE END 3 */
}