STM32 UART help - don't know what I am doing! - Page 1
Forum section: electronics / general

author: alank2
author_rank: Super Contributor
timestamp: June 29, 2017, 02:15:53 am
content: I've looked at a few examples, but so far not getting it working.I have it successfully transmitting a 0. I'm trying to get it to receive now.After reading:https://electronics.stackexchange.com/questions/266918/stm32f031k6-hal-uart-interrupts-problemThe answer suggests having to call HAL_UART_Receive_IT(&huart1, uint8_t *pData, uint16_t size) which I don't understand. I am familiar with AVR and an interrupt would fire, do what it needs to do, and then you could check variables it changed to see what has happened or retrieve bytes from a ring buffer. Why call this function? Is it blocking?I don't think it gets called because it always outputs 0's and doesn't change aTxBuffer to a '1'...I added the void USART5_IRQHandler() function because of the link above, but it did not have any effect....Code:/********************************************************************************* File Name : USART.c* Description : This file provides code for the configuration* of the USART instances.******************************************************************************** COPYRIGHT(c) 2017 STMicroelectronics** Redistribution and use in source and binary forms, with or without modification,* are permitted provided that the following conditions are met:* 1. Redistributions of source code must retain the above copyright notice,* this list of conditions and the following disclaimer.* 2. Redistributions in binary form must reproduce the above copyright notice,* this list of conditions and the following disclaimer in the documentation* and/or other materials provided with the distribution.* 3. Neither the name of STMicroelectronics nor the names of its contributors* may be used to endorse or promote products derived from this software* without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.********************************************************************************//* Includes ------------------------------------------------------------------*/#include "usart.h"#include "gpio.h"/* USER CODE BEGIN 0 *//* USER CODE END 0 */UART_HandleTypeDef huart4;UART_HandleTypeDef huart5;UART_HandleTypeDef huart7;/* UART4 init function */void MX_UART4_Init(void){huart4.Instance = UART4;huart4.Init.BaudRate = 115200;huart4.Init.WordLength = UART_WORDLENGTH_8B;huart4.Init.StopBits = UART_STOPBITS_1;huart4.Init.Parity = UART_PARITY_NONE;huart4.Init.Mode = UART_MODE_TX_RX;huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart4.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart4) != HAL_OK){Error_Handler();}}/* UART5 init function */void MX_UART5_Init(void){huart5.Instance = UART5;huart5.Init.BaudRate = 115200;huart5.Init.WordLength = UART_WORDLENGTH_8B;huart5.Init.StopBits = UART_STOPBITS_1;huart5.Init.Parity = UART_PARITY_NONE;huart5.Init.Mode = UART_MODE_TX_RX;huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart5.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart5) != HAL_OK){Error_Handler();}}/* UART7 init function */void MX_UART7_Init(void){huart7.Instance = UART7;huart7.Init.BaudRate = 115200;huart7.Init.WordLength = UART_WORDLENGTH_8B;huart7.Init.StopBits = UART_STOPBITS_1;huart7.Init.Parity = UART_PARITY_NONE;huart7.Init.Mode = UART_MODE_TX_RX;huart7.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart7.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart7) != HAL_OK){Error_Handler();}}void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle){GPIO_InitTypeDef GPIO_InitStruct;if(uartHandle->Instance==UART4){/* USER CODE BEGIN UART4_MspInit 0 *//* USER CODE END UART4_MspInit 0 *//* Peripheral clock enable */__HAL_RCC_UART4_CLK_ENABLE();/**UART4 GPIO ConfigurationPA0/WKUP ------> UART4_TXPC11 ------> UART4_RX*/GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF8_UART4;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_11;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF8_UART4;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/* Peripheral interrupt init */HAL_NVIC_SetPriority(UART4_IRQn, 5, 0);HAL_NVIC_EnableIRQ(UART4_IRQn);/* USER CODE BEGIN UART4_MspInit 1 *//* USER CODE END UART4_MspInit 1 */}else if(uartHandle->Instance==UART5){/* USER CODE BEGIN UART5_MspInit 0 *//* USER CODE END UART5_MspInit 0 *//* Peripheral clock enable */__HAL_RCC_UART5_CLK_ENABLE();/**UART5 GPIO ConfigurationPC12 ------> UART5_TXPD2 ------> UART5_RX*/GPIO_InitStruct.Pin = GPIO_PIN_12;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF8_UART5;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_2;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF8_UART5;HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);/* Peripheral interrupt init */HAL_NVIC_SetPriority(UART5_IRQn, 5, 0);HAL_NVIC_EnableIRQ(UART5_IRQn);/* USER CODE BEGIN UART5_MspInit 1 *//* USER CODE END UART5_MspInit 1 */}else if(uartHandle->Instance==UART7){/* USER CODE BEGIN UART7_MspInit 0 *//* USER CODE END UART7_MspInit 0 *//* Peripheral clock enable */__HAL_RCC_UART7_CLK_ENABLE();/**UART7 GPIO ConfigurationPF6 ------> UART7_RXPF7 ------> UART7_TX*/GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF8_UART7;HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);/* Peripheral interrupt init */HAL_NVIC_SetPriority(UART7_IRQn, 5, 0);HAL_NVIC_EnableIRQ(UART7_IRQn);/* USER CODE BEGIN UART7_MspInit 1 *//* USER CODE END UART7_MspInit 1 */}}void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle){if(uartHandle->Instance==UART4){/* USER CODE BEGIN UART4_MspDeInit 0 *//* USER CODE END UART4_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_UART4_CLK_DISABLE();/**UART4 GPIO ConfigurationPA0/WKUP ------> UART4_TXPC11 ------> UART4_RX*/HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);HAL_GPIO_DeInit(GPIOC, GPIO_PIN_11);/* Peripheral interrupt Deinit*/HAL_NVIC_DisableIRQ(UART4_IRQn);/* USER CODE BEGIN UART4_MspDeInit 1 *//* USER CODE END UART4_MspDeInit 1 */}else if(uartHandle->Instance==UART5){/* USER CODE BEGIN UART5_MspDeInit 0 *//* USER CODE END UART5_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_UART5_CLK_DISABLE();/**UART5 GPIO ConfigurationPC12 ------> UART5_TXPD2 ------> UART5_RX*/HAL_GPIO_DeInit(GPIOC, GPIO_PIN_12);HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);/* Peripheral interrupt Deinit*/HAL_NVIC_DisableIRQ(UART5_IRQn);/* USER CODE BEGIN UART5_MspDeInit 1 *//* USER CODE END UART5_MspDeInit 1 */}else if(uartHandle->Instance==UART7){/* USER CODE BEGIN UART7_MspDeInit 0 *//* USER CODE END UART7_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_UART7_CLK_DISABLE();/**UART7 GPIO ConfigurationPF6 ------> UART7_RXPF7 ------> UART7_TX*/HAL_GPIO_DeInit(GPIOF, GPIO_PIN_6|GPIO_PIN_7);/* Peripheral interrupt Deinit*/HAL_NVIC_DisableIRQ(UART7_IRQn);/* USER CODE BEGIN UART7_MspDeInit 1 *//* USER CODE END UART7_MspDeInit 1 */}}//variables need to be declared at the beginningvolatile char Rx_indx, Rx_data, Rx_Buffer, Transfer_cplt;volatile uint8_t aTxBuffer[] = "0123456789abcdef";void uart_task(){MX_UART4_Init();MX_UART5_Init();MX_UART7_Init();HAL_UART_Receive_IT(&huart5, Rx_data, 1);//activate UART receive interrupt every timewhile(1){//HAL_UART_Transmit(&huart4, (uint8_t*)aTxBuffer, 16, 5000);HAL_GPIO_WritePin(RS485_DIR_GPIO_Port, RS485_DIR_Pin, GPIO_PIN_SET);//HAL_UART_Transmit(&huart5, (uint8_t*)aTxBuffer, 16, 5000);if (Transfer_cplt){HAL_UART_Transmit(&huart5, (uint8_t*)Rx_Buffer, strlen(Rx_Buffer), 5000);Transfer_cplt=0;}else HAL_UART_Transmit(&huart5, (uint8_t*)aTxBuffer, 1, 5000);HAL_GPIO_WritePin(RS485_DIR_GPIO_Port, RS485_DIR_Pin, GPIO_PIN_RESET);//HAL_UART_Transmit(&huart7, (uint8_t*)aTxBuffer, 16, 5000);vTaskDelay(pdMS_TO_TICKS(1000));printf("x");}}/* USER CODE BEGIN 1 */void USART5_IRQHandler(){HAL_UART_IRQHandler(&huart5);}//Interrupt callback routinevoid HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){uint8_t i;aTxBuffer='1';if (huart->Instance == UART5)//current UART{if (Rx_indx==0){for (i=0;i<100;i++)Rx_Buffer=0;}//clear Rx_Buffer before receiving new dataif (Rx_data!=13)//if received data different from ascii 13 (enter){Rx_Buffer[Rx_indx++]=Rx_data;//add data to Rx_Buffer}else//if received data = 13{Rx_indx=0;Transfer_cplt=1;//transfer complete, data is ready to read}HAL_UART_Receive_IT(&huart5, Rx_data, 1);//activate UART receive interrupt every time}}/* USER CODE END 1 *//*** @}*//*** @}*//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

author: colorado.rob
author_rank: Frequent Contributor
timestamp: June 29, 2017, 03:15:28 am
content: What board are you using?Have you looked at the USART example programs from ST?Are you using STM32CubeMX to generate code or are you coding this all by hand?HAL_UART_Receive_IT() is non-blocking. You call it and it enables the interrupt and tells the low-level interrupt handler where to store the data it receives. The completion handler will be called when "size" bytes have been stored in pData[]. At that point you move the data into a different buffer, raise a flag that there is data, then re-enable the interrupt.Outside of the interrupt, you poll the flag waiting for data, then read the data once it is set. (In the real world you use an RTOS and use semaphores or some other signalling mechanism.)

author: alank2
author_rank: Super Contributor
timestamp: June 29, 2017, 03:20:29 am
content: 1) Customer designed PCB. I am adding a feature to it.2) No - where can I find them?3) I saw a YouTube video where someone did this, but I only have Atollic TrueStudio installed.4) I think I am doing what you suggest in the code - can you take a quick look at it to see if I missed something?Thanks for the help!

author: colorado.rob
author_rank: Frequent Contributor
timestamp: June 29, 2017, 03:32:31 am
content: There is example code all over ST's site. Find the chip you're working on. Look at all of the development tools, evaluation tools, and software. Most of the examples are geared towards running them on one of their dozens of dev boards. Buy one closest to the MCU you're working on. They're like $10. Then go through the examples for the dev board.

author: Gibson486
author_rank: Frequent Contributor
timestamp: June 29, 2017, 01:18:26 pm
content: There are plenty of tutorials on how to integrate cubemx into Atollic.There are also plenty of tutorials on how to get serial working as well with cubemx.

author: alexanderbrevig
author_rank: Frequent Contributor
timestamp: June 29, 2017, 01:30:31 pm
content: You have wrong length in transmit, you only send "0".

author: alank2
author_rank: Super Contributor
timestamp: June 29, 2017, 02:00:39 pm
content: Quote from: alexanderbrevig on June 29, 2017, 01:30:31 pmI know - I changed it on purpose to lower the quantity sent.It sounds like I need to make a new project for a dev board and get that working first, and then try to adapt it over. I've got a few dev boards so I can try that.

author: colorado.rob
author_rank: Frequent Contributor
timestamp: June 29, 2017, 04:53:51 pm
content: I would also recommend starting with the blocking version of the code (HAL_UART_Receive()) rather than the interrupt-driven ones. It's much easier to verify that the UART configuration is correct and that it can actually receive data without worrying about interrupt handlers, timing, bounce buffers, etc.

author: alank2
author_rank: Super Contributor
timestamp: June 29, 2017, 05:35:28 pm
content: Thanks Rob, that is a good idea, I'll try that!

author: seec
author_rank: Newbie
timestamp: July 02, 2017, 05:16:09 am
content: void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle){__HAL_UART_FLUSH_DRREGISTER(UartHandle); // try this}

author: alank2
author_rank: Super Contributor
timestamp: July 04, 2017, 12:11:44 am
content: Thanks everyone; I did get it all working.