2019-12-11 07:05 AM
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.
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
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
2019-12-11 09:58 AM
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.