2014-07-15 08:19 AM
Hello again.
I've two usarts in use on my board. One, Usart1 is connected to the console and the other usart2 is connected to a modem chip. When I enable the usart2 interrupt using the NVIC commands, there is no output to the console from usart1 and when I comment the usart2 NVIC commands, output to the console is normal but then usart2 interrupt handling is disabled. I need both working simultaneously. It looks as if there is some sort of priority contention. Both usarts are fine individually as their handlers are being activated. Any help greatly appreciated. Dave void Usart1Init(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE); /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); 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_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); COMInit(COM1, &USART_InitStructure); } PUTCHAR_PROTOTYPE { /* Place your implementation of fputc here */ /* e.g. write a character to the USART */ while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // Wait for Empty USART_SendData(USART1,(u8)ch); return ch; } void Usart2Init(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // Enable GPIOA clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); // Enable USART2 APB clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // USART2 IRQ Channel configuration NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // Doesn't look as if I need these // RCC_APB1PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; 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(USART2, &USART_InitStructure); USART_ITConfig(USART2, USART_IT_TXE, ENABLE); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); USART_Cmd(USART2, ENABLE); } void USART2_IRQHandler(void) { uint8_t rx_byte = 0; static int rx_count = 0; if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { rx_byte = USART_ReceiveData(USART2); rx_buf[rx_count++] = rx_byte; if (rx_count >= (sizeof(rx_buf) - 1)) rx_count = 0; } }2014-07-15 08:38 AM
Don't enable TXE interrupts unless you plan on servicing them with data.
2014-07-15 09:46 AM
Hello Clive,
Do you mean...unless I am sending data in the USART2_Handler, then I should keep this disabled? I am sending strings to the modem just not through the handler. Dave2014-07-15 10:43 AM
So why enable the interrupt?
Understand that the interrupt will keep re-entering, indefinitely, if the TXE status bit is asserted, and you have the interrupt enabled. If you do not supply it with data, it will never clear, and your foreground code will never get to execute.