在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何來編寫一個串口收發程序

汽車電子技術 ? 來源:物聯網知識 ? 作者: 跋扈洋 ? 2023-01-20 16:43 ? 次閱讀

介紹

串口(UART通用異步收發器,TTL)通訊是一種設備間的串行全雙工通訊方式。由于UART是異步傳輸,沒有傳輸同步時鐘,為了保證數據的正確性,UART采用16倍數據波特率的時鐘進行采樣。因為它簡便捷,因此大部分電子設備都支持該通訊方式工程師在調試設備時也經常使用該方式輸出調試信息

本文詳細的介紹如何來編寫一個串口收發程序,我們采用常用的收發邏輯,發送直接編寫函數進行實現,而接收使用中斷進行完成。接收中斷使用接收到一個字節和一幀數據兩種中斷觸發方式。

USART中斷

USART 有多個中斷請求事件。微信截圖_20230105161930.png

之所以介紹這個USART中斷請求,是因為很多人在初學階段,對串口怎么判斷串口中斷的狀態不太了解,所以我這里重點來介紹一下。

一般在我們開始和配置完串口中斷后,進入串口中斷處理程序的情況會有很多,我們也可以自己選擇打開哪些串口中斷情況。一般情況下,我們在接受時主要使用的中斷事件標志是RXNE和IDLE。

RXNE是接收中斷,每接收一個字節都會出發這個中斷,也是我們用的最頻繁的中斷請求。

IDLE 是空閑中斷,每接收完一幀數據,總線就會暫時空閑,就會觸發這個中斷。

串口狀態

串口的狀態可以通過狀態寄存器 USART_SR 讀取。USART_SR 的各位描述如下:微信截圖_20230105161930.png

這里我們關注一下兩個位,第 5、6 位 RXNE 和 TC。

RXNE(讀數據寄存器非空),當該位被置 1 的時候,就是提示已經有數據被接收到了,且可以讀出來了。這時候我們要做的就是盡快去讀取 USART_DR,通過讀 USART_DR 可以該位清零,也可以向該位寫 0,直接清除。

TC(發送完成),當該位被置位的時候,表示 USART_DR 內的數據已經被發送完成了。果設置了這個位的中斷,則會產生中斷。該位也有兩種清零方式:

  1. 讀 USART_SR,USART_DR。
  2. 直接向該位寫 0。

實例

需求分析

本項目主要編寫一個串口收發的實例。使用STM32F103C8T6充當MCU,在PC上使用串口調試助手充當上位機。每次PC向MCU下發一幀數據, MCU每接收一個字節數據,檢查一下數據中是否有指令0x23,當接收到指令0x23的時候,MCU向上位機發送“PC”。當一幀數據接收完畢后,MCU向上位機發送“Receive a frame data”.

串口初始化

串口初始化的一般步驟可以總結為如下幾個步驟:

  1. 串口時鐘使能,GPIO 時鐘使能。
  2. 設置引腳復用器映射:調用 GPIO_PinAFConfig 函數。
  3. GPIO 初始化設置:要設置模式為復用功能。
  4. 串口參數初始化:設置波特率,字長,奇偶校驗等參數。
  5. 開啟中斷并且初始化 NVIC,使能中斷(如果需要開啟中斷才需要這個步驟)。
  6. 使能串口。
#include "usart.h"
#include 
#include "stm32f1xx_hal.h
UART_HandleTypeDef huart3
void MX_USART3_UART_Init(void)


  huart3.Instance = USART3;
  huart3.Init.BaudRate = 115200;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler()
  __HAL_UART_ENABLE_IT(&huart3,UART_IT_RXNE);//接收中斷使能
  __HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE);//空閑中斷使能 
}


void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)


  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART3)
  {
    __HAL_RCC_USART3_CLK_ENABLE()
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**USART3 GPIO Configuration
    PB10     ------> USART3_TX
    PB11     ------> USART3_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct)
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    HAL_NVIC_SetPriority(USART3_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(USART3_IRQn);

我們平時需要改的其實就是串口的一些參數配置。

  • BaudRate:波特率
  • WordLength;:字長
  • StopBits:停止位
  • Parity:奇偶校驗
  • Mode:收/發模式設置
  • HwFlowCtl:硬件流設置
  • OverSampling:過采樣設置

串口發送

串口發送這里使用的非中斷發送方式。

/*******************************************************************************
  * @函數名稱  USART_Send
  * @函數說明   發送信息
  * @輸入參數   _UART:串口號
      data:要發送的信息的首地址
      len:發送的長度
  * @輸出參數   無
  * @返回參數   無
*******************************************************************************/
void USART_Send(USART_TypeDef *_UART,uint8_t *data,uint8_t len)
{
  for(int i;i

主要使用的是HAL_UART_Transmit(&huart3,&Res,1,0Xffff);

這是一個阻塞的發送函數,無需重復判斷串口是否發送完成。發送每個字符,直到遇空字符才停止發送。其中第一個參數是串口號,第二個參數是要發送的數據起始地址,第三個是要發送的數據長度,第四個超時時間(超過此長度仍未發送成功則阻塞完畢,停止發送,函數執行完畢)。

串口接收

這里串口接收使用的是中斷的方式。

中斷的類別在文章的最上邊已經介紹過。我們在初始化時設定觸發中斷的類型。本文中設置的

__HAL_UART_ENABLE_IT(&huart3,UART_IT_RXNE);//接收中斷使能
__HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE);//空閑中斷使能

代表只有接收數據和空閑中斷會觸發。

在stm32f1xx_it.c中有我們的串口中斷處理函數。我們將這個函數進行重構。

void USART3_IRQHandler(void)
{
  uint8_t Res;
if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_RXNE)!=RESET
{
  HAL_UART_Receive(&huart3,&Res,1,0Xffff); 
 if(Res==0x23)  
  printf("PC");
}
else if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)!=RESET)//空閑中斷(代表這一幀數據傳輸完了)
{
  printf("Receive a frame data.");
  __HAL_UART_CLEAR_IDLEFLAG(&huart3);
}

這里面的幾個重點,我們來一一介紹。

首先是判斷標志位,我們使用HAL庫中的__HAL_UART_GET_FLAG()函數,里面有兩個參數,前者是串口句柄,后者是具體哪個標志位。

if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_RXNE)!=RESET)用來檢測是否檢測到有單個字節的中斷。

if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)!=RESET)用來檢測是否有空閑中斷(代表這一幀數據傳輸完了)。

重定向printf和scanf

還有一點需要注意的,使用 fput 和 fgetc 函數達到重定向 C 語言標準庫輸入輸出函數必須在 MDK 的工程選項把“Use MicroLIB”勾選上, MicoroLIB 是缺省 C 庫的備選庫,它對標準 C 庫進行了高度優化使代碼更少,占用更少資源

為使用 printf、 scanf 函數需要在文件中包含 stdio.h 頭文件。

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

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

效果

  1. PC下發:11 22 33 44

    微信截圖_20230105161930.png

  2. PC下發:12 23 34 45

    微信截圖_20230105161930.png

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 收發器
    +關注

    關注

    10

    文章

    3440

    瀏覽量

    106117
  • 串口
    +關注

    關注

    14

    文章

    1557

    瀏覽量

    76738
  • uart
    +關注

    關注

    22

    文章

    1242

    瀏覽量

    101540
收藏 人收藏

    評論

    相關推薦

    【紫光同創國產FPGA教程】【第五章】串口收發實驗

    本文主要講解如何編寫FPGA串口通信的收發程序,在程序中使用了狀態機,是學習狀態機的重要實驗。
    的頭像 發表于 02-04 13:23 ?6782次閱讀
    【紫光同創國產FPGA教程】【第五章】<b class='flag-5'>串口</b><b class='flag-5'>收發</b>實驗

    編寫一個QT程序

    學習種編程語言或編程環境,通常會先編寫“Hello World”程序。我們也用 Qt Creator
    發表于 11-21 10:41 ?1040次閱讀

    如何去編寫種基于Atmega8單片機的串口收發程序

    如何去編寫種基于Atmega8單片機的串口收發程序?有大神遇到過這個問題嗎
    發表于 07-08 06:06

    如何利用AVR編寫簡單的串口通信的程序

    如何利用AVR編寫簡單的串口通信的程序
    發表于 11-02 08:06

    STM32的串口收發程序如何編寫

    STM32的串口收發程序如何編寫
    發表于 12-16 07:34

    怎樣去編寫串口數據接收程序

    【嵌入式】串口數據接收程序1.題目詳情2.代碼詳解1.題目詳情編寫串口數據接收
    發表于 12-21 06:12

    分享串口收發的小程序功能

    串口收發的小程序功能就是串口數據的收發;設置標題
    發表于 01-18 07:53

    求大佬分享stm32自收發串口通信程序

    求大佬分享stm32自收發串口通信程序
    發表于 02-18 07:40

    VHDL設計的串口通信程序

    本模塊的功能是驗證實現和PC機進行基本的串口通信的功能。需要在PC機上安裝串口調試工具來驗證程序的功能。
    發表于 06-05 12:03 ?2865次閱讀

    labview串口編寫中可能用到的程序

    串口編寫中可能用到的程序
    發表于 01-03 16:49 ?10次下載

    如何使用Python編寫簡單的程序

    按照軟件行業傳統習慣,當你學習種新的編程語言如Python時,首先編寫“Hello World! ”程序。請執行以下步驟,以創造你的“
    的頭像 發表于 01-16 15:21 ?2.2w次閱讀

    verilog編寫UART串口程序下載

    收發程序寫在.v文件中,已經在板子上實驗過,收發正常
    發表于 12-21 18:08 ?0次下載
    verilog<b class='flag-5'>編寫</b>UART<b class='flag-5'>串口</b><b class='flag-5'>程序</b>下載

    如何編寫一個hello world程序

    本文簡單介紹如何編寫一個hello world程序,以及程序是如何被執行的
    的頭像 發表于 03-02 17:31 ?8434次閱讀
    如何<b class='flag-5'>編寫</b>第<b class='flag-5'>一個</b>hello world<b class='flag-5'>程序</b>

    串口工具監聽多路串口收發方案

    當我們僅有串口工具時,如何通過簡單的方式,來做到串口工具,監聽
    的頭像 發表于 03-22 15:46 ?3545次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>個</b><b class='flag-5'>串口</b>工具監聽多路<b class='flag-5'>串口</b><b class='flag-5'>收發</b>方案

    vim編寫程序后怎么運行

    當你用 Vim 編寫程序后,你需要執行系列步驟來運行程序。下面是詳盡的說明: 保存文件:
    的頭像 發表于 11-28 15:27 ?3800次閱讀
    主站蜘蛛池模板: 天天爽天天| 亚洲欧美日韩色图| 久久亚洲精品玖玖玖玖| 久久国产精品无码网站| 福利精品| yyy6080韩国三级理论| 日本xxxⅹ69xxxx护士| 中文字幕一区二区三区精彩视频| 日本jlzz| 天天在线天天综合网色| 色爽爽爽| 成年人午夜影院| 黄色xxxx| 欧美猛操| 成人黄网大全在线观看| 午夜黄色| 欧美激情二区三区| tube日本xxxx69| 日本人69xxxxxxx69| 中文字幕亚洲区| 中国特黄毛片| 国产男女免费视频| 亚洲电影在线| 亚洲国内精品自在线影视| 四虎影视在线影院4hu| 亚洲精品视频网| 色丁香婷婷| 色婷婷影院| 四虎在线免费播放| 香蕉视频黄色片| 午色| 嫩草影院在线入口| 女人被狂躁视频网站免费| 国产精品人成在线播放新网站| 狠狠狠色丁香婷婷综合久久五月| 免费在线观看a| 可以免费观看的黄色网址| 久久久噜噜噜www成人网| avtt天堂网永久资源| 在线亚洲小视频| 加勒比在线一区|