cancel
Showing results for 
Search instead for 
Did you mean: 

USART & Timer Interrupt

Mujtaba
Senior
Posted on November 17, 2016 at 09:55

Hello,

I am trying to use USART1 to transmit and receive data in every 100ms. I've used both USART1 TXE and RXNE interrupts and Timer2 update interrupt but unfortunately it's not working and I don't have any data transmission nor reception! I am using stm32f103rbt6 microcontroller. Could you help me and tell me what I have to do ? Any helps would be appreciated. The main code is shown bellow:


#include ''stm32f10x.h''

#include ''stm32f10x_it.h''

#include ''stm32f10x_gpio.h''

#include ''stm32f10x_tim.h''

#include ''stm32f10x_usart.h''

#include ''misc.h''

void USART_config(void);

void RCC_config(void);

void NVIC_config(void);

void GPIO_config(void);

void Timer2_config(void);

USART_InitTypeDef USART_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

unsigned short write_led1_on[]={0x79,0x06,0x00,0x10,0x00,0x01,0x43,0xB7};

unsigned short write_led2_on[]={0x79,0x06,0x00,0x11,0x00,0x01,0x12,0x77};

unsigned short write_led_off[]={0x79,0x10,0x00,0x10,0x00,0x02,0x00,0x00,0x00,0x00,0x07,0xC2};

unsigned short read_2button_panel_touch_status[]={0x79,0x03,0x00,0x00,0x00,0x02,0xCE,0x73};

unsigned short *TxBuffer;

unsigned short *RxBuffer;

uint8_t TxLength=0x00;

uint8_t TxCount=0x00;

uint8_t ReceiveComplete=0,START=0;

uint8_t RxCount=0x00;

uint8_t Length;

ErrorStatus HSEStartUpStatus;

int main(void)

{

RCC_config();

GPIO_config();

USART_config();

Timer2_config();

NVIC_config();

//Enable the TIM2 Update Interrupt source:

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

USART_ITConfig(USART1,USART_IT_TXE,ENABLE);

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

while(1)

{

TxBuffer=read_2button_panel_touch_status;

TxLength=8;

START=0;

//Enable the TIM2:

TIM_Cmd(TIM2,ENABLE);

while(START!=1);

while(ReceiveComplete!=1);

if(RxBuffer[4]==0x01)

{

TxBuffer=write_led1_on;

TxLength=8;

}

else if(RxBuffer[6]==0x01)

{

TxBuffer=write_led2_on;

TxLength=8;

}

else

{

TxBuffer=write_led_off;

TxLength=12;

}

//Enable the TIM2:

TIM_Cmd(TIM2,ENABLE);

while(!START);

while(!ReceiveComplete);

}

}

void RCC_config(void)

{

RCC_DeInit();

RCC_HSEConfig(RCC_HSE_ON);

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)

{

RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);

RCC_PLLCmd(ENABLE);

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

while(RCC_GetSYSCLKSource() != 0x08);

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div2);

RCC_PCLK2Config(RCC_HCLK_Div1); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_USART1,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

}

}

void GPIO_config(void)

{

//USART1 TX GPIO Configuration:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);

//USART1 RX GPIO Configuration:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA,&GPIO_InitStructure);

// LED1 GPIO Configuration:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);

// DE & RE signal Configuration:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOC,&GPIO_InitStructure); 

}

void USART_config(void)

{

//USART1 Configuration:

USART_InitStructure.USART_BaudRate = 19200;

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_Tx|USART_Mode_Rx;

USART_Init(USART1,&USART_InitStructure);

}

void NVIC_config(void)

{

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

//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); 

//Enable the TIM2 Interrupt:

NVIC_InitStructure.NVIC_IRQChannel =TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure); 

}

void Timer2_config(void)

{

TIM_TimeBaseStructure.TIM_Period =16000-1;

TIM_TimeBaseStructure.TIM_Prescaler =450-1;

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 

}

and the interrupt routine code is shown as bellow:


void USART1_IRQHandler(void)

{

if((USART1->SR & 0x80)==0x80)

{

//If the buffer is fully transmitted:

if(TxCount == TxLength)

{

//Set DE pin to low level (TC interrupt is occured ):

GPIOA->BRR = GPIO_Pin_2;

GPIOC->BSRR=GPIO_Pin_6;

//Disable the USART1 Transmit Complete interrupt:

USART_ITConfig(USART1,USART_IT_TC, DISABLE);

USART_ClearFlag(USART1,USART_FLAG_TC);

TxCount=0;

START=0;

ReceiveComplete=0;

//Enable USART1 TXE Interrupt:

USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

}

else if (TxCount == TxLength-1)

{

if(USART_GetFlagStatus(USART1,USART_FLAG_TXE)!=RESET)

{

USART1->DR = TxBuffer[TxCount++];

//Disable USART TXE interrupt:

USART_ITConfig(USART1, USART_IT_TXE, DISABLE);

//Enable TC interrupt at the last byte to transmit:

USART_ITConfig(USART1, USART_IT_TC , ENABLE);

}

}

else if(TxCount != 0) //if it's not the first byte

{

//USART1 Tx empty interrupt has occured:

if(USART_GetFlagStatus(USART1,USART_FLAG_TXE)!=RESET)

{

//Continue the buffer transmission via USART:

USART1->DR = TxBuffer[TxCount++];

}

}

else if(TxCount==0)//The first byte to be transmitted:

{

//USART1 Tx empty interrupt has occured:

if(USART_GetFlagStatus(USART1,USART_FLAG_TXE)!=RESET)

{

USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);

//Set DE pin to high level:

GPIOA->BSRR = GPIO_Pin_2;

GPIOC->BRR=GPIO_Pin_6;

//Transmit the first byte:

USART1->DR = TxBuffer[TxCount++];

}

if(TxLength == 1 )

{

//Enable TC interrupt at the last byte to transmit (single byte):

//Enable USART TC interrupt:

USART_ITConfig(USART1, USART_IT_TC , ENABLE);

//Disable USART TXE interrupt:

USART_ITConfig(USART1, USART_IT_TXE, DISABLE);

}

}

}

else if((USART1->SR & 0x20)==0x20)

{

if(RxCount>2)

{

if(RxCount<
RxBuffer
[2]+2+3-1)

{

if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)!=RESET)

{

//Continue the buffer transmission via USART:

RxBuffer[RxCount++]=USART1->DR;

}

} 

else if(RxCount==RxBuffer[2]+2+3)

{

if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)!=RESET)

{

RxBuffer[RxCount++]=USART1->DR;

ReceiveComplete=1;

USART_ITConfig(USART1, USART_IT_RXNE,DISABLE);

RxCount=0;

START=0;

GPIOA->BSRR=GPIO_Pin_2;

GPIOC->BRR=GPIO_Pin_6;

}

}

}

else

{

if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)!=RESET)

{

//Continue the buffer transmission via USART:

RxBuffer[RxCount++]=USART1->DR;

}

}

}

}

void TIM2_IRQHandler(void)

{

if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)

{

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

START=1;

//USART_ITConfig(USART1,USART_IT_TXE,ENABLE);

USART_Cmd(USART1,ENABLE);

TIM_Cmd(TIM2,DISABLE);

} 

}

5 REPLIES 5
to2
Associate
Posted on November 18, 2016 at 10:33

Probably

__enable_irq();

Mujtaba
Senior
Posted on November 20, 2016 at 20:29

Hello,

when I disable the USART and comment the USART related lines, the TIMER interrupt works correctly and when I disable the TIMER and the USART receiving part and comment the related lines, the USART transmit part also woks correctly.

But when I enable the USART receiving part (TIMER is still disabled), none of them works at all.

I can't find where the problem is!!!! It's very urgent and if anybody can help, I'll be greatly thankful.

Posted on November 21, 2016 at 01:30

I can't see any blocking in the IRQ handler, but I'm not digging into the logic here. I'd probably not ''if else'' the USART status, both RXNE and TXE could assert together.

If the code is too complex to debug, simplify it, and test the USART is behaving correctly.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
to2
Associate
Posted on November 21, 2016 at 08:33

Try to look into .map file for ''Removing Unused input sections from the image''. Just to be sure. It may happen compiler remove your ISR for some reason.

adil
Associate II
Posted on November 21, 2016 at 09:30

''But when I enable the USART receiving part (TIMER is still disabled), none of them works at all.''

 

void

TIM2_IRQHandler(

void

)

{

if

(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)

{

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

START=1;

//USART_ITConfig(USART1,USART_IT_TXE,ENABLE);   //This is the reason for above question. When you enable usart and not timer ur usart doesnt work  //When timer is disabled this even won't fire and not start USART.

USART_Cmd(USART1,ENABLE);   

TIM_Cmd(TIM2,DISABLE);

}

}