2013-12-11 01:37 PM
Hello ST Community,
I am using a STM32F2 uC for my project, and I have configured an USART interface as an UART by not initializing the clock settings. In order to program the device the UART is connected to I send commands that terminate in <CR><LF> through the interface, then this device automatically sends data without needing the uC to transmit anything else, I would only need to read the data.I have verified the communication via polling, If I execute a reading function on the infinite loop everything seems to work and I get the responses I expected. However, I need to make this reading procedure via interrupts and here is where I have encountered a few problems.I enable the RXNE interrupt and set the priority with the NVIC structure, the code jumps to the IRQ handler as expected, however it only jumps once or twice maximum and I can't read the whole response. It's also worth noting thata the characters I read are equal to the first characters I expect from a response from the device, so I believe there is something wrong with the way I am managing this interrupt.My starting point is an example on the Standard Peripherial Library manual where it explains the procedure to set an interrupt on the USART3 interface. I have also tried to use my polling loop on the IRQ handler function with no success.Any help or directions are appreciated, thanks in advance! #usart-tx-rx-interrupt-rxne-uart2013-12-11 01:47 PM
// STM32 USART IRQ TX/RX Loop (USART3 Tx PD.8, Rx PD.9) STM32F2 - sourcer32@gmail.com
#include ''stm32f2xx.h''
volatile char StringLoop[] = ''The quick brown fox jumps over the lazy dog
'';
/**************************************************************************************/
void RCC_Configuration(void)
{
/* --------------------------- System Clocks Configuration -----------------*/
/* USART3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
/* GPIOD clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*-------------------------- GPIO Configuration ----------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Connect USART pins to AF */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3);
}
/**************************************************************************************/
void USART3_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USARTx configuration ------------------------------------------------------*/
/* USARTx configured as follow:
- BaudRate = 9600 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);
USART_ITConfig(USART3, USART_IT_RXNE | USART_IT_TXE, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USART3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void USART3_IRQHandler(void)
{
static int tx_index = 0;
static int rx_index = 0;
if (USART_GetITStatus(USART3, USART_IT_TXE) != RESET) // Transmit the string in a loop
{
USART_SendData(USART3, StringLoop[tx_index++]);
if (tx_index >= (sizeof(StringLoop) - 1))
tx_index = 0;
}
if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) // Received characters modify string
{
StringLoop[rx_index++] = USART_ReceiveData(USART3);
if (rx_index >= (sizeof(StringLoop) - 1))
rx_index = 0;
}
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
USART3_Configuration();
while(1); // Don't want to exit
}
/**************************************************************************************/
2013-12-11 02:13 PM
Thank you clive1, that code clears things out a bit. Tomorrow I will implement something similar in my project and see if it works.
2013-12-12 03:51 AM
I used your code to develop one of my own to suit my needs and now I finally have working reading code via the RXNE interrupt.
I wonder if you could help me with another issue regarding this... in case I wanted to do hardware flow control, would this same IRQ handler you provided work if I used the RTS and CTS signals?