1. 項目:野火stm32f10指南者開發板,使用USART實現數據的發送和接收。
2. 代碼
- 主函數main.c
#include "stm32f10x.h"
#include "bsp_usart.h"
int main(void)
{
USART_Config();
//發送一個字符
Usart_SendByte(DEBUG_USARTx,'A');
while(1)
{
}
}
- bsp_usart.c
#include "bsp_usart.h"
static void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /*配置NVIC為優先級組2*/
NVIC_InitStruct.NVIC_IRQChannel= DEBUG_USART_IRQ; /*配置USART中斷源*/
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; /*使能中斷通道*/
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1; /*配置搶占優先級:1*/
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1; /*配置子優先級:1*/
NVIC_Init(&NVIC_InitStruct); /*初始化配置NVIC*/
}
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
//GPIO外設時鍾使能
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
//串口時鍾使能
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
//將USART Tx的GPIO配置為推挽復用模式
GPIO_InitStruct.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStruct);
//將USART Rx的GPIO配置為浮空輸入模式
GPIO_InitStruct.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStruct);
//配置串口的工作參數
//配置波特率
USART_InitStruct.USART_BaudRate = DEBUG_USART_BAUNDRATE;
//配置針數據字長
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
//配置停止位
USART_InitStruct.USART_StopBits = USART_StopBits_1;
//配置校驗位
USART_InitStruct.USART_Parity = USART_Parity_No;
//配置硬件流控制
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
//配置工作模式,收發一起
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
//完成串口的初始化配置
USART_Init(DEBUG_USARTx, &USART_InitStruct);
//串口中斷優先級配置
NVIC_Config();
//使能串口接收中斷
USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);
//使能串口
USART_Cmd(DEBUG_USARTx,ENABLE);
}
//發送字節函數
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
{
USART_SendData(pUSARTx, data);
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
- bsp_usart.h
#ifndef __bsp_usart_h #define __bsp_usart_h #include "stm32f10x.h" //串口USART宏定義 #define DEBUG_USARTx USART1 #define DEBUG_USART_CLK RCC_APB2Periph_USART1 #define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_BAUNDRATE 115200 //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 void USART_Config(void); void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data); #endif /*bsp_usart_h*/
- stm32f10x_it.c函數添加中斷函數
/* Includes ------------------------------------------------------------------*/ #include "stm32f10x_it.h" #include "bsp_usart.h" /** @addtogroup STM32F10x_StdPeriph_Template * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /******************************************************************************/ /* Cortex-M3 Processor Exceptions Handlers */ /******************************************************************************/ /** * @brief This function handles NMI exception. * @param None * @retval None */ void NMI_Handler(void) { } /** * @brief This function handles Hard Fault exception. * @param None * @retval None */ void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } } /** * @brief This function handles Memory Manage exception. * @param None * @retval None */ void MemManage_Handler(void) { /* Go to infinite loop when Memory Manage exception occurs */ while (1) { } } /** * @brief This function handles Bus Fault exception. * @param None * @retval None */ void BusFault_Handler(void) { /* Go to infinite loop when Bus Fault exception occurs */ while (1) { } } /** * @brief This function handles Usage Fault exception. * @param None * @retval None */ void UsageFault_Handler(void) { /* Go to infinite loop when Usage Fault exception occurs */ while (1) { } } /** * @brief This function handles SVCall exception. * @param None * @retval None */ void SVC_Handler(void) { } /** * @brief This function handles Debug Monitor exception. * @param None * @retval None */ void DebugMon_Handler(void) { } /** * @brief This function handles PendSVC exception. * @param None * @retval None */ void PendSV_Handler(void) { } /** * @brief This function handles SysTick Handler. * @param None * @retval None */ void SysTick_Handler(void) { } void DEBUG_USART_IRQHandler(void) { uint8_t ucTemp; if (USART_GetITStatus(DEBUG_USARTx, USART_IT_RXNE) != RESET) { ucTemp = USART_ReceiveData(DEBUG_USARTx); USART_SendData(DEBUG_USARTx,ucTemp); } }
Keil5編程總覽:

3. 執行結果:
打開串口調試助手,配置好串口、波特率等參數。按下開發板上的復位鍵,接收區域顯示A

4. 參考資料
- 原理圖

- 編程要點
- 使能RX和TX引腳GPIO時鍾和USART時鍾;
- 初始化GPIO,並將GPIO復用到USART上;
- 配置USART參數;
- 配置中斷控制器並使能USART接收中斷;
- 使能USART;
- 在USART接收中斷服務函數實現數據接收和發送。
5. 總結
- 串口時鍾使能與控制器使能的關系:為何USART時鍾使能了,還需要在配置USART控制器的時候再使能一次?(為什么需要同時打開串口時鍾和GPIO時鍾)
- 轉自:STM32之串口通信 (bbsmax.com)
-
//打開GPIO時鍾
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
//打開串口USART時鍾
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
- (1)USART的時鍾使能
- Note: 當外部時鍾沒有被激活時,外設寄存器值可能不可讀,並且返回值為0x0.

- (2)USART控制器使能

- 寄存器內部控制關系圖
-

RCC_APB2ENR: 控制APB2時鍾是否供應給USART控制器
USART_CR1: 控制USART控制器的分頻器和輸出是否工作
- USART1要用到GPIOA的復用管腳輸入輸出功能,不使能的話只能內部串口外設工作,但是沒辦法與外界(即串口線)通信。也就是說只使
- 能USART1的話就只是讓USART1這個外設工作,GPIOA作為一個USART1與外界通信的橋梁沒有打通,所以不行。
6. 常見的幾種通訊協議的參數
轉自:
(71條消息) 通信方式梳理:GPIO,I2C,SPI,UART,USART,USB的區別_步印的博客-CSDN博客_gpio i2c spi uart

