国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【STM32】標準庫與HAL庫對照學習教程八--串口通信詳解

yck / 4866人閱讀

摘要:異步通信與同步通信異步通信異步通信是指通信的發送與接收設備使用各自的時鐘控制數據的發送和接收過程。同步通信同步通信時要建立發送方時鐘對接收方時鐘的直接控制,使雙方達到完全同步。配置串口設置為異步通信基礎參數波特率為。

一、前言

本篇文章是對單片機串口通信的詳講,串口通信作為STM32單片機的一個重要功能,在程序調試中發揮著重要的作用,本篇從通信基本原理講解開始,一步一步讓您理解并會使用STM32的串口通信,實驗程序包括標準庫與HAL庫,例程為串口中斷通信實驗,您也可以點擊目錄跳轉到自己想看的內容。

二、準備工作

  • STM32F103開發板(我用的是普中的STM32F103ZE開發板)
  • cubemx軟件、keil 5(MDK)
  • USB轉串口模塊(CH340)

三、通信的基本概念

1、通信方式

通信的方式可以分為多種:

  • 按照數據傳送方式可分為串行通信和并行通信
  • 按照通信的數據同步方式,可分為異同通信和同步通信
  • 按照數據的傳輸方向又可分為單工、半雙工和全雙工通信

下面我們就來簡單介紹這幾種通信方式。

2、串行通信與并行通信

(1)串行通信

串行通信是指使用一條數據線,將數據一位一位地依次傳輸,每一位數據占據一個固定的時間長度。

  • 優點:傳輸線少,長距離傳送時成本低。
  • 缺點:數據的傳送控制比并行通信復雜且速度相對較慢。

(2)并行通信

并行通信通常是將數據字節的各位用多條數據線同時進行傳送,通常是8位、16位、32位等數據一起傳輸。

  • 優點:控制簡單、傳輸速度快。
  • 缺點:長距離傳送時成本高且接收方的各位同時接收存在困難,抗干擾能力差 。

3、異步通信與同步通信

(1)異步通信

異步通信是指通信的發送與接收設備使用各自的時鐘控制數據的發送和接收過程。
異步通信是以字符(構成的幀)為單位進行傳輸,字符與字符之間的間隙(時間間隔)是任意的。

優點:不要求收發雙方時鐘的嚴格一致,實現容易。
缺點:每個字符要附加2~3位用于起止位,各幀之間還有間隔,因此傳輸效率不高 。

(2)同步通信

同步通信時要建立發送方時鐘對接收方時鐘的直接控制使雙方達到完全同步。實現方法有外同步和自同步兩種。

優點:由于傳輸因此傳輸效率高。
缺點:同步實現困難且開銷大。

4、單工、半雙工與全雙工通信

(1)單工通信

單工是指數據傳輸僅能沿一個方向,就是一個設備只管發送,一個設備只管接收。

(2)半雙工通信

半雙工是指數據傳輸可以沿兩個方向,但需要分時進行。也就是發送的時候不能接收,接收的時候不能發送。

(3)全雙工通信

全雙工是指數據可以同時進行雙向傳輸。也就是發送的時候可以接收,接收的時候可以發送。

5、通信速率

衡量通信性能的一個非常重要的參數就是通信速率,通常以比特率(Bitrate)來表示。
比特率每秒鐘傳輸二進制代碼的位數,單位是:位/秒(bps)。
例如:每秒鐘傳送200個字符,而每個字符格式包含10位(1個起始位、1個停止位、8個數據位),這時的比特率為:10位×200個/秒 = 2000 bps

四、STM32F1的USART介紹

1、串口通信簡介

串口通信(Serial Communication),是指外設和計算機之間,通過數據信號線、地線等,按位進行傳輸數據的一種通信方式,屬于串行通信方式
串口是一種接口標準,它規定了接口的電氣標準,沒有規定接口插件電纜以及使用的協議。

2、USART簡介

USART即通用同步異步收發器,它能夠靈活地與外部設備進行全雙工數據交換。UART即通用異步收發器,它是在USART基礎上裁剪掉了同步通信功能。STM32F103ZET6芯片含有3個USART,2個UART外設

3、USART結構框圖

圖片在STM32F1xx中文參考手冊 通用同步異步收發器章節

結構圖重點在框住的部分,通過寄存器USART_SRTXE、TC、RXNE位知道串口收發情況。

4、USART寄存器重點控制位

(1)TXE

TXE位USART_SR寄存器的第七位,為1時,TDR寄存器中的數據已經被轉移到移位寄存器,為0時,TDR寄存器中的數據還沒有被轉移到移位寄存器復位時為1TDR寄存器中有數據時,該位立即為0

(2)TC

TC位USART_SR寄存器的第六位,為1時,移位寄存器中的數據發送完成,為0時,移位寄存器還有數據復位時為1需要手動清0,或者進行讀操作讓其為0

(3)RXNE

接收完數據時,該位為1,其他時候為0

5、STM32與PC主機通信的方法

串口數據收發線要交叉連接計算機的TXD要對應單片機的RXD計算機的RXD要對應單片機的TXD,并且共GND
如下圖:

五、USB轉串口模塊

單片機與電腦進行通信需要用到USB轉串口模塊,因為電腦上沒有RXD、TXD引腳,并且電腦還要安裝CH340的驅動
市場常見的USB轉串口模塊

接上電腦,TX接單片機的RX,RX接單片機的TX,電源與地接到單片機上就可以串口通信了。
電腦上的CH340驅動我放在網盤上了,有需要自己去下載。
https://pan.baidu.com/s/1bO7mpkwjkB19HXvmD0083Q
密碼:kpa6

六、標準庫使用串口中斷通信

一、配置步驟

(1)使能串口時鐘及GPIO端口時鐘
(2)GPIO端口模式設置,設置串口對應的引腳為復用功能
(3)初始化串口參數,包含波特率、字長、奇偶校驗等參數
(4)使能串口
(5)設置串口中斷類型并使能
(6)設置串口中斷優先級,使能串口中斷通道
(7)編寫串口中斷服務函數

二、配置工程


(1)復制上一章的工程,并重命名為8、串口中斷通信


(2)進入工程文件,進入APP文件,新建USART文件夾用來存放與串口相關的文件。


(3)打開工程,新建文件,并命名為usart.h與usart.c




(4)添加文件到目錄,并添加頭文件路徑




(5)要使用串口需要添加相應的文件




三、相關程序


mian.c

#include "LED.h"#include "Delay.h"#include "System.h"#include "usart.h"/**************************************************函數名:    main*函數功能: 主函數*輸入:     無  *返回值:   無**************************************************/int main(){		SysTick_Init(72);	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //搶占式優先級與響應式優先級的分組	LED_Init();	USART1_Init(9600);	while(1)	{		  	}}

usart.h

#ifndef USART_H_#define USART_H_#include "stm32f10x.h"/************串口引腳************/#define USART1_GPIO_Port  GPIOA#define USART1_RX_Pin     GPIO_Pin_10#define USART1_TX_Pin     GPIO_Pin_9/************串口函數************/void USART1_Init(u32 bound);          //串口初始化void USART_SendBit(USART_TypeDef* USARTx,u16 Data);   //發送單個數據uint16_t USART_ReceiveBit(USART_TypeDef* USARTx);     //接收單個數據void USART_SendString(USART_TypeDef* USARTx,char *string); //發送字符串#endif

usart.c

#include "usart.h"/**************************************************函數名:     USART1_Init*函數功能:   串口1的初始化*輸入:       bound:波特率   *返回值:     無**************************************************/void USART1_Init(u32 bound){	GPIO_InitTypeDef GPIO_InitStruct;	USART_InitTypeDef USART_InitStruct;	NVIC_InitTypeDef NVIC_InitStruct;		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE); //時鐘使能		GPIO_InitStruct.GPIO_Pin = USART1_TX_Pin;      //發送引腳	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;   //復用推挽輸出	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //發送速度	GPIO_Init(USART1_GPIO_Port, &GPIO_InitStruct); //引腳初始化		GPIO_InitStruct.GPIO_Pin = USART1_RX_Pin;      //接收引腳	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入	GPIO_Init(USART1_GPIO_Port, &GPIO_InitStruct); //引腳初始化		USART_InitStruct.USART_BaudRate = bound; //波特率	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; //8位一個字節	USART_Init(USART1, &USART_InitStruct); //初始化串口		USART_Cmd(USART1, ENABLE);  //串口使能		USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  //接收中斷使能		NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;  //要打開的中斷通道	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; //搶占式優先級	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;   //相應式優先級	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;  //NVIC通道使能	NVIC_Init(&NVIC_InitStruct);		USART_ClearFlag(USART1, USART_FLAG_TC); //TC位初始值位1,要先清0}//直接使用串口發送接收函數會出現內容覆蓋的問題,所以需要我們重寫函數/**************************************************函數名:      USART_SendBit*函數功能:    串口發送函數*輸入:        Data:發送的數據*返回值:      無**************************************************/void USART_SendBit(USART_TypeDef* USARTx,u16 Data)   {	USART_SendData(USARTx, Data);		//while(!USART_GetFlagStatus(USARTx, USART_FLAG_TXE));  //要等待數據全部轉到移位寄存器	//USART_ClearFlag(USARTx, USART_FLAG_TXE); //清空標志位		while(!USART_GetFlagStatus(USARTx, USART_FLAG_TC));//要等待數據全部發出	USART_ClearFlag(USARTx, USART_FLAG_TC); //清空標志位}/**************************************************函數名:       USART_ReceiveBit*函數功能:     串口接收函數*輸入:         USARTx:串口*返回值:       接收到的數據**************************************************/uint16_t USART_ReceiveBit(USART_TypeDef* USARTx){	while(!USART_GetFlagStatus(USARTx, USART_FLAG_RXNE)); //等待接收的數據全部接收	USART_ClearFlag(USARTx, USART_FLAG_RXNE);	return USART_ReceiveData(USARTx);}/**************************************************函數名:        USART_SendString*函數功能:      串口發送字符串函數*輸入:          USARTx:串口,string:字符型指針*返回值:        無**************************************************/void USART_SendString(USART_TypeDef* USARTx,char *string){	while(*string)	{		USART_SendBit(USARTx,*string++);	}}/**************************************************函數名:         USART1_IRQHandler*函數功能:       串口中斷函數-將從電腦發送的數據發回給電腦*輸入:           無*返回值:         無**************************************************/void USART1_IRQHandler(){	u16 r;	if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)  //判斷中斷標志	{		r = USART_ReceiveData(USART1);		USART_SendBit(USART1,r);	}}

四、實驗效果

七、HAL庫使用串口中斷通信

一、cubemx配置工程


(1) 打開cubemx,新建工程,選擇自己的芯片。


(2) 配置RCC,選擇外部高速時鐘


(3) 配置時鐘樹


(4) 配置串口

  • Mode設置為異步通信(Asynchronous)
  • 基礎參數:波特率為115200 Bits/s。傳輸數據長度為8 Bit。奇偶檢驗無,停止位1 接收和發送都使能 (默認的就行)
    打開串口中斷


(5) 工程文件配置并生成工程




二、常用函數講解


  • HAL_UART_Transmit();串口發送數據,使用超時管理機制
  • HAL_UART_Receive();串口接收數據,使用超時管理機制
  • HAL_UART_Transmit_IT();串口中斷模式發送(只觸發一次中斷)
  • HAL_UART_Receive_IT();串口中斷模式接收(只觸發一次中斷)
  • HAL_UART_Transmit_DMA();串口DMA模式發送
  • HAL_UART_Transmit_DMA();串口DMA模式接收
  • HAL_UART_GetState();判斷接收與發送是否結束

相關參數:

  • UART_HandleTypeDef *huart 串口的別名 如 : 我們使用串口USART1的別名就是huart1
  • *pData 需要發送的數據
  • Size 發送的字節數
  • Timeout 最大發送時間
  • HAL_UART_STATE_BUSY_RX,接收完成標志
  • HAL_UART_STATE_BUSY_TX,發送完成標志

回調函數

  • void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);//接收中斷回調函數
  • HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //發送中斷回調函數
  • void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); //串口發送一半中斷回調函數
  • void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回調函數

串口中斷接收完成之后,會進入該函數,該函數為空函數,用戶需自行修改。


三、主函數程序


#include "string.h"uint8_t Rx_String[100];    //接收字符串數組uint8_t Rx_Flag=0;         //接收字符串計數uint8_t Rx_buff;           //接收緩存

HAL_UART_Receive_IT(&huart1, (uint8_t *)&Rx_buff, 1);   //開啟接收中斷

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){	if(huart == &huart1)	{		Rx_String[Rx_Flag++] = Rx_buff;  //接收字符		if(Rx_String[Rx_Flag-1] == 0x0A) //判斷是否接收結束		{			HAL_UART_Transmit(&huart1, (uint8_t *)&Rx_String, Rx_Flag,0xFFFF); //字符串發送			while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX); //判斷發送是否完畢			memset(Rx_String,0x00,sizeof(Rx_buff)); //清空接收字符串			Rx_Flag = 0; //清空計數器		}		HAL_UART_Receive_IT(&huart1, (uint8_t *)&Rx_buff, 1);   //再開啟接收中斷	}}

四、實驗效果

八、關于printf重定向

C語言中printf函數默認輸出設備是顯示器,如果要實現在
串口或者LCD上顯示,必須重定義標準庫函數里調用的與輸出設備相關的函數。比如使用printf輸出到串口,需要將fputc里面的輸出指向串口
這一過程就叫重定向


對于標準庫
將這段程序加入主函數中

int fputc(int ch,FILE *p)  //函數默認的,在使用printf函數時自動調用{	USART_SendData(USART1,(u8)ch);		while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);	return ch;}int fgetc(FILE *p){  uint8_t ch = 0;  USART_SendData(USART1, ch);  return ch;}

并添加stdio.h頭文件,就可以使用C語言中的printf函數將字符串通過串口打印在電腦上了。


對于HAL庫
將這段程序加入主函數中

/**  * 函數功能: 重定向c庫函數printf到DEBUG_USARTx  * 輸入參數: 無  * 返 回 值: 無  * 說    明:無  */int fputc(int ch, FILE *f){  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);  return ch;} /**  * 函數功能: 重定向c庫函數getchar,scanf到DEBUG_USARTx  * 輸入參數: 無  * 返 回 值: 無  * 說    明:無  */int fgetc(FILE *f){  uint8_t ch = 0;  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);  return ch;}

并添加stdio.h頭文件,就可以使用C語言中的printf函數將字符串通過串口打印在電腦上了。


九、RS232補充說明(選看)

1、接口標準

串口通信的接口標準有很多,有RS-232C、RS-232、RS-422A、RS-485等。常用的就是RS-232和RS-485。RS-232其實是RS-232C的改進,原理是一樣的。這里我們就以RS-232C接口進行講解。
RS-232C是EIA(美國電子工業協會)1969年修訂RS-232C標準。RS-232C定義了數據終端設備(DTE)與數據通信設備(DCE)之間的物理接口標準。
RS-232C接口規定使用25針連接器,簡稱DB25,連接器的尺寸及每個插針的排列位置都有明確的定義 。

2、邏輯電平規定

RS-232C對邏輯電平也做了規定,如下:

  • 在TXD和RXD數據線上,邏輯1為(-3)V到(-15)V的電壓,邏輯0為3V到15V的電壓。
  • 在RTS、CTS、DSR、DTR和DCD等控制線上,信號有效(ON狀態)為3V到15V的電壓,信號無效(OFF狀態)為(-3)V到(-15V)的電壓。

由此可見,RS-232C是用正負電壓來表示邏輯狀態,與晶體管-晶體管邏輯集成電路(TTL)以高低電平表示邏輯狀態的規定正好相反

到這里就結束啦!

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/124044.html

相關文章

  • STM32串口通信HAL 二)

    摘要:緊接著上一篇博文。。。編寫串口中斷函數當中斷發生的時候,程序就會執行中斷服務函數,我們在中斷服務函數中編寫相應的邏輯代碼就可以了。將以下代碼編寫在中串口輸出重定義到注意頭文件需要包含標準庫,也就是。 ...

    frontoldman 評論0 收藏0
  • STM32CubeMX學習教程之硬件I2C讀取光照度

    摘要:使用庫讀寫環境光照度傳感器本文將教大家如何快速使用庫讀取光照度數據。五實驗樣機測試展示通過之前配置好的面板,通過涂鴉智能進行配網實時采集光照度傳感器的數據。 使用STM32 HAL庫讀寫環境光照度傳感器(BH1750) 本文將教大家如何快速使用STM32HAL庫讀取光照度數據。 實現功能:通...

    tinylcy 評論0 收藏0
  • 使用STM32CubeMX初始化STM32F031F6Px系列

    摘要:利用可視化界面來進行的相關配置,所以時鐘滴答定時器串口等就不用根據數據手冊去操作標準庫甚至是寄存器了,可以通過軟件直接生成。 使用STM32CubeMX初始化ST...

    Zhuxy 評論0 收藏0
  • 串口通信中關鍵知識點4

    摘要:串口波特率設置。串口的狀態可以通過狀態寄存器讀取。關閉接收完成中斷使能中斷通道搶占優先級,子優先級第五編寫中斷服務函數第六串口數據接收和發送發送與接收是通過數據寄存器來實現。 ? ? ? ?串口基本配置的寄存器,配置過程總結為: 1、串口時鐘使能。這里的串口1設置是APB2ENR寄存器的第4...

    zgbgx 評論0 收藏0
  • STM32學習筆記 第二章 STM32資源介紹

    摘要:總線掛載的外設有等。外設地址映射片上外設區分為三條總線,根據外設速度的不同,不同總線掛載著不同的外設,掛載低速外設,和掛載高速外設。 第二章 STM32資源介紹 2...

    G9YH 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<