cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with interupt-configuration

johnjohn9104
Associate II
Posted on July 19, 2012 at 15:50

Hello,

in my Application I have got a LED which is toggled by Timer2. When only this timer is running, the output level of the I/O pin is 3V when high. When I additionaly activate the USART interrupt, the output level goes only up to 2,5V.

// Enable interrupt TIM2
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable interrupt USART1
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

Can anybody explain this? Next, when I alter the USART-code to

NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;

the LED stops blinking and it seems, that the timer is no more running. This should only disable the USART-interrupt, why does it impact the timer-interrupt? Regards Tom
6 REPLIES 6
jpeacock2399
Associate II
Posted on July 19, 2012 at 16:02

What processor and which pins are you using?  Chances are it's a conflict with alternate functions.

  Jack Peacock

johnjohn9104
Associate II
Posted on July 19, 2012 at 19:54

The controller is a STM32L15... (sorry, can't have a look at the moment).

The USART1 is on Pins PA9/10, the Leds are on PB6/7.

As far as i know there are no alternate functions of USART1 on the Port B.

What I don't understand is why the timer is no longer working when disabling the USART1 .... ?

Regards

Tom

Posted on July 19, 2012 at 20:15

''When only this timer is running, the output level of the I/O pin is 3V when high.

 

When I additionaly activate the USART interrupt, the output level goes only up to 2,5V''

 

How are you measuring those voltages?

Have you checked with an oscilloscope to see if there is anything ''high frequency'' going on...?

johnjohn9104
Associate II
Posted on July 20, 2012 at 07:43

Posted on July 20, 2012 at 09:28

The biggest issue is USART_FLAG_TXE != USART_IT_TXE, etc

Then again, you also don't initialize the pins correctly. The timer period and prescaler are N-1, ie for N cycles [0 .. N-1] The NUL marking and buffer limits were a problem. Using 8-bit indexes is very inefficient, the registers are 32-bit and work more effectively even with ranges <256 A more considered solution might look like this :

#include ''stm32l1xx.h''
/* function prototypes */
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void USART1_Configuration(void);
void TIM2_Configuration(void);
void SysTick_Handler(void);
void TIM2_IRQHandler(void);
void USART1_Send(char cData);
void USART1_IRQHandler(void);
int iTick = 0;
int main(void)
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
USART1_Configuration();
TIM2_Configuration();
// Init SysTick Timer
SysTick_Config(1000000);
while(1)
{
// Just for debugging
if (iTick != 0)
{
iTick = 0;
}
}
}
void USART1_Send(char cData)
{
// Wait for buffer empty
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
// Send first byte
USART_SendData(USART1, cData);
// Enable Tx interrupt after sending first byte
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
void RCC_Configuration(void)
{
// Enable GPIOA, GPIOB clock
RCC_AHBPeriphClockCmd (RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
// Enable TIM2 clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// Enable USART1 clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// Set sysclock to output PA8
RCC_MCOConfig(RCC_MCOSource_SYSCLK, RCC_MCODiv_1);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// Enable interrupt TIM2
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable interrupt USART1
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void SysTick_Handler(void)
{
iTick = 1;
}
void GPIO_Configuration(void)
{
// Initialize Leds mounted on STM32L board
GPIO_InitTypeDef GPIO_InitStructure;
// Configure the GPIO_LED pin
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// Configure USART1 Tx (PA9) and Rx (PA10) as alternate function
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Configure MCO (PA8) as alternate function
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_MCO);
}
void USART1_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USART1 configured as follow:
- BaudRate = 115200 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 = 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(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
//Disable Transmit Data Register empty interrupt
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
//Enable Receive Data register not empty interrupt
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
void TIM2_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//setting timer 2 interrupt to ??hz ((??/1000)*1000)s
TIM_TimeBaseStructure.TIM_Prescaler = 1000 - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 10000 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* TIM IT enable */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
}
void TIM2_IRQHandler(void)
{
//If interrupt happens the do this
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
//Clear interrupt and start counting again to get precise freq
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
//Toggle led to see some chance in port B pin 6
if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_6) == RESET)
GPIO_WriteBit(GPIOB,GPIO_Pin_6,SET);
else
GPIO_WriteBit(GPIOB,GPIO_Pin_6,RESET);
}
}
void USART1_IRQHandler(void)
{
static char cReceiveData[100];
static char cSendData[100];
static int iReceiveIndex = 0;
static int iSendIndex = 0;
int a;
if (USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET)
{
GPIOB->ODR ^= GPIO_Pin_7;
cReceiveData[iReceiveIndex++]=(uint8_t)USART_ReceiveData(USART1);
if ((cReceiveData[iReceiveIndex-1] == 0x0D) || (iReceiveIndex >= 99))
{
for (a = 0; a < iReceiveIndex;a++)
{
cSendData[a] = cReceiveData[a];
cReceiveData[a] = 0;
}
cSendData[a] = 0; // NUL terminate

iReceiveIndex = 0;
iSendIndex = 0;
USART1_Send(cSendData[iSendIndex++]); //echo
}
}
if (USART_GetITStatus(USART1, USART_IT_TXE)!= RESET)
{
if ((cSendData[iSendIndex] != 0) && (iSendIndex < 100))
USART_SendData(USART1, cSendData[iSendIndex++]);
else
{
// Disable Tx interrupt after sending last byte
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
for (a = 0; a < iSendIndex;a++)
{
cSendData[a] = 0;
}
}
}
// Clear all flags
USART_ClearITPendingBit(USART1, (USART_IT_CTS | USART_IT_LBD | USART_IT_TC | USART_IT_RXNE));
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
johnjohn9104
Associate II
Posted on July 20, 2012 at 11:39

Thanks for your support!

Just before I read your answer I found that by adding this line:

GPIO_StructInit(&GPIO_InitStructure);

before each new GPIO configuration the output level was correct. You are right thatUSART_FLAG_TXE != USART_IT_TXE but in the SR theUSART_FLAG_TXE id at position 0x80 and in the CR1 the USART_IT_TXE is also at position 0x So this piece of my code worked as expected. I know that my code is not perfect (for example the missing receive- and send-length check) because it is not intended to be ''productional'' code, it is at some points just quick and dirty functional ''play'' code to get used to the device. I promise to improve the quality I will post here in the future ;) Regards Tom