cancel
Showing results for 
Search instead for 
Did you mean: 

stm32 USART2 issue

Oahme.1
Associate III

Hi , My USART1 works fine when i send a character and i recieve a character in comport ,

but i need to also configure USART2 ,i have configured the apb1 register and also apb2enr for the GPIOA clock enable ,i know for the fact that the clock on apb1 register in 36Mhz if running core on 72Mhz,I did try to set the BRR register but not sure if its the correct hex value,I cant find the solution.I am recieving data on serial port but its garbage value and nothing else. basically im recieving the value and want to just throw it back to the comport.Please help me out .The code runs fine otherwise ,I think the problem is not being able to set the baud rate.Im using the stm32f1 series.

Thanks,

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "string.h"
 
/* Private define ------------------------------------------------------------*/
 
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void GPIO_Init(void);
void Timer_4_Init(void);
void TIM4_IRQHandler(void);
void micro(int us);
void USART_Init(void);
void USART2_Init(void);  
 
/* Private variables ---------------------------------------------------------*/
 
int myTicks=0 ;
 
/* Private user code ---------------------------------------------------------*/
 
/*Interrupt Enable */
 
#define USART_SR_RX 0x20 
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
 
  /* MCU Configuration--------------------------------------------------------*/
 
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  GPIO_Init();
/*  Initalize Timers */
  Timer_4_Init();
	
 //USART_Init();
  USART2_Init();	
 
  NVIC_EnableIRQ(TIM4_IRQn);
 
 
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
 
		
  		
	 micro(1000);
		
	
		
			   if (USART2->SR & USART_SR_RXNE	)
					 
		 {
		    char temp = USART2->DR ;
			  USART2->DR	= temp ;
			  while (!(USART2->SR & USART_SR_TC)); 
			 
			  
		 }
		
	
		
	/*
			   if (USART1->SR & USART_SR_RXNE	)
		 {
		    char temp = USART1->DR ;
			  USART1->DR	= temp ;
			  while (!(USART1->SR & USART_SR_TC)); 
			 
			  
		 }
	
		
		
		*/
	
		
  }
 
	
  /* Main ends here */
}
 
 
 
/*
  * brief System Clock Configuration
  */
 
 
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
 
    Error_Handler();
  }
 
}
 
void USART_Init(void)
	
{
	
	 
 
	 RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN;  	// USART1/GPIOA Enable clock
 
   GPIOA->CRH |= GPIO_CRH_MODE9 |GPIO_CRH_CNF9_1;								// Config A9 as Tx Alternate pushpull at 50Mhz,A10 is default set to Rx 
	 GPIOA->CRH &= ~(GPIO_CRH_CNF9_0);
	
	 USART1->BRR = 0x1D4C ;
	  
	 USART1->CR1 =USART_CR1_TE | USART_CR1_RE |USART_CR1_UE ;     //---------   Tx Enable----- Re Enable ----UART Enable
	
	 
	
}
 
 
void USART2_Init(void)
	
 {
   RCC->APB2ENR = RCC_APB2ENR_IOPAEN;
   RCC->APB1ENR |=RCC_APB1ENR_USART2EN ;  // USART1/GPIOA ENABLE 
	 
	 GPIOA->CRL |= (1<<8);             // gpioa running on 10Mhz 
	 GPIOA->CRL |= GPIO_CRL_CNF2_1 ;   
         GPIOA->CRL &= ~(GPIO_CRL_CNF2_0);	 
	 
	 USART2->BRR =0xEA5D ; 
	 
	 USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE ; 
	
 }
 
 
void Timer_4_Init(void)
 
{
 
	 RCC->APB1ENR |= (1<<2);		                 // Timer4 clock enable register
 
	 TIM4->PSC = 	0 ; 													// Timer 4 prescaler register
	 TIM4->ARR = 	7200;                         // Auto Reload register
	 TIM4->CR1    |=TIM_CR1_URS;								//Update Interrupt on overflow/underflow only
	 TIM4->CR1 &=	~((1<<0) | (1<<4)) ;				 //Put 0 in DIR and CEN register
	 TIM4->EGR  |= TIM_EGR_UG;                          //Update generation bit --> Pending
	 TIM4->DIER |= TIM_DIER_UIE; 	 	 	 	 	 	 	 	//Update interrupt enable
	 //TIM4->CR1 |= TIM_CR1_CEN;
 
 
/*
 RCC->APB1ENR |=(1<<8);		                        // Timer4 clock enable register
 TIM4->CR1    |=(1<<2);								//Update Interrupt on overflow/underflow only
 TIM4->PSC = 	65535 ; 							// Timer 4 prescaler register
 TIM4->ARR = 	60000;                               // Auto Reload register
 TIM4->CR1 &=	~((1<<0) | (1<<4)) ;				//Put 0 in DIR and CEN register
 TIM4->DIER |= (1<<0); 	 	 	 	 	 	 	 	//Update interrupt enable
 TIM4->EGR  |=   (1<<0);                          //Update generation bit --> Pending
 TIM4->CR1 |= (1<<4);
 
  */
 
}
 
 
 
void micro(int us)
{
 TIM4->CR1 |= 	TIM_CR1_CEN;
	GPIOC->BSRR =(1<<(13+16));
	myTicks = 0;
	
	while(myTicks<us);
	
	
	GPIOC->BSRR =(1<<13);	
	TIM4->CR1 &= ~TIM_CR1_CEN;
 
}
 
 
/**
  * @brief GPIO Initialization Function
  */
 
static void GPIO_Init(void)
{
 
 
	RCC->APB2ENR |= (1<<4);							// GPIO-C Port Clock Enable
	GPIOC->CRH   |=	(1<<20) | (1<<21);				// Clock Frequency 50Mhz
	GPIOC->CRH 	 &= ~((1<<22) | (1<<23)); 			//General purpose output
 
}
 
 
 
 
 
/* ALL Interrupts go here    */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
 
  /* USER CODE END Error_Handler_Debug */
}
 
void TIM4_IRQHandler(void)
 
{
  GPIOC->BSRR =(1<<13);
	myTicks++;
  TIM4->SR &=~TIM_SR_UIF;				// Update interrupt flag
 
}
 
 
 
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

1 ACCEPTED SOLUTION

Accepted Solutions
Oahme.1
Associate III

Thanks @Community member​  and @TDK​  , The baud Rate was the problem ,The code runs properly and thankyou for the other corrections . The Data sheet had this formula of BRR = ***/16xUSARTDIV , USARTDIV being the fixed point value I'll put into the BRR register,Didn't know it was that simple

View solution in original post

3 REPLIES 3
TDK
Guru

> I did try to set the BRR register but not sure if its the correct hex value,I cant find the solution.

Buad rate is peripheral clock / BRR. So BRR = peripheral clock / target rate.

If you feel a post has answered your question, please click "Accept as Solution".

With register level programming you're going to have to get a lot sharper on the details.

Need to OR this on, otherwise you'll break other settings

RCC->APB2ENR = RCC_APB2ENR_IOPAEN

You don't need to use the RMW method for this, the register has special, defined behaviour. Also put it at the TOP of the Handler, otherwise you'll get a bonus tail-chain interrupt. Qualify the interrupt source on entry

TIM4->SR &=~TIM_SR_UIF;

Prescale and Period are programmed as N-1 values

TIM4->ARR = 7200; // Auto Reload register

APB1 is running half the speed of APB2, the BRR value will be half

USART2->BRR =0xEA5D ;

USART2->BRR = 36000000 / 1200; // Use human readable values, the compiler will fold the computation to a constant

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

Thanks @Community member​  and @TDK​  , The baud Rate was the problem ,The code runs properly and thankyou for the other corrections . The Data sheet had this formula of BRR = ***/16xUSARTDIV , USARTDIV being the fixed point value I'll put into the BRR register,Didn't know it was that simple