<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                >[success] **技術支持說明:** >**1**.一般以自主學習為主 > **2**.可到官方問答社區中提問:[**去提問**](https://bbs.csdn.net/forums/nb-iot) > **3**.工程師**會盡快**解答社區問題,但他們是一線開發,【**難以保證**】解答時效,解答辛苦,感謝理解! <br/> ## **串口通信基礎理論** **1.USART簡介** USART全稱為Universal Synchronous/Asynchronous Receiver/Transmitter,即通用串行 同步/異步 接收/發送器。USART中包含串行通信、同步通信和異步通信幾個概念,接下來逐一介紹一下。 <br/> **2.并行通信和串行通信簡介** 并行通信是指同時發送各個數據位(bit),使用并行通信發送8個比特位的示意圖如圖所示。 ![](https://img.kancloud.cn/a6/5e/a65e5f2b5759a3bacf931e9a499b90ac_1000x632.png =250x) ### 串行通信是指一個接一個地發送各個比特位,通過串行通信發送8個比特位的示意圖如圖所示。 ![](https://img.kancloud.cn/92/f9/92f9b7ebbc2112c5632e2cc8582c602e_2560x771.png =500x) 一般地,并行通信的速度比串行通信的速度更快,但所需要的數據引腳也更多。 <br/> **3.異步通信與同步通信簡介** 舉個簡單的例子來說明異步通信與同步通信的主要區別: (1)異步通信類似于手機發短信,其特點是隨時可以發送,而且每次只能發送一條消息。 (2)同步通信類似于手機打電話,其特點是必須在對方接通后才能通話,而且在對方接通后想聊天(通信)多久都可以。 ### **1)異步通信的特點** (1)接收設備要時刻做好接收數據的準備。 (2)發送設備隨時可以發送數據。 (3)發送設備每次只能發送一個數據幀,即一段較長的數據需要被劃分為多個數據幀,且數據幀的組成格式規定如下: * ① 1個起始位。 * ② 5、7或8個數據位,即要傳送的信息。 * ③ 1個奇偶校驗位。 * ④ 1~2個停止位,規定為1。 異步通信的示意圖如圖所示。 ![](https://img.kancloud.cn/33/2d/332d57689b21a82bf4d0254b16129432_2560x803.png =500x) ### 數據幀格式如圖所示。 ![](https://img.kancloud.cn/83/3e/833e1453c2ae9d96a529cf70ec4d6e64_1000x304.png =500x) **2)同步通信的特點** (1)發送設備在發送消息前必須要先和接收設備做時鐘頻率同步。 (2)發送設備每次發送的是數據塊,一個數據塊可以理解為多個字節,且消息格式如下: * 2個同步字符作為一個數據塊的起始標志。 * 多個連續傳輸的的數據字節。 * 2個字節的CRC碼。CRC的全稱是Cyclical Redundancy Check(循環冗余校驗),是數據通信領域中常用的一種差錯校驗碼,數據的接收者可以根據此碼來判斷所接收到數據是否發生錯亂。 同步通信的示意圖如圖所示。 ![](https://img.kancloud.cn/1c/ef/1cef20c35399325938b58425fd912a42_998x450.png) ### 數據塊(數據幀)的格式如圖所示。 ![](https://img.kancloud.cn/11/51/115185ae18b050bff105ca8363f2d1fd_2560x329.png) ### <br/> **3.UART簡介** UART的全稱是Universal Asynchronous Receiver/Transmitter(通用串行異步收發器),也稱作串口,可以理解為在USART的基礎上去掉了同步通信的支持,通常用于主機與嵌入式設備之間的通信,例如配套的ZigBee開發板便可以使用UART與PC主機通信。 <br/> **4.SPI簡介** SPI的全稱是Serial Peripheral Interface(串行外設接口),USART的一種,是一種具有速度快、全雙工和同步通信特點的通信總線。 <br/> ## **串口通信 API 設計** 串口通信功能應該提供初始化、發送和接收信息API,如圖所示。 ![](https://img.kancloud.cn/72/d6/72d6beb6a0c6fdb2589c423eff633ad8_466x474.png =300x) ### 其中的接收串口信息與按鍵類似,都是被動輸入的,同樣地可以使用注冊回調的思想,即上層應用在HAL中注冊已給回調函數,一旦HAL檢測到需要接收串口信息,就會回調給上層應用。 <br/> **編寫代碼** 筆者在本節課配套的源代碼中新建了 hal\_uart.h 和 hal\_uart.c文件,如圖所示。 ![](https://img.kancloud.cn/b7/54/b7549abffdcc722a3625e6be8b3d0e72_254x542.png =250x) ### 打開本節課配套的代碼,筆者把hal\_uart.c以及必要的標準庫文件添加進工程了,如圖所示。 ![](https://img.kancloud.cn/b7/97/b79757222701136351fb25ba60ceae45_375x618.png =300x) <br/> hal_uart.h文件的代碼如下: ### ``` #ifndef __HAL_UART_H__ #define __HAL_UART_H__ /* * 串口通信初始化 * * @param baudrate - 串口通信波特率 */ void halUartInit(unsigned long baudrate); /* * 注冊接收串口信息的回調函數 * * @param onIRQ - 回調函數,接收到到串口信息時自動調用此函數 */ void halUartSetIRQCallback(void (*onIRQ)(unsigned char byte)); /* * 通過串口發送信息 * * @param buf - 待發送的信息的存儲地址 * @param len - 待發送的信息的數據長度 */ void halUartWrite(unsigned char *buf, unsigned int len); #endif /* #ifndef __HAL_UART_H__ */ ``` <br/> hal_uart.c文件的代碼如下: ``` #include "hal_uart.h" #include "stm32f0xx_usart.h" //保存串口通信回調函數 static void (*halUartOnIRQ)(unsigned char byte) = 0; static void halUartGpioInit(void); static void halUartParamInit(unsigned long baudrate); static void halUartIRQInit(void); /* * 串口通信初始化 * * @param baudrate - 串口通信波特率 */ void halUartInit(unsigned long baudrate) { halUartGpioInit(); halUartParamInit(baudrate); halUartIRQInit(); } /* * 注冊接收串口信息的回調函數 * * @param onIRQ - 回調函數,接收到到串口信息時自動調用此函數 */ void halUartSetIRQCallback(void (*onIRQ)(unsigned char byte)) { halUartOnIRQ = onIRQ; } /* * 通過串口發送信息 * * @param buf - 待發送的信息的存儲地址 * @param len - 待發送的信息的數據長度 */ void halUartWrite(unsigned char *buf, unsigned int len) { for (unsigned int i = 0; i < len; i++) { USART_SendData(USART1, buf[i]); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } } /* * 初始化串口通信相關的GPIO */ void halUartGpioInit() { GPIO_InitTypeDef uart1Tx; GPIO_InitTypeDef uart1Rx; /* TX */ uart1Tx.GPIO_Pin = GPIO_Pin_9, //使用PA9作為串口發送接口 uart1Tx.GPIO_Speed = GPIO_Speed_10MHz, uart1Tx.GPIO_Mode = GPIO_Mode_AF, uart1Tx.GPIO_PuPd = GPIO_PuPd_NOPULL, /* RX */ uart1Rx.GPIO_Pin = GPIO_Pin_10,//使用PA10作為串口接收接口 uart1Rx.GPIO_Speed = GPIO_Speed_10MHz, uart1Rx.GPIO_Mode = GPIO_Mode_AF, uart1Rx.GPIO_PuPd = GPIO_PuPd_NOPULL, RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); GPIO_Init(GPIOA, &uart1Tx); GPIO_Init(GPIOA, &uart1Rx); } /* * 初始化串口通信配置 */ void halUartParamInit(unsigned long baudrate) { USART_InitTypeDef uartConfig; uartConfig.USART_BaudRate = baudrate; uartConfig.USART_WordLength = USART_WordLength_8b; uartConfig.USART_Parity = USART_Parity_No; uartConfig.USART_StopBits = USART_StopBits_1; uartConfig.USART_HardwareFlowControl = USART_HardwareFlowControl_None; uartConfig.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); USART_Init(USART1, &uartConfig); USART_Cmd(USART1, ENABLE); } /* * 初始化串口通信的中斷請求 */ void halUartIRQInit() { NVIC_InitTypeDef uartNVIC; uartNVIC.NVIC_IRQChannel = USART1_IRQn; uartNVIC.NVIC_IRQChannelPriority = 0; uartNVIC.NVIC_IRQChannelCmd = ENABLE; USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_ITConfig(USART1, USART_IT_TC, ENABLE); NVIC_Init(&uartNVIC); } /* * 串口通信中斷處理函數。當串口接收到數據時,便會自動產生中斷并執行此函數 */ void USART1_IRQHandler(void) { unsigned char byte = 0; if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { byte = USART_ReceiveData(USART1); // Auto to clear RXNE flag when read! if (halUartOnIRQ != 0) halUartOnIRQ(byte);//執行串口通信回調函數 } else{ USART_ClearFlag(USART1,USART_FLAG_TC);//清理中斷標志 } } ``` 上述的初始化代碼較為復雜,讀者暫時可以直接套用上述代碼,留作后期再深入學習相關原理。 <br/> ## **使用串口通信 HAL API** 編寫好串口通信 HAL API后,串口通信的使用非常簡單。在配套工程的main.c文件中添加如下代碼: ### ``` /* * 通過串口接收到信息時的回調函數 * @param byte - 接收到的數據 */ static void onUartIRQ(unsigned char byte) { halUartWrite(&byte, 1);//把接收到的數據原封不動地發送回去 } int main(void) { halSystemInit();//系統初始化 halUartInit(115200);//串口通信初始化,并設置波特率為115200 halUartSetIRQCallback(onUartIRQ);//注冊串口通信回調函數,當通過串口接收到信息時自動調用此函數 /* Infinite loop */ while (1) {} } ``` <br/> #### **代碼測試** 1.編譯鏈接工程代碼,把生成的Hex文件燒錄到開發板中。 2.把STM32開發板的第1、2、3和4打到右邊,第5和6位打到左邊,如圖所示。 ![](https://img.kancloud.cn/58/9a/589a66f16f8ca111d36b54fac452805c_1076x1045.png =250x) ### 接著,使用配套的Micro USB線連接開發板到電腦上。 ### 3.打開串口助手,在端口選項框中選擇開發板對應的端口,如圖所示。 ![](https://img.kancloud.cn/dd/9d/dd9ddc3699e8471d25a8527372c50189_1166x1032.png =400x) ### 4.按如圖所示配置好數據位、校驗位、停止位和流控等相關配置。 ![](https://img.kancloud.cn/cd/68/cd68b15155eb6d075d8741869447b521_1164x1030.png =400x) ### 5.點擊打開串口按鈕,如果上述步驟操作可以看到“COMx OPENED”的提示,如圖所示。 ![](https://img.kancloud.cn/82/b4/82b4d26bffe601948444cb9937986a25_1164x1028.png =400x) ### 6.在輸入框中輸入任意的字符,然后點擊“發送”按鈕把這些字符通過串口的發送給開發板,如圖所示。 ![](https://img.kancloud.cn/8b/77/8b77c772db1d5e6c9049bbcaa25ee3c0_1170x1038.png =400x) ### 7.開發板把通過串口接收到的數據原封不動地通過串口發送回去,于是讀者可以在串口助手中查看到這些數據,如圖所示。 ![](https://img.kancloud.cn/a8/95/a895b6040f8cab39a1512f027eff23e2_1166x1038.png =400x) <br/> <br/> ## **商務合作** 如有以下需求,可掃碼添加管理員好友,注明“**商務合作**” * 項目定制開發,技術范圍:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等; * 入駐平臺,成為講師; * 接項目賺外快; * 善學坊官網:[www.sxf-iot.com](https://www.sxf-iot.com/) ![](https://img.kancloud.cn/b7/5a/b75ac8c3da945f20568771f5935c388f_430x430.png =150x) (非商務合作**勿擾**,此處**非**技術支持)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看