👨?💻個人主頁:@開發者-削好皮的Pineapple!
👨?💻 hello 歡迎 點贊👍 收藏? 留言📝 加關注?!
👨?💻 本文由 削好皮的Pineapple! 原創
👨?💻 收錄于專欄:C語言到基于STM32 的智能礦探小車
文章目錄
- 🎶一、UART通信
- 🎶二、基于STM32F407固件庫UART的配置流程
- 2.1 時鐘使能
- 2.2 GPIO的配置
- 2.3 把GPIO復用成對應的串口
- 2.4 串口初始化
- 2.5 串口中斷的配置
- 2.6 NVIC的配置
- 2.7 打開串口
- 2.8 中斷服務函數的格式
- 2.9串口接收數據/發送數據的接口
- 🎶三、HC05模塊
- 結束語🥇
?前言?
-本文是對UART通信、基于STM32F407固件庫UART的配置流程以及HC05模塊相關知識的筆記總結,涵蓋了通信的基本概念、配置步驟和模塊使用等內容,旨在為后續的嵌入式開發提供參考。
🎶一、UART通信
- UART 是異步全雙工串行通信。
- 通信的前提:通信雙方要同步。
- 同步機制和異步機制的區別在于通信雙方是否有相同的參考(時鐘線)。
- 有通用時鐘線屬于同步機制。
- 沒有通用時鐘線屬于異步機制。
- 異步:通信雙方沒有通用時鐘線,通信雙方需要提前約定用相同的波特率進行通信。
- 同步機制和異步機制的區別在于通信雙方是否有相同的參考(時鐘線)。
- 單工通信:A 單向發送數據到 B(A ----> B)。
- 雙工通信:
- 半雙工通信:接收數據和發送數據不能夠同時進行(A ------> B 與 A <------ B 不同時)。
- 全雙工通信:接收數據和發送數據可以同時進行(A ------> B 與 A <------ B 同時)。
- 串行:發送/接收數據只用了一根數據線,每次只能 1bit 1bit 發送/接收。
- 支持串口(UART)通信的設備通常具有如下引腳:
設備A 設備B Tx Rx Rx Tx VCC VCC GND GND - 對于STM32F407本次使用的開發板上提供了三個UART引腳:P4(UART1)、P5(UART2)和P6(UART3)處。
🎶二、基于STM32F407固件庫UART的配置流程
2.1 時鐘使能
- 使能對應GPIO時鐘:
RCC_AHB1PeriphClockCmd
。 - 使能對應的USARTx(USART1、USART2和USART3)時鐘:
- 對于USART1,應該使用
RCC_APB2PeriphClockCmd
。 - 對于USART2和USART3,應該使用
RCC_APB1PeriphClockCmd
。
- 對于USART1,應該使用
2.2 GPIO的配置
- 使用
GPIO_Init
函數配置。- Tx:復用模式,推挽模式。
- Rx:復用模式,浮空模式。
- 注意:對于通信一般選擇高速電平切換。
2.3 把GPIO復用成對應的串口
- 使用
GPIO_PinAFConfig
函數,函數格式為:GPIO_PinAFConfig(GPIO_TypeDef * GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
。GPIOx
:指定具體的GPIO組號,如GPIOA、GPIOB等。GPIO_PinSource
:指定具體的引腳編號,如GPIO_PinSource0、GPIO_PinSource1……GPIO_PinSource15。GPIO_AF
:指定具體要復用成的功能,如GPIO_AF_USART1(復用成串口1的引腳)、GPIO_AF_USART2(復用成串口2的引腳)等。
- 注意:該接口不支持位或。例如UASRT1的Tx接PA9,Rx接PA10時,配置如下:
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9 , GPIO_AF_UASRT1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10 , GPIO_AF_UASRT1);
2.4 串口初始化
- 使用
USART_Init
函數,函數格式為:USART_Init(USART_TypeDef * USARTx, USART_InitTypeDef * USART_InitStruct)
。USARTx
:指定具體的串口,如USART1、USART2、USART3。USART_InitStruct
結構體成員:USART_BaudRate
:指定具體的波特率,如115200、9600等。USART_WordLength
:指定數據位,常用USART_WordLength_8b
。USART_StopBits
:指定停止位,常用USART_StopBits_1
。USART_Parity
:奇偶校驗位,常用USART_Parity_No
(無校驗),還有USART_Parity_Even(偶校驗)、USART_Parity_Odd(奇校驗)。USART_Mode
:指定串口模式,USART_Mode_Rx
(接收數據)、USART_Mode_Tx
(發送數據)、USART_Mode_Rx | USART_Mode_Tx
(收發數據)。USART_HardwareFlowControl
:硬件控制流,常用USART_HardwareFlowControl_None
(無控制流)。
2.5 串口中斷的配置
- 使用
USART_ITConfig
函數,函數格式為:USART_ITConfig(USART_TypeDef * USARTx, uint16_t USART_IT, FunctionalState NewState)
。USARTx
:指定具體的串口,如USART1、USART2、USART3。USART_IT
:指定觸發因素,如USART_IT_RXNE
(接收數據觸發中斷)。NewState
:ENABLE
(使能)。
2.6 NVIC的配置
- 使用
NVIC_Init
函數,中斷通道分別為USART1_IRQn
、USART2_IRQn
等。
2.7 打開串口
- 使用
USART_Cmd
函數,函數格式為:USART_Cmd(USART_TypeDef * USARTx, FunctionalState NewState)
。USARTx
:指定具體的串口,如USART1、USART2、USART3。NewState
:ENABLE
(使能)。
2.8 中斷服務函數的格式
- 以USART1為例:
void USART1_IRQHandler(void) {if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET) //接收到數據{//...USART_ClearITPendingBit( USART1, USART_IT_RXNE);} }
2.9串口接收數據/發送數據的接口
-
接收數據:
USART_ReceiveData(USART_TypeDef * USARTx)
USARTx
:指定用什么串口接收數據,如USART1、USART2、USART3。- 返回值:返回接收到的數據。
- 說明:由于不能預料對方什么時候發送數據,一般開啟串口接收數據的中斷,該接口一般在中斷服務函數中調用。
-
發送數據:
USART_SendData(USART_TypeDef * USARTx, uint16_t Data)
USARTx
:指定用什么串口發送數據,如USART1、USART2、USART3。Data
:要發送的數據。
-
相關配置修改:
- 在
smt32f4xx.h
的第144行HSE_VALUE
為8000000。 - 在
system_stm32f4xx.c
的第371行把25修改成8即可。 - 串口1用來下載程序,可按照串口1的配置流程,實現串口2和串口3的配置。
- 在
#include "stm32f4xx.h"
#include "uart.h"//串口1為例 Tx (PA9) Rx(PA10)
void uart_init(int bond)
{GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;NVIC_InitTypeDef NVIC_InitStruct;//1.時鐘使能RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//2.GPIO初始化//TX 復用推挽GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;GPIO_Init(GPIOA, & GPIO_InitStruct);//RX 復用浮空GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;GPIO_Init(GPIOA, & GPIO_InitStruct);//3.把GPIO復用成對應的功能GPIO_PinAFConfig( GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig( GPIOA, GPIO_PinSource10, GPIO_AF_USART1);//4.串口初始化USART_InitStruct.USART_BaudRate = bond;//指定波特率USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_InitStruct.USART_Parity = USART_Parity_No;USART_InitStruct.USART_StopBits = USART_StopBits_1;USART_InitStruct.USART_WordLength = USART_WordLength_8b;USART_Init(USART1, &USART_InitStruct);//5.串口接收數據中斷USART_ITConfig( USART1, USART_IT_RXNE, ENABLE);//6.NVIC的配置NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;NVIC_Init(&NVIC_InitStruct);//7.打開串口USART_Cmd( USART1, ENABLE);
}u8 recv; //串口1接收數據//串口中斷服務函數
void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET) //接收到數據{recv = USART_ReceiveData(USART1);USART_SendData(USART1, recv);USART_ClearITPendingBit( USART1, USART_IT_RXNE);}
}
#ifndef __UART_H__
#define __UART_H__
#include "stm32f4xx.h"//串口1為例 Tx (PA9) Rx(PA10)
void uart_init(int bond);extern u8 recv;#endif
🎶三、HC05模塊
- HC05模塊與單片機的連接:
HC05模塊 單片機 VCC 5V GND GND TXD(發送數據的引腳) 單片機的RX RXD(接收數據的引腳) 單片機的TX
-
藍牙的相關信息:
- 藍牙的連接密碼:1234。
- 藍牙的設備名稱:需要通過AT指令修改。
-
修改藍牙設備名稱的方法:
- 接線:
- VCC ----------- P4處的5V
- GND ----------- P4處的GND
- TX ---------- UART1處的1號引腳
- RX ---------- UART1處的2號引腳
- 如果按住按鈕發送沒有反應:
- 按住按鈕重新給藍牙模塊上電,直到藍牙模塊上的指示燈閃爍變慢,說明此時進入了AT指令模式。
- 把波特率更改成38400,再嘗試發送
AT+NAME=XXX
【回車】。
- 接線:
-
注意:請用手機配對自己的藍牙設備,為了避免麻煩,藍牙建議使用串口2或者串口3。
-
工作原理:
- 手機與藍牙模塊通過無線信號連接,藍牙模塊和單片機之間通過串口(USART2、USART3)通信。
- 手機發送給藍牙模塊的數據,藍牙模塊會完完整整的通過串口發送給單片機。
- 連接方式為 TX -------------- RX,RX -------------- TX。
- 在主函數直接調用,用手機藍牙串口APP控制小車的運動狀態。
#include "stm32f4xx.h"
#include "exit.h"
#include "car.h"
#include "delay.h"
//#include "remote.h"
#include "uart.h"
#include "led.h"// 聲明全局變量recv
extern uint8_t recv;int main(void) {SystemInit();car_init();//remote_Init();delay_init(); // 初始化定時器led_init();uart_init(9600); // 初始化串口通信while(1) {if(recv == '1') {led_ctrl(D4, ON);}else if(recv == 'F') {car_up();}else if(recv == 'B') {car_back();}else if(recv == 'L') {car_left();}else if(recv == 'R') {car_right();}else if(recv == 'S') {car_stop();}delay_ms(1); // 實現實時循環,控制循環頻率}
}
結束語🥇
🔥 訂閱專欄持續學習:C語言到基于STM32的智能礦探小車
💬 歡迎點贊、收藏、留言討論,一起攻克嵌入式開發!