Hi everyone
I need help understanding what I am doing wrong.
I would like my buffers to work properly, but when I run the program my terminal starts sending all sorts of strange characters.
I use stm32f411e-Disco
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-03-12 10:00 AM
#define UART_RX_BUF_SIZE 20
#define UART_TX_BUF_SIZE 20
int8_t uart_put_char(char data);
int8_t uart_get_char(char *data);
volatile char uart_rxBuff[UART_RX_BUF_SIZE];
volatile char uart_txBuff[UART_TX_BUF_SIZE];
void uart_put_string(char *s);
typedef struct {
volatile char *const buffer;
uint8_t head;
uint8_t tail;
} circ_buffer_t;
volatile circ_buffer_t uart_rx_circBuff = { uart_rxBuff, 0, 0 };
volatile circ_buffer_t uart_tx_circBuff = { uart_txBuff, 0, 0 };
int8_t uart_put_char(char data) {
uint8_t head_temp = uart_tx_circBuff.head + 1;
if (head_temp == UART_TX_BUF_SIZE)
head_temp = 0;
if (head_temp == uart_tx_circBuff.tail)
return 0; //0
uart_tx_circBuff.buffer[head_temp] = data;
//uart_tx_circBuff.buffer[uart_tx_circBuff.head] = data;
uart_tx_circBuff.head = head_temp;
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE);
return 0;
}
int8_t uart_get_char(char *data) {
if (uart_rx_circBuff.head == uart_rx_circBuff.tail)
return -1;
uart_rx_circBuff.tail++;
if (uart_rx_circBuff.tail == UART_RX_BUF_SIZE)
uart_rx_circBuff.tail = 0;
*data = uart_rx_circBuff.buffer[uart_rx_circBuff.tail];
return 0;
}
void uart_put_string(char *s) {
while (*s)
uart_put_char(*s++);
}
void USART1_IRQHandler( void ) {
HAL_UART_IRQHandler(&huart1);
//if ( __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE) != RESET) {
if(UART_IT_RXNE !=RESET){
uint8_t head_temp = uart_rx_circBuff.head + 1;
if (head_temp == UART_RX_BUF_SIZE)
head_temp = 0;
if (head_temp == uart_rx_circBuff.tail) {
//USART_ClearITPendingBit(&huart1, USART_IT_RXNE);
__HAL_UART_CLEAR_FLAG(&huart1, UART_IT_RXNE);
}
else {
HAL_UART_Receive_IT(&huart1,
(uint8_t*) &uart_rx_circBuff.buffer[head_temp], 1);
uart_rx_circBuff.head = head_temp;
}
}
//if ( __HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE) != RESET) {
if(UART_IT_TXE !=RESET){
if (uart_tx_circBuff.head == uart_tx_circBuff.tail) {
__HAL_UART_DISABLE_IT(&huart1, UART_IT_TXE);
} else {
uart_tx_circBuff.tail++;
if (uart_tx_circBuff.tail == UART_TX_BUF_SIZE)
uart_tx_circBuff.tail = 0;
HAL_UART_Transmit_IT(&huart1,
(uint8_t*) &uart_tx_circBuff.buffer[uart_tx_circBuff.tail],
1);
}
}
}
int main(void) {
/* USER CODE BEGIN 1 */
/* 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();
MX_TIM10_Init();
/* USER CODE BEGIN 2 */
uint8_t head_temp = uart_rx_circBuff.head + 1;
HAL_UART_Receive_IT(&huart1,(uint8_t*) &uart_rx_circBuff.buffer[head_temp], 1);
uart_rx_circBuff.head = head_temp;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
uart_put_string("abcdefxxxxxxxxxx");
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
}
//Configuration
/*
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
*/
- Labels:
-
STM32F4 Series
-
UART-USART
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-03-12 10:07 AM
Lot of mixed methods there. Decide if you're using callbacks, or not, then stop calling the HAL IRQ Handler if you're going to service the UART directly.
Can you output data in a normal polled method, and does that look good? If not check the HSE_VALUE is consistent with 8 MHz clock on the board.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-03-12 11:16 PM
Only receive is started in main. You'll need an interrupt before anything's transmitted. The interrupt may be receive, or any other interrupt enabled by HAL_UART_Receive_IT
Your USART1_IRQHandler calls HAL_UART_IRQHandler, which checks the interrupt status register to determine what conditions it needs to service. You should register callbacks that HAL_UART_IRQHandler will call for the conditions you care about.
Your interrupt code wouldn't work correctly anyway as the UART_IT_RXNE and UART_IT_TXE macros can never equal the RESET macro and so it'd be calling HAL_UART_Receive_IT and HAL_UART_Transmit_IT spuriously.
Your loop at the bottom of main keeps the transmit buffer full. If the strange characters are in "abcdefxxxxxxxxxx" that'll be part why.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-03-15 05:07 PM
So what should I write instead of this "if(UART_IT_RXNE !=RESET){" and this " if(UART_IT_TXE !=RESET){" ???
when I add in while this :
________________________________
While(1)
{
char downloaded;
uart_get_char(&downloaded);
if(downloaded == '!' ){
uart_put_string("abcdefxxxxxxxxxx");
}
}
_____________________________________
I send twenty times '!' (because my buf has 20 size and then I received this(picture below). When I removed this:
//void USART1_IRQHandler( void ) {
//HAL_UART_IRQHandler(&huart1);
and insert this:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
nothing was displayed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-03-15 06:32 PM
when i insert :
void USART1_IRQHandler( void ) {
HAL_UART_IRQHandler(&huart1);
}
uint8_t byte;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1)
{
HAL_UART_Transmit(&huart1, &byte, 1, 100);
HAL_UART_Receive_IT(&huart1, &byte, 1);
}
}
and in main:
HAL_UART_Receive_IT(&huart1, &byte, 1);
everything is fine. it gets the same characters as I am sending.
I don't know how to write code in such a way that it works in a circular buffer on interrupts
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-03-15 06:38 PM
>So what should I <snip>?
You'll need to decide
- stumble until it works and remain a hack
- read ST's code you're calling, read code broadly and improve your mastery
In your Drivers\STM32F4xx_HAL_Driver\Src folder, read stm32f4xx_hal_uart.c. Read how its IRQ function calls the callback functions, e.g. HAL_UART_RxCpltCallback? See how they're declared __weak? Google that. Code your own callbacks, pertinent to your implementation, to replace them.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-03-15 10:22 PM
Verify your baudrate - output 0x55 ('U') and measure but duration using oscilloscope/LA.
JW