1. 五个串口对应的引脚:
-
STM32F103VCT6有五个串口
引脚 USART1 USART2 USART3 USART4 USART5 TX PA9 PA2 PB10 PC10 PC12 RX PA10 PA3 PB11 PC11 PD2 SCLK PA8 PA4 PB12 nCTS PA11 PA0 PB13 nRTS PA12 PA1 PB14
2. 写代码步骤
这里以USART1 (串口一) 举例
-
自定义的宏定义
#ifndef __USART_H_ #define __USART_H_ #include "stm32f10x.h" // 串口 1-USART1 #define DEBUG_USARTx USART1 #define DEBUG_USART_CLK RCC_APB2Periph_USART1 #define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_BAUDRATE 19200 // USART GPIO 引脚宏定义 #define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA) #define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_TX_GPIO_PORT GPIOA #define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9 #define DEBUG_USART_RX_GPIO_PORT GPIOA #define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10 #define DEBUG_USART_IRQ USART1_IRQn #define DEBUG_USART_IRQHandler USART1_IRQHandler static void NVIC_Configuration(void); void USART_Config(void); void Usart_SendByte(USART_TypeDef* pUSARTX, char data); void Usart_SendString( USART_TypeDef * pUSARTx, char *str); #endif
-
初始化GPIO口外设
GPIO_InitTypeDef GPIO_InitStructure; // 打开串口 GPIO 的时钟 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE); // 将 USART1 Tx 的 GPIO 配置为推挽复用模式 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); // 将 USART1 Rx 的 GPIO 配置为浮空输入模式 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
-
初始化串口外设
USART_InitTypeDef USART_InitStructure; // 打开串口外设的时钟 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE); // 配置波特率 USART_InitStructure.USART_BaudRate = DEBUG_USART_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(DEBUG_USARTx, &USART_InitStructure); // 使能串口接收中断 USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE); // 使能串口 USART_Cmd(DEBUG_USARTx, ENABLE);
- 配置串口中断
NVIC_InitTypeDef NVIC_InitStructure; /* 嵌套向量中断控制器组选择 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 配置 USART 为中断源 */ NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ; /* 抢断优先级为 1 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 子优先级为 1 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 使能中断 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 初始化配置 NVIC */ NVIC_Init(&NVIC_InitStructure);
-
发送数据函数
//发送单个字符 void Usart_SendByte(USART_TypeDef* pUSARTx, char data) { USART_SendData(pUSARTx, data); while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); } //发送字符串 void Usart_SendString( USART_TypeDef * pUSARTx, char *str) { unsigned int k=0; do { Usart_SendByte( pUSARTx, *(str + k) ); k++; } while (*(str + k)!='\0'); /* 等待发送完成 */ while (USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) { } }
- 接受字符函数(直接用固件库)
// 接收一个字节的数据 uint16_t USART_ReceiveData(USART_TypeDef* USARTx); // 接收多个字节,还没搞懂怎么弄
- 中断函数
void DEBUG_USART_IRQHandler(void) { char ucTemp; // 该该串口的中断函数有多种触发方式(多种串口中断),USART_GetITStatus可以获得各种中断标志位,从而判断出是哪个中断触发了该中断函数。在之前我们只使能了接受寄存器非空的中断(USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);),所以这里的if也可不写 if (USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET) { ucTemp = USART_ReceiveData(DEBUG_USARTx); CMDDATA = ucTemp; //Usart_SendByte(DEBUG_USARTx, ucTemp); //Usart_SendByte(DEBUG_USARTx, '\n'); TIFLAG = 1; } }