2020-09-02 06:30 AM
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>© 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****/
Solved! Go to Solution.
2020-09-02 11:02 AM
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
2020-09-02 06:50 AM
> 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.
2020-09-02 09:03 AM
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
2020-09-02 11:02 AM
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