cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 - Problem with UART Receiver

MW9501
Associate

Hello

I'm trying to communicate STM32F411RE (NUCEO board) with SIM800L module through the USART interface.

I made USART initialization by HAL driver but I want to communicate manually by referring to the registers directly.

USART Initialization:

void uart_init(uint32_t baud)
{
	uart_gpio.Pin = GPIO_PIN_9 | GPIO_PIN_10; //TX RX
	uart_gpio.Mode = GPIO_MODE_AF_PP;
	uart_gpio.Alternate = GPIO_AF7_USART1;
	uart_gpio.Speed = GPIO_SPEED_HIGH;
	uart_gpio.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(GPIOA,&uart_gpio);
 
	usart.Instance = USART1;
	usart.Init.BaudRate = baud;
	usart.Init.Parity = USART_PARITY_NONE;
	usart.Init.StopBits = USART_STOPBITS_1;
	usart.Init.WordLength = USART_WORDLENGTH_8B;
	usart.Init.Mode = USART_MODE_TX_RX;
	HAL_USART_Init(&usart);
}
int main(void)
{
	HAL_Init();
 
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();
	__HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_USART1_CLK_ENABLE();
    	__HAL_RCC_TIM5_CLK_ENABLE();
  
  	timers_init();
	interrupt_init();
  	uart_init(9600);
  	
   	while(1)
	{
 
	}
}

Communication takes place in the interrupt from timer, in function "sim_reception". It's simple reading flags from USART Status Register and send/receive data.

I send data byte by byte, I load command into a tx buffer through my function "sim_tx_buf_put". After one send I'm calling my function "sim_byte_up" to shift all bytes in tx buffer up and send next byte. I'm sending very simple command "AT\r\n", to which I should get an answer.

I will not describe or insert code of functions, they work fine. I have only problem with receiver...

Main function:

#define SIM_TX_BUF_SIZE		32
#define SIM_RX_BUF_SIZE		32
 
unsigned char sim_tx_buf[SIM_TX_BUF_SIZE];
unsigned char sim_rx_buf[SIM_RX_BUF_SIZE];
unsigned char sim_tx_len = 0;
unsigned char sim_rx_len = 0;
 
#define SIM_HNDSHK			"AT\r\n"
enum { handshake, hdsh_resp };
unsigned char sim_states = handshake;
 
void sim_reception(void)
{
        //RX
	while(USART1 -> SR & USART_SR_RXNE)
	{
		if(sim_rx_len < SIM_RX_BUF_SIZE)
			sim_rx_buf[sim_rx_len++] = USART1 -> DR; 
		else
			break;
	}
 
	//TX
	while(USART1 -> SR & USART_SR_TXE)
	{
		if(sim_tx_len != 0)
		{
			USART1 -> DR = sim_tx_buf[0];
			sim_byte_up(sim_tx_buf);	
		}
		else
			break;
	}
        
        switch(sim_states)
	{
		case handshake:
			sim_tx_buf_put(SIM_HNDSHK);
 
			sim_states = hdsh_resp;
			break;
 
		case hdsh_resp:
 
			break;
         }
}

Transmitter works perfectly, I can send whole commands. As you can see I send one command and waiting for response.

0690X00000AtT5yQAF.png

As seen at the screenshot from logic analyzer after command "AT\r\n" SIM module send response.

But receiver in STM can't see it...

Screens from debugger

0690X00000AtT71QAF.png0690X00000AtT76QAF.png

Microprocessor receive only one byte of value 127.

I have no idea what could be wrong.

Does anyone have any ideas?

I would be very grateful for help.

mw

1 REPLY 1

I'd probably use a proper ring buffer.

Watch for other error status on the USART blocking reception.

Don't inspect the USART registers from the debugger.

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