cancel
Showing results for 
Search instead for 
Did you mean: 

Hlo all, i'm trying to receive data over uart and something weird happens every time i try to receive the data, my buf variable always stays empty. can anyone suggest me the solution. I am attaching my code for your reference.

RChou.1
Associate III
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
//#include "stm32f4xx.h"
#include "stm32f411xe.h"
#include "uart.h"
 
#define GPIOAEN           (1U<<0)
#define PIN5              (1U<<5)
#define LED_PIN           PIN5
 
 
char key;
 char *token;
 
volatile int idx = 0,alpha=0;
  char * buf;
 int len=80;
 
int main(void){
 
 
	RCC->AHB1ENR |= GPIOAEN;
	GPIOA->MODER |= (1U<<10);
	GPIOA->MODER &=~ (1U<<11);
 
	uart2_rx__interrupt_init();
 
 
 
	while(1){
		if(alpha == 2){
			
			token = strtok(buf,",");
			if (strcmp(token,"ON")==0)
			{
				GPIOA->ODR |= LED_PIN;
			}
			
			   alpha=0;
 
			 }
 
 
	}
}
 
 
 
void USART2_IRQHandler(void)
{
	/*Check if RXNE is set*/
	if(USART2->SR & SR_RXNE)
	{
		//uart_callback();
		while(USART2->DR)
		{
			char c = USART2->DR;
 
					if (c == '\0')
					{
						continue;
					}
					if (c == ',')
					{
						alpha=2;
						//GPIOA->ODR ^= LED_PIN;
					}
					/*if it is RET or NL..*/
					if ((c == '\r') || (c == '\n'))
					{
						break;
					}
					// else store the received character
					buf[idx] = c;
					// increment the index
					idx++;
					// if reached the end (with room for final 0x00) break
					if (idx == (len - 1))
					{
						break;
					}
		}
		buf[idx] = 0x00;
		idx=0;
	}
 
 
}
 

5 REPLIES 5
Bob S
Principal

You don't mention which CPU and don't show your init code. But still, your code has several issues.

You declare buf as "char *", but you never allocate memory for it to point to. So it points to 0x00000000 (since the "C" startup code zeros all global uninitialized variables). Declare it as "char buf[80]" or something like that.

In your IRQ function:

while(USART2->DR)

reads the incoming data from DR and now the contents of DR are undefined. It MAY (probably) still hold a copy of the data, or it ay hold the NEXT byte if your CPU is slow enough responding to the interrupt. Your IRQ loop will read that same value multiple (MANY) times until you fill the buffer. Loop on RXNE not DR.

RChou.1
Associate III
void uart2_rx__interrupt_init(void){
	/********Configure uart gpio pin********/
	/*Enable clock access to gpio*/
	RCC->AHB1ENR |= GPIOAEN;
 
	/*Set pa2 to alternate function mode*/
	GPIOA->MODER &=~(1U<<4);
	GPIOA->MODER |=(1U<<5);
 
	/*Set PA2 alternate function type to UART_TX (AF07)*/
	/*to activate alternate function on PA2(Uart TX pin) the logic is 0111
	 * so for PA2 i have to select AFRL2 and AFRL2 has bits that are 11,10,9 & 8*/
	GPIOA->AFR[0] |= (1U<<8);
	GPIOA->AFR[0] |= (1U<<9);
	GPIOA->AFR[0] |= (1U<<10);
	GPIOA->AFR[0] &=~ (1U<<11);
 
	/*Set pa3 to alternate function mode*/
	GPIOA->MODER &=~(1U<<6);
	GPIOA->MODER |=(1U<<7);
	/*Set PA3 alternate function type to UART_RX (AF07)*/
	GPIOA->AFR[0] |= (1U<<12);
	GPIOA->AFR[0] |= (1U<<13);
	GPIOA->AFR[0] |= (1U<<14);
	GPIOA->AFR[0] &=~ (1U<<15);
 
	/**********Configure uart module**********/
	/*Enable clock access to uart2*/
	RCC->APB1ENR |= UART2EN;
	/*Configure the baudrate*/
	uart_set_baudrate(USART2,APB1_CLK,USART_BAUDRATE);
	/*Configure the transfer direction*/
	USART2->CR1 = CR1_TE | CR1_RE;
	/*Enable RXNE interrupt*/
	USART2->CR1 |= CR1_RXNEIE;
 
	/*Enable uart2 interrupt in NVIC*/
	NVIC_EnableIRQ(USART2_IRQn);
 
	/*Enable uart module*/
	USART2->CR1 |= CR1_UE;
	/**/
}
 
char uart2_read(void){
	/*Make sure the receive data register is empty*/
		while(!(USART2->SR & SR_RXNE)){}
		return USART2->DR;
}

Sorry for being late for this reply, I have given the init as well as my uart2_read methods.

And i didn't get your point can you please elaborate.

> And i didn't get your point can you please elaborate.

You interrupt callback doesn't do what you think it does. To test it, use PuTTY or some other program where you can send 1 character at a time to your STM32. Set a breakpiont in your callback on the line that checks RXNE (line 54 in your first post). Then send a single letter "A" (or whatever letter you like). Then single step through your callback function and see how many times it stores that letter in your buffer. The "while (UART2->DR)" line is not correct, among other things.

If it still doesn't make sense, look at the HAL UART example programs that use interrupt receive and see how they do it.

Thanks for your support, it is working now. It was just a simple mistake.

These forums work best when people post the actual solutions. That helps others who may face a similar issue.

So @RChou.1​ , what was your fix?