<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                >[success] **技術支持說明** > 1.**客服**提供簡單的技術支持,一般自主學習為主 > 2.可到官方問答社區中提問:[**去提問**](https://bbs.csdn.net/forums/nb-iot) > 3.工程師**會盡快**解答社區問題,但他們是一線開發,【**難以保證**】解答時效,解答辛苦,感謝理解! <br/> ## **串口通信基礎理論** #### **1\. USART** 全稱為Universal Synchronous/Asynchronous Receiver/Transmitter,即通用串行 同步/異步 接收/發送器。 <br/> #### **2\. 并行通信和串行通信** * 并行通信是指同時發送各個數據位(bit),使用并行通信發送8個位數據的示意圖如下。 ![](https://img.kancloud.cn/9f/62/9f62b739d9573a1c7b2c7371c055285e_294x338.png =200x) ### * 串行通信是指一個接一個地發送各個數據位,通過串行通信發送8位數據的示意圖如下: ![](https://img.kancloud.cn/06/af/06af56f52e028758c4bde695c59138c4_832x252.png =500x) ### 一般地,并行通信的速度比串行通信的速度更快,但所需要的數據引腳也更多。 <br/> #### **3.異步通信與同步通信** 舉個簡單的例子說明異步通信與同步通信的區別, * 發短信: 屬于異步通信,隨時可以發,而且每次只能發送一條消息; * 打電話: 屬于同步通信,必須對方接通后才能通話,對方接通后,想聊多久都可以。 ### **異步通信的特點** 1.接收設備時刻做好接收數據的準備 2.發送設備隨時可以發送數據 3.發送設備每次只能發送一個字符,且字符的組成格式規定如下: ??A. 1位起始位,規定為低電0 ??B. 5~8位數據位,即要傳送的有效信息 ??C. 1位奇偶校驗位 ??D. 1~2位停止位,規定為高電平1 ### 異步通信的示意圖如下。 ![](https://img.kancloud.cn/72/1f/721f6ad4ae6a6ee8b8ccb93122d3231d_830x262.png =500x) ### 數據幀格式如下。 ![](https://img.kancloud.cn/96/64/966402c3e28753c61f37a4b161bb1e73_736x214.png =500x) ### **同步通信的特點** 1.發送設備在發送消息前必須先和接收設備做時鐘頻率同步。 2.發送設備每次發送的是數據塊(可以理解為很多個字節),且消息格式如下: ??A. 2個同步字符作為一個數據塊(信息幀)的起始標志; ??B. n個連續傳送的數據 ??C. 2個字節循環冗余校驗碼(CRC) ### 同步通信的示意圖如下。 ![](https://img.kancloud.cn/fa/ab/faab57776f32a479bc301aa3c3516b0c_498x332.png =400x) ### 數據幀格式如下。 ![](https://img.kancloud.cn/e1/75/e1758cef916d74353a7caa21481fdf4e_832x108.png =500x) <br/> #### **4\. UART** 串口通信,是一種串行異步收發的通信模式。配套的開發板具備串口通信能力,開發者可以用來與上位機通信。 <br/> ## **串口通信 API 設計** 串口通信功能應該提供初始化、發送和接收信息API,如圖所示。 ![](https://img.kancloud.cn/0d/86/0d86905051567e2dc0e9c31e51cee57c_466x474.png =250x) ### 其中的接收串口信息與按鍵類似,都是被動輸入的,同樣地可以使用注冊回調的思想,即上層應用在HAL中注冊已給回調函數,一旦HAL檢測到需要接收串口信息,就會回調給上層應用。 <br/> **編寫代碼** 筆者在本節課配套的源代碼中新建了 hal\_uart.h 和 hal\_uart.c文件,如圖所示。 ![](https://img.kancloud.cn/5b/06/5b0638e7ca01c06640295b8c822d48a2_254x542.png =250x) ### 打開本節課配套的工程,筆者把hal\_uart.c以及必要的標準庫文件添加進工程了,如圖所示。 ![](https://img.kancloud.cn/cf/9d/cf9ddc338baeddcf223ef013e407ff66_375x618.png =250x) <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, 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, 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.按如圖所示把開發板的撥碼開關的第1~4位打到右邊,第5、6位打到左邊 ![](https://img.kancloud.cn/34/9c/349cceae4177926416445b6daf932d24_664x827.png =200x) ### 3.打開串口助手,給開發板發送數據,可以看到發送的數據原封不動地發送回來了,如圖所示。 ![](https://img.kancloud.cn/64/51/6451e971725cf5abfbde6e77ef8a1da4_723x639.png =500x) <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/ca/73/ca739f92cab220a3059378642e3bd502_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>

                              哎呀哎呀视频在线观看