How to send and receive message through UART interrupt or DMA?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-08 4:47 AM
< What I want to do? >
- Send string messages(AT command) from STM32 microcontroller to LTE module through UART, receive the reply, and store the received data in a string variable.
- I tried HAL_UART_Receive function and it works. However, it doesn't complete the job until duration set in the timeout param passes, even if all the bytes are received. I want CPU to move to next job right after receiving all the bytes.
*My Mother tongue is not English. If what I'm writing here is not understandable, let me know. I will fix sentences properly.
< Environment >
- Nucleo-L053R8
- 3G module(HL8548-G)
- The Nucleo-L053R8 and the 3G module should be connected properly.
< What I tried? >
- I looked through discussion on some websites and figured out that taking one byte by one from the buffer by HAL_UART_Receive_IT or HAL_UART_Receive_DMA is needed. Then I implemented the below code. However, it does not work well. I'm struggling for this problem for two weeks. I appreciate it if you give me any advice.
- Settings: 32MHz, using HAL_UART_Receive_DMA(115200baud, Circular mode, no interrupt), and a timer(prescaler:100-1, counter period:320, interrupt, 1msec interruption),
- How the below code works
- Initialize UART, timer, and printf function.
- (In Func_3G_Comm func)Send string stored in txBuf by HAL_UART_Transmit.
- (In Func_3G_Comm func)Enable HAL_UART_Receive_DMA(&huart1, (uint8_t*)&rxBuf_IT, 1);.
- (In Func_3G_Comm func)Enter sleep mode.
- (In HAL_UART_RxCpltCallback func)When one byte is received, stop a timer, store it in rxBuf, and start the timer again.
- (In HAL_TIM_PeriodElapsedCallback func)When 1msec passes after the last byte is received, this func is called. This means no byte will be received. Set rxFlag = 1.
- (In Func_3G_Comm func)Break for loop by rxFlag = 1. Print string in rxBuf
- The step 7 does not work. Just "AT" characters show up and only blank later.
- I don't know using DMA is the good way.
extracts from main.c
#include "main.h"
#include "stm32l0xx_hal.h"
TIM_HandleTypeDef htim2;
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
#define txBuf_size 512
#define rxBuf_size 128
char txBuf[txBuf_size];
char rxBuf[rxBuf_size];
char superRxBuf[2000];
uint8_t rxFlag = 0;
uint16_t rxIndex = 0;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM2_Init(void);
void Func_3G_Comm(char *Cmd);
extern void initialise_monitor_handles(void);
int main(void)
{
initialise_monitor_handles(); // Initialize printf func
HAL_Init();
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_TIM2_Init();
/* Perform the initial configuration in 3G module */
Func_3G_Comm("AT&K3"); // Set hardware flow control
Func_3G_Comm("AT+KTCPCLOSE=1"); // Close TCP1 connection
Func_3G_Comm("AT+KTCPDEL=1"); // Close Delete TCP1 connection
Func_3G_Comm("AT+GPSSTOP"); // Stop GPS
Func_3G_Comm("AT+GPSNMEA=01,,0"); // Stop receiving GPS NMEA data
Func_3G_Comm("AT+CGATT=0"); // PS detachment
Func_3G_Comm("AT+KCNXCFG=1,\"GPRS\",\"***.com\",\"***.com\",\"***\""); // Configure TCP Connection
Func_3G_Comm("AT+CGDCONT=4,\"IP\",\"***.com\""); // Configure GPRS
Func_3G_Comm("AT+KCNXPROFILE=1"); // Configure current profile connection
Func_3G_Comm("AT+KGNSSAD=1"); // Configure GNSS antenna detection
Func_3G_Comm("AT+CGATT=1"); // PS attachment
Func_3G_Comm("AT+KTCPCFG=1,0,\"xxxxxx.com\",16650"); // Configure TCP Connection
Func_3G_Comm("AT+KCNXUP=1"); // Bring up PDP connection
Func_3G_Comm("AT+KTCPCNX=1"); // Start TCP connection
while (1)
{
}
}
/* USART1 init function */
static void MX_USART1_UART_Init(void)
{
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_RTS_CTS;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* Enable DMA controller clock */
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel2_3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
}
void Func_3G_Comm(char *Cmd)
{
memset(txBuf, '\0', txBuf_size);
memset(rxBuf, '\0', rxBuf_size);
snprintf(txBuf, txBuf_size, "%s\r\n", Cmd);
HAL_UART_Transmit(&huart1, (uint8_t *)txBuf, strlen(txBuf), 0xFFFF);
HAL_UART_Receive_DMA(&huart1, (uint8_t*)&rxBuf_IT, 1);
HAL_SuspendTick();
for(rxFlag=0;rxFlag==0;)
{
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
HAL_ResumeTick();
HAL_TIM_Base_Stop_IT(&htim2);
printf("%s\n",rxBuf);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
HAL_TIM_Base_Stop_IT(&htim2);
if(UartHandle->Instance==USART1){
rxBuf[rxIndex] = rxBuf_IT;
rxIndex++;
}
HAL_TIM_Base_Start_IT(&htim2);
HAL_UART_Receive_DMA(&huart1, (uint8_t*)&rxBuf_IT, 1);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2) {
rxFlag = 1;
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
}
}
extracts from stm32l0xx_it.c
void DMA1_Channel2_3_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_usart1_rx);
}
void TIM2_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim2);
}
*modification: Func_3G_Comm => LTE_Comm
- Labels:
-
Interrupt
-
STM32L0 Series
-
TIM
-
UART-USART
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-10 5:02 AM
>>TJ
I'm new to STM32 .
I think once HAL_TIM_Base_Stop_IT(&htim2) in line 105, and 111 is called, timer is reset. Isn't this correct?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-10 5:04 AM
>>Clive Two.Zero
You're right. I will use interrupt, not DMA.
Does anyone have advice on how to get to know the end of messages on interrupt?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-10 5:11 AM
Depends if the data stream has a defined form or if you have to sense and intermessage gap.​
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
‎2018-11-15 1:32 PM
I felt, what suggested by "AvaTar" is the appropriate design for this kind of application.
- ISR
- Buffer between ISR and main loop
- State machine in main loop
- Timeouts if response(s) are not received in stipulated time
- Retries, if response(s) are not received in stipulated time
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-02-26 4:53 AM
HI yusukechief1.5356023809566858E12 ,
As I'm working on same topic, receiving response for AT commands from GSM module through stm32 uart. I'm facing issue since 3 weeks. It will really help full of you could share the code of yours for my reference.. Please help me on this.
mail address:shashishreekuppurmce@gmail.com
Thank you in advance
shashishree
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-02-26 8:09 AM
You could receive data from uart by dma in a cyclic buffer, and every 1 msec, by interrupt, you check what was received so far. Or you create rx interrupt on per byte basis and manually fill the buffer, while detecting when a message has been fully received and ready for processing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-02-26 8:37 AM
Thank you ill try woth your suggestion
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-02-26 9:41 AM

- « Previous
-
- 1
- 2
- Next »