cancel
Showing results for 
Search instead for 
Did you mean: 

STM32f303xe(nucleoF303RE) USART2 interrupt recive not respoding.

FilipF303RE
Associate III

Hello everyone, I have a problem with sending a variable of type string using the USART interrupt in order to control an SG90 servo with PWM. Initially, the idea was to use keyboard key presses to make the motor rotate either to the right or to the left. The microcontroller is not responding; I tried using my own application as well as RealTerm. I don't understand what could be causing the interrupt not to work. I thought the issue might be related to not handling the flag register, but unfortunately, I haven't been able to figure out the solution.

#include "stm32f303xe.h"
#include "stdint.h"
#include "stm32f3xx.h"
#include <stdio.h>
#include <string.h>

volatile int currentindex=0;
volatile int position = 150;
volatile char message[50];


void clock_config(void)
{
	RCC->CR |= RCC_CR_HSION;
	 while (!(RCC->CR & RCC_CR_HSIRDY));
	 RCC->APB1ENR |= RCC_APB1ENR_PWREN;

	 RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
	 RCC->CFGR|= RCC_CFGR_PPRE1_DIV2;
	 //PPL SOURCE MUX

	// RCC->CFGR |= RCC_CFGR_PLLMUL9;
	 RCC->CFGR |= (0x7 << RCC_CFGR_PLLMUL_Pos);
	 RCC->CR |= RCC_CR_PLLON;
	 while (!(RCC->CR & RCC_CR_PLLRDY));
	 RCC->CFGR |= RCC_CFGR_SW_PLL;
	 while(!(RCC->CFGR & RCC_CFGR_SWS));
}



void config_UART(void)
{
	RCC -> AHBENR |= RCC_AHBENR_GPIOAEN;


	//PA2_TXAF7
	GPIOA -> MODER &= ~(GPIO_MODER_MODER2_0);
    GPIOA->MODER |= GPIO_MODER_MODER2_1;
    GPIOA->AFR[0] &= ~((0xF << GPIO_AFRL_AFRL2_Pos));
	GPIOA->AFR[0] |= (0x7 << GPIO_AFRL_AFRL2_Pos);

	//PA3_RXAF7
	GPIOA -> MODER &= ~(GPIO_MODER_MODER3_0);
	GPIOA->MODER |= GPIO_MODER_MODER3_1;
	GPIOA->AFR[0] &= ~((0xF << GPIO_AFRL_AFRL3_Pos));
	GPIOA->AFR[0] |= (0x7 << GPIO_AFRL_AFRL3_Pos);




	//GPIOA -> OTYPER |= GPIO_OTYPER_OT_3;
	//GPIOA->PUPDR |= GPIO_PUPDR_PUPDR3_0;
	RCC -> APB1ENR |= RCC_APB1ENR_USART2EN;

	//RCC -> CFGR |= RCC_CFGR_PPRE1_2;

	USART2->BRR = 36000000/115200;

	USART2-> CR1 |= USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
	USART2-> CR1 |=	 USART_CR1_IDLEIE | USART_CR1_RXNEIE;
	NVIC_SetPriority(USART2_IRQn, 0);
	NVIC_EnableIRQ(USART2_IRQn);



}
void USART2_IRQHandler(void)
{
	if(USART2->ISR & USART_ISR_RXNE)
	{
		message[currentindex] = USART2-> RDR;
		currentindex++;

	}else if(USART2->ISR &  USART_ISR_IDLE)
	{
		if(strcmp(message,"L") == 0)
		{
			if(position < 250)
			{
				position+=2;
				TIM3->CCR1 = position;
			}
		}
		else if(strcmp(message,"P") == 0)
		{
			if(position > 50)
			{
				position-=2;
				TIM3->CCR1 = position;
			}
		 }
		memset(message,0,currentindex+1);
		currentindex = 0;
		USART2->ISR &= ~USART_ISR_IDLE;
	}
}
void configureTIMER3(void);
void TIM3_start(void);
void interuptTIM3(void);
void pwmconfigration(void);
void configPWMPA6(void);
int main(void)
{
	clock_config();
	config_UART();
	configureTIMER3();
	TIM3_start();
	pwmconfigration();
	configPWMPA6();
	interuptTIM3();
	while(1)
	{

	}
}

void configureTIMER3(void)
{
	 //PA6:D12

	RCC -> APB1ENR |= RCC_APB1ENR_TIM3EN;
	TIM3->PSC = 71;   //72mghz
	TIM3->ARR = 1999;  //PA6
}
void TIM3_start(void)
{
	TIM3->CNT=0;
	TIM3->CR1|= TIM_CR1_CEN;
}

void interuptTIM3(void)
{
	TIM3 -> DIER |= TIM_DIER_UIE;
	TIM3 -> DIER |= TIM_DIER_CC1IE;
	NVIC_SetPriority(TIM3_IRQn, 1);
	NVIC_EnableIRQ(TIM3_IRQn);
}
void TIM3_IRQHandler(void)
{
	if(TIM3 -> SR & TIM_SR_UIF)
	{
		TIM3 -> SR &= ~(TIM_SR_UIF);
	}
	if(TIM3 -> SR & TIM_SR_CC1IF)
		{
			TIM3 -> SR &= ~(TIM_SR_CC1IF);
		}
}
void pwmconfigration(void)
{
	TIM3 -> CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
	TIM3 -> CCMR1 |= TIM_CCMR1_OC1PE;
	TIM3 -> CCR1 = 450;
	 TIM3->CR1 |= TIM_CR1_ARPE;
	TIM3 -> CCER |= TIM_CCER_CC1E;
}
void configPWMPA6(void)
{

	GPIOA-> MODER |= GPIO_MODER_MODER6_1;
	GPIOA->AFR[0] |= (0x2 << GPIO_AFRL_AFRL6_Pos);
}

2 REPLIES 2

> I don't understand what could be causing the interrupt not to work.

Interrupt works, but it loops infinitely. In 'F3 UART, IDLE is not cleared by writing to it, but by writing 1 to the IDLECF in
the USART_ICR register, see description of IDLE bit of UART_ISR register in RM.

Probably not the primary issue, but do handle the UART error flags, especially overflow. Also, don't RMW flags registers.

JW

PS. Why did you set "string" in bold typeface in your post?

Unfortunately register level coding comes with responsibility to debug it yourself, and go over the register definitions to understand the reported conditions when it fails.

Is there a Noise or Framing type error blocking further reception? If the source of the interrupt is not cleared it will keep reentering.

Confirm the UART2 is outputting successfully by sending a diagnostic message as the code starts.

Also

TIM3->SR = ~(TIM_SR_UIF); // Just write the mask, don't do the RMW &=

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..