初始化串口1PA9 PA10
流程
1、声明结构体
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
2、打开时钟
// 打开串口GPIO的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
// 打开串口外设的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
3、、GPIO初始化 复用上拉
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_9 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure);
4、 中断优先级配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
5、串口功能配置
// 配置串口的工作参数
// 配置波特率
USART_InitStructure.USART_BaudRate = baudrate;
// 配置 针数据字长
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校验位
USART_InitStructure.USART_Parity = USART_Parity_No;
// 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置工作模式,收发一起
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 完成串口的初始化配置
USART_Init(USART1, &USART_InitStructure);
6、开中断
//开启串口接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 使能串口
USART_Cmd(USART1, ENABLE);
// 完成TC状态位的清除,防止硬件复位重启之后, 第一个字节丢失
USART_ClearFlag(USART1, USART_FLAG_TC);
/**
* @Brief: 初始化IO 串口1
* @Note:
* @Parm: baudrate:波特率
* @Retval:
*/
void USART1_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 打开串口GPIO的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
// 打开串口外设的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_9 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure);
//Usart NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
// 配置串口的工作参数
// 配置波特率
USART_InitStructure.USART_BaudRate = baudrate;
// 配置 针数据字长
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校验位
USART_InitStructure.USART_Parity = USART_Parity_No;
// 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置工作模式,收发一起
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 完成串口的初始化配置
USART_Init(USART1, &USART_InitStructure);
//开启串口接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 使能串口
USART_Cmd(USART1, ENABLE);
// 完成TC状态位的清除,防止硬件复位重启之后, 第一个字节丢失
USART_ClearFlag(USART1, USART_FLAG_TC);
#if ENABLE_USART1_DMA
USART1_DMA_Init();
#endif
}
流程:
1、DMA初始化结构体声明
DMA_InitTypeDef DMA_InitStructure;
2、使能时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
3、反初始化DMA2_Stream5 这里注意每个数据流对应着不同通道,故数据流通道共同决定外设的DMA
4、配置DMA初始化
通道
外设地址
内存地址
传输方向
发送长度
外设地址自增
内存地址地怎
外设数据宽度
内存数据宽度
DMA模式
DMA传送优先级(1)软件阶段 配置寄存器的DMA_SxCR寄存器的PL[1:0]位,可以设为从非常高到低的四挡;2)硬件阶段 软件配置相同时,优先级取决于硬件流的编号,编号越低越具有优先权。
DMA_InitStructure.DMA_Channel = DMA_Channel_4;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR); // 外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)g_dma_buff; // 发送内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; // 外设为传送数据目的地,即发送数据
DMA_InitStructure.DMA_BufferSize = 0; // 发送长度为0
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不增加
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址自增1
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设数据宽度8bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存数据宽度8bit
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // (DMA传送优先级为高)
DMA_Init(DMA1_Stream5, &DMA_InitStructure); // 初始化
static void USART1_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/* DMA2 Channel4 (triggered by USART1 Tx event) Config */
DMA_DeInit(DMA2_Stream5);
DMA_InitStructure.DMA_Channel=DMA_Channel_4;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR); // 外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)g_dma_buff; // 发送内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; // 外设为传送数据目的地,即发送数据
DMA_InitStructure.DMA_BufferSize = 0; // 发送长度为0
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不增加
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址自增1
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设数据宽度8bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存数据宽度8bit
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // (DMA传送优先级为高)
DMA_Init(DMA1_Stream5, &DMA_InitStructure); // 初始化
// USART_ITConfig(USART1, USART_IT_TC, ENABLE); // 使能串口发送完成中断,需配置中断,否则影响开机
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); // 使能DMA串口发送请求
}
#endif
/// 重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口 */
USART_SendData(DEBUG_USARTx, (uint8_t)ch);
/* 等待发送完毕 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET)/* 发送缓冲区为空时USART_FLAG_TXE=1 这句代表有数据发送中*/
;
return (ch);
}
/// 重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
/* 等待串口输入数据 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET)/* 接收数据寄存器非空 */
;
return (int)USART_ReceiveData(DEBUG_USARTx);
}
/**
* @Brief: UART1发送数据
* @Note:
* @Parm: ch:待发送的数据
* @Retval:
*/
void USART1_Send_U8(uint8_t ch)
{
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
;
USART_SendData(USART1, ch);
}
/**
* @Brief: 串口1中断函数
* @Note:
* @Parm:
* @Retval:
*/
void USART1_IRQHandler(void)
{
uint8_t Rx1_Temp = 0;
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
// Rx1_Temp = USART1->DR; //(USART1->DR)/(USART_ReceiveData(USART1)); //读取接收到的数据
Rx1_Temp = USART_ReceiveData(USART1);
#if PID_ASSISTANT_EN
protocol_data_recv(&Rx1_Temp, 1);
#else
Upper_Data_Receive(Rx1_Temp);
#endif
}
}
串口2PA2PA3 使用SBUS协议 波特率100000 9位数据位 2个停止位 偶校验
使用蓝牙时正常设置
void USART2_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 打开串口GPIO的时钟
// 打开串口GPIO的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
// 打开串口外设的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART3);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Usart2 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; // 子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化NVIC寄存器
// 配置串口的工作参数
#if ENABLE_SBUS
// 配置波特率
USART_InitStructure.USART_BaudRate = baudrate;
// 配置 针数据字长,字长为9位数据格式,包含了1位校验位,8个数据位
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
// 配置2个停止位
USART_InitStructure.USART_StopBits = USART_StopBits_2;
// 配置校验位:偶校验位USART_Parity_Even
USART_InitStructure.USART_Parity = USART_Parity_Even;
// 配置硬件流控制:无
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置工作模式,收发一起
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
#else
// 配置波特率
USART_InitStructure.USART_BaudRate = baudrate;
// 配置 针数据字长
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校验位
USART_InitStructure.USART_Parity = USART_Parity_No;
// 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置工作模式,收发一起
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
#endif
// 完成串口的初始化配置
USART_Init(USART2, &USART_InitStructure);
// 开启串口接收中断
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
// 使能串口
USART_Cmd(USART2, ENABLE);
}
void USART3_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 打开串口GPIO的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
// 打开串口外设的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);
// Usart NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4; // 子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器
// 配置串口的工作参数
// 配置波特率
USART_InitStructure.USART_BaudRate = baudrate;
// 配置 针数据字长
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校验位
USART_InitStructure.USART_Parity = USART_Parity_No;
// 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置工作模式,收发一起
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 完成串口的初始化配置
USART_Init(USART3, &USART_InitStructure);
// 开启串口接受中断
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
// 使能串口
USART_Cmd(USART3, ENABLE);
}
#if ENABLE_UART4
void UART4_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 打开串口GPIO的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
// 打开串口外设的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
GPIO_Init(GPIOC, &GPIO_InitStructure);
// 配置串口的工作参数
// 配置波特率
USART_InitStructure.USART_BaudRate = baudrate;
// 配置 针数据字长
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校验位
USART_InitStructure.USART_Parity = USART_Parity_No;
// 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置工作模式
USART_InitStructure.USART_Mode = USART_Mode_Tx;
// 完成串口的初始化配置
USART_Init(UART4, &USART_InitStructure);
// 使能串口
USART_Cmd(UART4, ENABLE);
USART_ClearFlag(UART4, USART_FLAG_TC);
}
#endif
#if ENABLE_UART5
void UART5_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 打开串口GPIO的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
// 打开串口外设的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
GPIO_Init(GPIOD, &GPIO_InitStructure);
// 配置串口的工作参数
// 配置波特率
USART_InitStructure.USART_BaudRate = baudrate;
// 配置 针数据字长
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校验位
USART_InitStructure.USART_Parity = USART_Parity_No;
// 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置工作模式
USART_InitStructure.USART_Mode = USART_Mode_Tx;
// 完成串口的初始化配置
USART_Init(UART5, &USART_InitStructure);
// 使能串口
USART_Cmd(UART5, ENABLE);
USART_ClearFlag(UART5, USART_FLAG_TC);
}
#endif