本章概述思維導圖
通信介紹
通信介紹概況
通信,至少是需要兩個對象,一個收一個發數據。
根據數據通信的傳輸時序協調方式,可分為:同步通信和異步通信;
根據數據通信的傳輸線路可分為:串行通信和并行通信;
根據數據通信的傳輸方向性及雙向交互能力可分為:單工通信和雙工通信(半雙工通信和全雙工通信)
同步通信和異步通信定義
同步通信:發送方與接收方通過共享時鐘線的時鐘信號,確保數據按固定時間間隔傳輸,接收方能準確預測數據到達時間;
異步通信:發送方與接收方無共享時鐘線,通過數據包或數據幀格式(如起始信號/停止位)協調傳輸數據;
同步和異步的區別:同步通訊需要有時鐘信號控制,通過時鐘線的高低電平控制數據的收發;異步通信沒有時鐘信號控制,通過數據幀格式控制數據的收發(大家約定好通信速度(波特率));
小心得:就是一個有時鐘線提供時鐘時序,一個沒有時鐘線;
串行通信和并行通信定義
串行通信:數據按位順序傳輸,使用單條線路進行數據得傳輸。例如,發送字節?10110010
?時,先傳?1
,再傳?0
,以此類推。
并行通信:數據的多個位(通常8位、16位等)同時通過多條線獨立線路并行傳輸。如傳輸字節?10110010
,會使用8根數據線,每根線同時傳1位。
串行和并行的區別;
串行通信指同一時刻,只能收或發一個bit位信息,因此只用一根數據信號線即可;并行通信指同一時刻,可以收或發多個bit位信息,因此需要多根數據信號線才行;
單工和半雙工、全雙工定義
單工通信:數據僅能沿固定方向單向傳輸,發送端與接收端角色不可互換。
應用場景:廣播系統(電臺→聽眾、衛星數據下行)、傳感器網絡(如溫濕度傳感器→數據中心)等;
半雙工通信:同一信道分時復用,雙方交替發送和接收;
應用場景:對講機、傳統Wi-Fi;
全雙工通信:雙方可同時發送和接收數據;
應用場景:電話通話、以太網交換機等;
單工和半雙工、全雙工的區別:
單工通信:單工要么收要么發,只能做接收設備或者發送設備。接收器不能發送數據給 ?發送器。例如:收音機;?
半雙工通信:雙發都可以發送數據,雙方不能同時發送數據或接收數據;只有一根發送/接收數據信號線。(特點:可以收可以發,但是不能同時收發)例如:對講機;?
全雙工通信:雙方可以同時發送或者接收數據;有兩根發送/接收數據信號線;(特點:可以同時即發送又接收數據)例如:手機
USART串口通信
串口(USART)通訊:異步通訊、全雙工、串行通訊、總線協議;
USART通用同步異步收發器,是一種通用的串行、異步/同步通信總線。該總線有兩條數據信號線,可以實現全雙工的發送和接收;
波特率:用于描述USART串口通信時的通信速度,其單位(bps)即每秒鐘傳送的位(bit) 的數量
上位機:就是連接串口的電腦或者手機上的APP軟件;是在自動化控制系統中,用于監控 和控制下位機(如單片機、PLC等)的計算機。它可以直接發送操作指令給下位機, 并接收下位機的反饋數據,通過用戶操作交互界面向用戶展示數據。
USART采用幀格式從低位開始發送數據——>高位
串口通信是不允許連續發送,避免累積誤差。所以發送完一字節數據后就得停止重新發送;
USART1串口1電路原理圖
1. 分析原理圖,查看對應引腳
分析原理圖這是串口USART1實現下載程序功能
我們不能隨意配置USART1的引腳,要根據STM32F103X引腳定義手冊來查看USART1配置的引腳;
TXD發送數據腳--->PA10(數據接收腳)
RXD接收數據腳--->PA9 (數據發送腳)
串口屬于自行控制數據的收發,所以我們應設置GPIO引腳模式為復用模式;
發送對接收;PA10設置為復用輸入模式,PA9設置為復用輸出模式;
2. 配置串口1(USART1)模塊初始化函數
配置USART1串口初始化函數步驟:
1. 開時鐘
2. 對串口1模塊開啟復位時鐘,在取消復位;
3. 配置GPIO模式
4.?通過在USART_CR1寄存器上置位UE位來激活USART
5.?編程USART_CR1的M位來定義字長。
6.?在USART_CR2中編程停止位的位數。
7.?利用USART_BRR寄存器選擇要求的波特率。
8.?設置USART_CR1中的TE位,發送一個空閑幀作為第一次數據發送。
9.?設置USART_CR1的RE位。激活接收器,使它開始尋找起始位。
代碼示例:
#include "USART1.h"
/*USART1串口初始化函數形參bps——>保持通信的波特率PA10設置為輸入模式,PA9設置為復用輸出模式;
*/
void USART1_Init(u32 bps)
{
// 1. 開時鐘RCC->APB2ENR|=1<<2;//開啟PA時鐘;RCC->APB2ENR|=1<<14;//開啟USART1時鐘
// 2. 對串口1模塊開啟復位時鐘,在取消復位;RCC->APB2RSTR|=1<<14;//開啟USART1復位時鐘,復位這一步可以省略配置USART1步驟RCC->APB2RSTR&=~(1<<14);//取消復位時鐘,關閉復位
// 3. 配置GPIO模式GPIOA->CRH&=0xfffff00f;//清空PA10、PA9引腳模式GPIOA->CRH|=0x000008b0;//PA10輸入PA9輸出
// 4.通過在USART_CR1寄存器上置位UE位來激活USARTUSART1->CR1|=1<<13;
// 5.編程USART_CR1的M位來定義字長。USART1->CR1&=~(1<<12);
// 6.在USART_CR2中編程停止位的位數。USART1->CR2&=~(0x3<<12);
// 7.利用USART_BRR寄存器選擇要求的波特率。USART1->BRR=72000000/bps;
// 8.設置USART_CR1中的TE位,發送一個空閑幀作為第一次數據發送。USART1->CR1|=1<<3;
// 9.設置USART_CR1的RE位。激活接收器,使它開始尋找起始位。USART1->CR1|=1<<2;
}
3. USART1串口底層發送數據函數
USART1串口數據發送函數(以數據幀格式發送):
配置步驟:
1.把發送的數據放入到USART_DR數據寄存器
2.判斷USART_SR狀態寄存器的TXE(發送數據寄存器空)位數據是否發送完成
代碼示例:
/*USART1串口底層數據發送函數形參:temp——>發送的數據
*/
void USART1_TX(u8 *temp)
{while(*temp){USART1->DR=*temp++;while(&(USART1->SR&1<<7)){}}
}
測試USART1串口初始化函數和USART1串口底層發送函數
代碼示例:
#include "LED.h"
#include "Delay.h"
#include "SYSTICK.h"
#include "BEEP.h"
#include "KEY.h"
#include "USART1.h"
int main()
{LED_Init();//LED燈初始化函數BEEP_Init();//蜂鳴器初始化函數KEY_Init();//按鍵初始化函數USART1_Init(115200);//USART1串口1初始化函數USART1_TX((u8 *)"串口1初始化完成\n");//發送"串口1初始化完成"這句話while(1){}
}
測試結果:
4. 串口讀取/接收數據操作
操作步驟:
1. 首先判斷USART1_SR寄存器中RXNE(讀數據寄存器非空),置1表示收到數據,可以讀出。置0表示數據沒有收到;
2. 將收到數據返回給上位機終端顯示
代碼示例:
#include "LED.h"
#include "Delay.h"
#include "SYSTICK.h"
#include "BEEP.h"
#include "KEY.h"
#include "USART1.h"
int main()
{LED_Init();//LED燈初始化函數BEEP_Init();//蜂鳴器初始化函數KEY_Init();//按鍵初始化函數USART1_Init(115200);//USART1串口1初始化函數USART1_TX((u8 *)"串口1初始化完成\n");u8 dat=0;while(1){if(USART1->SR&1<<5){dat=USART1->DR;//讀取數據USART1->DR=dat;//將讀取的數據在上位機軟件顯示}}
}
上位機軟件發送數據給USART1串口判斷是否接收:
發送結果顯示:
5. printf( )打印函數使用USART1底層實現?
在我們以后項目開發過程中會遇到各種各樣的開發問題,使用printf( )函數可以讓我們快速方便的查找問題!解決問題!下面是利用串口1實現printf( )函數的底層實現;
配置步驟:
1.在<stdio.h>文件中查找函數fputc
2.創建printf( )打印函數
3.實現printf函數還需在keil v5中的魔法棒中第二個選項卡Target中勾選右上角的Use Micro LIB;
代碼示例:
/*printf函數底層接口實現形參:tx——發送的內容注意:不需要聲明喲!
*/
int fputc(int tx, FILE *stream)
{USART1->DR=tx;while(!(USART1->SR&1<<7)){}return tx;
}
第三步操作:
測試printf( )函數實現代碼示例:
#include "USART1.h"
#include "stdio.h"
int main()
{USART1_Init(115200);//USART1串口1初始化函數printf("大河向東流哇\n天上的星星參北斗哇\n嘿嘿 參北斗哇\n生死之交一碗酒哇\n說走咱就走哇\n你有我有全都有哇\n嘿嘿 全都有哇\n");while(1){}
}
測試結果
6. 顯示USART1接收到的數據
代碼示例:
#include "stm32f10x.h"
#include "Delay.h"
#include "USART.h"
#include <stdio.h>int main()
{USART1_Init(115200);//串口1初始化函數USART1_TX((u8 *)"串口1初始化成功\n");u8 dat; //讀取數據 u8 buffer[100];//接收數據的數組 u8 cnt=0;//下標while(1){if(USART1->SR&1<<5){dat=USART1->DR;//讀取數據buffer[cnt]=dat;//將讀取的數據放入到數組中if(dat == '\n'){buffer[cnt-1]='\0';//上位機軟件設置時以\r\n結尾。手動把\r改成數組結束標準符printf("buf=%s;\tcnt=%d\n",buffer,cnt);cnt=0;}else cnt++;}}
}
制作不易!喜歡的小伙伴給個小贊贊!喜歡我的小伙伴可以點關注!有不懂的地方和需要的資源隨時問我喲!