Skip to main content
Graduate
June 11, 2024
Solved

Switching between UART to GPIO and GPIO to UART

  • June 11, 2024
  • 4 replies
  • 2005 views

Hi 

   i am configuration UART1 as default and Tx pin switching into GPIO then  reset (Low) the GPIO for 28 micro sec(delay)  and set(high) the GPIO then again switching to UART1.

during switching waveform level  is intermediate as show in below. (my requirement is intermediate wave  in high leave)  

my requirement is send data 13bit data (all ZERO) and some data (different numbers in HEX) by using UART.

#include "main.h"

UART_HandleTypeDef huart1;



/* USER CODE BEGIN PV */



/* USER CODE END PV */



/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_USART1_UART_Init(void);



void GPIO_Init_Output(void)

{

// Enable the GPIOA clock

__HAL_RCC_GPIOA_CLK_ENABLE();



// Configure PA9 and PA10 as output

GPIO_InitTypeDef GPIO_InitStruct = {0};



GPIO_InitStruct.Pin = GPIO_PIN_9; // | GPIO_PIN_10;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // Push-pull mode

GPIO_InitStruct.Pull = GPIO_NOPULL; // No pull-up or pull-down resistors

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // Low frequency



HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}



void switchToGpio(void)

{

// Deinitialize UART to free PA9 and PA10

HAL_UART_DeInit(&huart1);

USART1->CR1 &= ~USART_CR1_TE; // disable the USART Tx



// Initialize PA9 and PA10 as GPIO output

GPIO_Init_Output();

}

void GPIO_Init_UART(void)

{

// Enable the GPIOA clock

__HAL_RCC_GPIOA_CLK_ENABLE();



// Configure PA9 and PA10 as alternate function (UART)

GPIO_InitTypeDef GPIO_InitStruct = {0};

GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // Alternate function push-pull

GPIO_InitStruct.Pull = GPIO_NOPULL; // No pull-up or pull-down resistors

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // Very high frequency

GPIO_InitStruct.Alternate = GPIO_AF7_USART1; // Alternate function 7 (USART1)

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}





void switchToUart(void)

{

// Deinitialize PA9 and PA10 as GPIO | GPIO_PIN_10

HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9);

// Initialize PA9 and PA10 as UART

GPIO_Init_UART();

// Reinitialize UART

MX_USART1_UART_Init();

}



void delayMicroseconds(uint32_t us)

{

uint32_t startTick = HAL_GetTick();

uint32_t startMicros = DWT->CYCCNT;

uint32_t delayTicks = (SystemCoreClock / 1000000) * us; // Calculate the number of ticks needed for the delay



while ((DWT->CYCCNT - startMicros) < delayTicks)

{

// Wait until the required number of ticks has passed

}

}

void SysTick_Handler(void)

{

HAL_IncTick();

HAL_SYSTICK_IRQHandler();

}

int main(void)

{



uint8_t data_1[10]={0x55,0x40,0xE1,0xB3};

uint8_t tx_buffer[10];

HAL_Init();

/* Configure the system clock */

SystemClock_Config();



/* USER CODE BEGIN SysInit */



DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // Enable the cycle counter

/* USER CODE END SysInit */



/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_USART1_UART_Init();

/* USER CODE BEGIN 2 */



/* USER CODE END 2 */



/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

switchToGpio();

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);

delayMicroseconds(28);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);

// delayMicroseconds(2);

switchToUart();

HAL_UART_Transmit(&huart1,data_1,4, 100);

HAL_Delay(10);

}

/* USER CODE END 3 */

}



/**

* @brief System Clock Configuration

* @retval None

*/

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_HSI;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

RCC_OscInitStruct.PLL.PLLM = 13;

RCC_OscInitStruct.PLL.PLLN = 195;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = 5;

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_DIV2;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;



if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)

{

Error_Handler();

}

}



static void MX_USART1_UART_Init(void)

{



huart1.Instance = USART1;

huart1.Init.BaudRate = 500000;

huart1.Init.WordLength = UART_WORDLENGTH_9B;

huart1.Init.StopBits = UART_STOPBITS_1;

huart1.Init.Parity = UART_PARITY_EVEN;

huart1.Init.Mode = UART_MODE_TX_RX;

huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;

huart1.Init.OverSampling = UART_OVERSAMPLING_8;

if (HAL_UART_Init(&huart1) != HAL_OK)

{

Error_Handler();

}



}



static void MX_GPIO_Init(void)

{

/* USER CODE BEGIN MX_GPIO_Init_1 */

/* USER CODE END MX_GPIO_Init_1 */



/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOA_CLK_ENABLE();



/* USER CODE BEGIN MX_GPIO_Init_2 */

/* USER CODE END MX_GPIO_Init_2 */

}

 

    This topic has been closed for replies.
    Best answer by waclawek.jan

    +1, although GPIOx_MODER needs to be changed rather than GPIOx_AFR[].

    JW

    4 replies

    Graduate II
    June 11, 2024

    Perhaps just change the GPIO AFR and ODR more directly rather than continuously DeInit/Init

    Super User
    June 11, 2024

    +1, although GPIOx_MODER needs to be changed rather than GPIOx_AFR[].

    JW

    Naresh_Author
    Graduate
    June 12, 2024

    Hi Waclawek,

    the below is working for UART but come to GPIO it not working.

    kindly help me.

    void moder_conf()

    {

    GPIOA->MODER &= ~((3 << 18) | (3 << 20));

    //Switching from UART to GPIO

    GPIOA->MODER|=(1<<18)|(1<<20); // Moder register Alternate function

    }

     

    void clear_moder()

    {

    GPIOA->MODER &= ~((3 << 18) | (3 << 20)); // UART init

    GPIOA->MODER |= (2 << 18) | (2 << 20);

    }

    Super User
    June 13, 2024

    > GPIOA->MODER|=(1<<18)|(1<<20); // Moder register Alternate function

    The comment is not correct - this switches the pins to GPIO Output.

    > come to GPIO it not working

    What exactly do you do, what are the symptoms and how are they different from expectations?

    JW