學習於:野火stm32F429教程

為了和我們的EC20模塊進行通信,有必要複習一下32的串口通信先,打好基礎。

按數據的傳輸方式分:並行通信和串列通信

首先分清楚什麼是串列通信和並行通信: 如圖

同一時刻可以同時傳輸多位數據位的即並行通信,同一時刻只能傳輸一位數據位的即串列通信

然後看一下兩者的對比:

最好有相應得基礎,不然可能不太好理解。

根據數據通訊的方向,通訊又分為全雙工、半雙工及單工通訊。

示意圖如下:

操作系統里的管道就是半雙工通信。

tcp就是全雙工的通信方式。

根據通訊的數據同步方式,又分為同步和非同步兩種,可以根據通訊過程中是否有使用 到時鐘信號進行簡單的區分。

在同步通訊中,收發設備雙方會使用一根信號線表示時鐘信號,在時鐘信號的驅動下 雙方進行協調,同步數據。通訊中通常雙方會統一規定在時鐘信號的上升沿或 下降沿對數據線進行採樣。 如下圖:

在非同步通訊中不使用時鐘信號進行數據同步,它們直接在數據信號中穿插一些同步用 的信號位,或者把主體數據進行打包,以數據幀的格式傳輸數據,某些通訊中 還需要雙方約定數據的傳輸速率,以便更好地同步。 如下圖:

對計算機網路熟悉一點的同學就很容易理解這個非同步通訊了。哈哈。

通訊速率

衡量通訊性能的一個非常重要的參數就是通訊速率,通常以比特率(Bitrate)來表示,即 每秒鐘傳輸的二進位位數,單位為比特每秒(bit/s)。容易與比特率混淆的概念是「波特率」 (Baudrate),它表示每秒鐘傳輸了多少個碼元。而碼元是通訊信號調製的概念,通訊中常用 時間間隔相同的符號來表示一個二進位數字,這樣的信號稱為碼元。如常見的通訊傳輸中, 用 0V 表示數字 0,5V 表示數字 1,那麼一個碼元可以表示兩種狀態 0和 1,所以一個碼元 等於一個二進位比特位,此時波特率的大小與比特率一致;如果在通訊傳輸中,有 0V、 2V、4V 以及6V 分別表示二進位數 00、01、10、11,那麼每個碼元可以表示四種狀態, 即兩個二進位比特位,所以碼元數是二進位比特位數的一半,這個時候的波特率為比特率的一半。因為很多常見的通訊中一個碼元都是表示兩種狀態,人們常常直接以波特率來表 示比特率,雖然嚴格來說沒什麼錯誤,但希望您能了解它們的區別。

沒錯,火哥的講解總是非常通俗易懂。咦~

然後來看串口通訊:

首先來回憶一些基礎:

根據通訊使用的電平標準不同,串口通訊可分為 TTL 標準及 RS-232 標準

我們知道常見的電子電路中常使用 TTL的電平標準,理想狀態下,使用 5V 表示二進 制邏輯 1,使用 0V 表示邏輯 0;而為了增加串口通訊的遠距離傳輸及抗干擾能力,它使用+15V 表示邏輯 1,-15V 表示邏輯 0。使用 RS232與 TTL電平校準表示同一個信號時的對比 見下圖

因為控制器一般使用 TTL電平標準,所以常常會使用 MAX232 晶元對 TTL及 RS-232 電平的信號進行互相轉換。

後面總之就是RXD接TXD就完事了。

STM32晶元具有多個 USART 外設用於串口通訊,它是 Universal Synchronous Asynchronous Receiver and Transmitter的縮寫,即通用同步非同步收發器可以靈活地與外部設 備進行全雙工數據交換。有別於 USART,它還有具有 UART 外設(Universal Asynchronous Receiver and Transmitter),它是在 USART 基礎上裁剪掉了同步通信功能,只有非同步通信。 簡單區分同步和非同步就是看通信時需不需要對外提供時鐘輸出,我們平時用的串口通信基 本都是 UART

USART 支持使用 DMA,可實現高速數據通信

USART 在 STM32應用最多莫過於「列印」程序信息,一般在硬體設計時都會預留一 個 USART 通信介面連接電腦,用於在調試程序是可以把一些調試信息「列印」在電腦端 的串口調試助手工具上,從而了解程序運行是否正確、指出運行出錯位置等等。

STM32的 USART 輸出的是 TTL電平信號,若需要RS-232標準的信號可使用 MAX232晶元進行轉換。

USART_DR包含了已發送的數據或者接收到的數據。USART_DR實際是包含了兩個 寄存器,一個專門用於發送的可寫 TDR,一個專門用於接收的可讀 RDR。當進行發送操 作時,往 USART_DR寫入數據會自動存儲在 TDR內;當進行讀取操作時,向 USART_DR 讀取數據會自動提取 RDR數據。 TDR 和 RDR 都是介於系統匯流排和移位寄存器之間。串列通信是一個位一個位傳輸的, 發送時把 TDR內容轉移到發送移位寄存器,然後把移位寄存器數據每一位發送出去,接收時把接收到的每一位順序保存在接收移位寄存器內然後才轉移到 RDR

然後就不多說廢話了,開始串口通信的程序:

首先我這裡為了方便,另外使用了正點原子的ST_Link的下載器,這個下載器不像DAP下載器那樣不需要驅動,需要自己手動安裝驅動:pan.baidu.com/s/1cmreV0 。然後在keil5里把DAP-CMSIS改成ST_LINK即可,然後把下面的jtag改為SWD即可。

然後程序的主要功能是PC發一個字元串到32,然後32返回同樣的字元串即可。

main.c

#include "stm32f4xx.h"
#include "./usart/bsp_debug_usart.h"
int main(void)
{
Debug_USART_Config();

Usart_SendString( DEBUG_USART,"?aê?ò???′??ú?D???óê?????êμ?é
");
printf("?aê?ò???′??ú?D???óê?????êμ?é
");

while(1)
{

}
}

亂碼是由於複製到知乎里的編碼錯誤問題。

感覺全部複製過來不太合適,這裡就說幾點注意的地方:

1.GPIO時鐘和串口時鐘都要打開 RCC_AHB1PeriphClockCmd(DEBUG_USART_RX_GPIO_CLK|DEBUG_USART_TX_GPIO_CLK,ENABLE);

RCC_APB2PeriphClockCmd(DEBUG_USART_CLK, ENABLE);

2.GPIO初始化,設置引腳復用。

3.NVIC的配置

4.使能串口接收中斷和串口。

這裡由於很久沒寫32了,接近兩年了。看這個中斷控制器有點懵,總結一下就是

static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

這裡的配置中斷源 DEBUG_USART_IRQ,對應stm32f4xx_it.c文件里的DEBUG_USART_IRQHandler函數,這個函數需要自己重寫,這裡由於要接收串口數據,所以這裡要包含串口的封裝函數,調用裡面我們封裝好的函數。如下:

USART_GetITStatus 函數與 USART_GetFlagStatus函 數類似用來獲取標誌位狀態,但 USART_GetITStatus 函數是專門用來獲取中斷事件標誌的, 並返回該標誌位狀態。使用 if 語句來判斷是否是真的產生 USART 數據接收這個中斷事件, 如果是真的就使用 USART 數據讀取函數 USART_ReceiveData讀取數據到指定存儲區。然 後再調用 USART 數據發送函數 USART_SendData把數據又發送給源設備。

然後就結束了。

許久不看,還是感覺32的中斷系統和定時器有點複雜,得花點時間去慢慢複習一下。

哇,還是在這個操作系統上操作線程舒服。。今天消化得東西有點多,到這裡結束先吧。後面嘗試把串口通信使用到EC20模塊上,然後結合AT指令控制模塊進行tcp通信。

歡迎交流討論。

推薦閱讀:

相关文章