#include "usart1.h"
#include "main.h"
#include "stdio.h"
#include "string.h"
#include "stdbool.h"
#include "stdlib.h"
#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
DMA_HandleTypeDef hdma_uart1_rx;
UART_HandleTypeDef huart1;
uint8_t rx_buffer[1024] = {0};
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(huart->Instance == USART1)
{
USARTx_RX_GPIO_CLK_ENABLE();
USARTx_TX_GPIO_CLK_ENABLE();
__HAL_RCC_AFIO_CLK_ENABLE();//重定向时钟//需要重映射的话要开启重映射时钟,不重映射开启这个时钟也没有影响
//首先开启引脚的时钟,开启引脚的复用模式,关于引脚被复用成什么功能是与接下来开启哪个外设的时钟有关系,
//比如开启串口的时钟就是串口的功能,开启adc的时钟就是adc的功能
USARTx_CLK_ENABLE();
//时钟开始后开始配置串口发送引脚
GPIO_InitStruct.Pin = USARTx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
//配置引脚这些配置放到初始化函数中
HAL_GPIO_Init(USARTx_TX_GPIO_PORT,&GPIO_InitStruct);
//配置接受引脚
GPIO_InitStruct.Pin = USARTx_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(USARTx_RX_GPIO_PORT,&GPIO_InitStruct);
//使用中断开启中断
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
}
void usart1_dma1_congfig()
{
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_uart1_rx.Instance = DMA1_Channel5;
hdma_uart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart1_rx.Init.Mode = DMA_NORMAL; // 循环模式(持续接收)
hdma_uart1_rx.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma_uart1_rx);
__HAL_LINKDMA(&huart1, hdmarx, hdma_uart1_rx);
}
void uart_open()
{
// HAL_UART_MspInit(&huart1);
uint8_t ch;
huart1.Instance = USARTx;
huart1.Instance = USARTx;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.OverSampling= UART_OVERSAMPLING_16;//16倍过采样是保证每次都取到中间值去掉前后干扰如0~16取值是9
if(HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
usart1_dma1_congfig();
HAL_UART_Receive_DMA(&huart1, rx_buffer, sizeof(rx_buffer));
}
void USART1_IRQHandler()
{
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
huart1.Instance->DR;
huart1.Instance->SR;
uint32_t remaining = __HAL_DMA_GET_COUNTER(&hdma_uart1_rx);
uint32_t received_len = sizeof(rx_buffer)-remaining;
HAL_UART_Transmit(&huart1, rx_buffer,received_len, 0xFFFF);
HAL_UART_DMAStop(&huart1);//处理完重置//接受完成后一定要加停止,让dma重新从0开始传输,不然会dma通道会溢出,停止之后再重新开启dma传输
memset(rx_buffer,0,sizeof(rx_buffer));
}
HAL_UART_Receive_DMA(&huart1, rx_buffer, sizeof(rx_buffer));
}
int fputc(int ch, FILE *f)
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART2 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}