2025-03-05 11:08 AM
Hello everyone,
I am struggling with a problem that has not been solved before. Perhaps someone could be found who would be able to solve it. The issue is with the operation of the interrupt for receiving a character via USART. The interrupt is not responding, and I am unable to resolve this problem on my own. The USART transmits and receives the data frame correctly, but when I enable the interrupt for USART reception, it stops receiving. I am trying to control an SG90 servo motor. Its nuclef303RE, MCU stm32f3.
#include "stm32f303xe.h"
#include "stdint.h"
#include "stm32f3xx.h"
#include <stdio.h>
#include <string.h>
#define LD4_ON GPIOA -> BSRR |= GPIO_BSRR_BS_5;
#define LD4_OFF GPIOA -> BSRR |= GPIO_BSRR_BR_5;
volatile int currentindex=0;
volatile int position = 1000;
volatile char message;
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 < 2000)
{
position+=30;
TIM3->CCR1 = position;
}
}
else if(strcmp(message,"P") == 0)
{
if(position > 900)
{
position-=30;
TIM3->CCR1 = position;
}
}
memset(message,0,currentindex+1);
currentindex = 0;
USART2->ICR |= USART_ICR_IDLECF;
}
}
void configureLD4(void)
{
GPIOA -> MODER |= GPIO_MODER_MODER5_0;
GPIOA -> MODER &= ~(GPIO_MODER_MODER5_1);
GPIOA -> OTYPER &= ~(GPIO_OTYPER_OT_5);
GPIOA -> OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR5);
GPIOA -> PUPDR &= ~(GPIO_PUPDR_PUPDR5);
}
void configureTIMER3(void);
void TIM3_start(void);
void interuptTIM3(void);
void pwmconfigration(void);
void configPWMPA6(void);
int main(void)
{
clock_config();
configureLD4();
config_UART();
configureTIMER3();
TIM3_start();
pwmconfigration();
configPWMPA6();
interuptTIM3();
USART2->TDR = 'D';
while (!(USART2->ISR & USART_ISR_TXE)) { } // Czekaj na opróżnienie bufora
while (!(USART2->ISR & USART_ISR_TC)) { } // Czekaj na zakończenie transmisji
while(1)
{
}
}
void configureTIMER3(void)
{
//PA6:D12
RCC -> APB1ENR |= RCC_APB1ENR_TIM3EN;
TIM3->PSC = 71; //72mghz
TIM3->ARR = 19999; //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 = 900;
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);
}
2025-03-05 12:47 PM - edited 2025-03-05 12:52 PM
Hi,
did you think on: what, if a receive error coming ?
USART doing nothing any more, until error state is cleared and again "ready to receive" is set...
+ check in debug, if its coming to the INT, but with any error set...instead of a received byte.
btw
i only use the HAL lib, so i cannot tell you, what you should set ; but with HAL also need to handle uart-receive and uart-error, to have it working reliably.