串行接口簡稱串口,也稱串行通信接口或串行通訊接口(通常指COM接口),是採用串行通信方式的擴展接口。串行接口 (Serial Interface)是指數據一位一位地順序傳送。
數據格式;一個字符一個字符地傳輸,每個字符一位一位地傳輸,並且傳輸一個字符時,總是以“起始位”開始,以“停止位”結束,字符之間沒有固定的時間間隔要求。
每一個字符的前面都有一位起始位(低電平),字符本身由7位數據位組成,接着字符後面是一位校驗位(檢驗位可以是奇校驗、偶校驗或無校驗位),最後是一位或一位半或二位停止位,停止位後面是不定長的空閒位,停止位和空閒位都規定爲高電平。實際傳輸時每一位的信號寬度與波特率有關,波特率越高,寬度越小,在進行傳輸之前,雙方一定要使用同一個波特率設置。
平常使用類似STM32這種平臺使用串口一般是用來做調試或者外接一些模塊比如:藍牙、超聲波等等,同樣ESP8266針對串口這塊提供的接口也是特別多,本文只針對主要的幾個關鍵函數進行解析;
頭文件
#include "driver/uart.h"
SDK中提供的接口與STM32的串口配置大同小異,無外乎就是配置串口的波特率、數據位、停止位、奇偶校驗位等等,再者就還有串口中斷配置如接收中斷、發送中斷、超時中斷等等。
串口配置結構體
typedef struct {
int baud_rate; /*!< 串口波特率 */
uart_word_length_t data_bits; /*!< 字長(數據位)*/
uart_parity_t parity; /*!< 奇偶校驗位 */
uart_stop_bits_t stop_bits; /*!< 停止位 */
uart_hw_flowcontrol_t flow_ctrl; /*!< UART硬件流控制模式(cts / rts) */
uint8_t rx_flow_ctrl_thresh; /*!< 設置串口RTS閾值 */
} uart_config_t;
簡單的使用起來就兩個步驟:
- 串口相關參數的配置
- 安裝UART驅動程序
通過以上兩步就可以通過串口進行讀寫了;
串口相關參數配置
當我們創建一個uart_config_t uart_config的結構體進行配置後,只需要調用一個函數即可完成配置;
UART參數配置函數
*esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t uart_conf)
參數 | 解析 |
---|---|
uart_num | 要配置的Uart號 |
uart_conf | uart_config_t結構體 |
函數原型如下:
esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t *uart_conf)
{
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
if (uart_num == UART_NUM_1) {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
} else {
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
if (uart_conf->flow_ctrl & UART_HW_FLOWCTRL_RTS) {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS);
}
if (uart_conf->flow_ctrl & UART_HW_FLOWCTRL_CTS) {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS);
}
uart_set_hw_flow_ctrl(uart_num, uart_conf->flow_ctrl, uart_conf->rx_flow_ctrl_thresh);
}
uart_set_baudrate(uart_num, uart_conf->baud_rate); //波特率
uart_set_word_length(uart_num, uart_conf->data_bits); //字長
uart_set_stop_bits(uart_num, uart_conf->stop_bits); //停止位
uart_set_parity(uart_num, uart_conf->parity); //奇偶校驗位
uart_reset_rx_fifo(uart_num);
return ESP_OK;
}
不難看出,該函數調用了單獨配置給各種參數的接口,算是一個串口配置的結合函數,使用起來十分方便,但是如果想要對單獨的某個設置進行配置的話,也可以使用對應的接口去配置。
安裝UART驅動程序
類似於GPIO配置中開啓GPIO中斷一樣,中斷服務需要通過一個函數來進行安裝,串口在配置完成後,也需要進行串口服務安裝,調用以下函數。
esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, QueueHandle_t *uart_queue);
參數 | 解析 |
---|---|
uart_num | Uart端口號 |
rx_buffer_size | UART 接收緩衝區的大小 |
tx_buffer_size | UART 發送緩衝區的大小。如果設置爲零,驅動程序將不使用TX緩衝區,TX函數將阻塞任務,直到所有數據都已發送出去,即需要發送完後才能執行別的工作 |
queue_size | UART事件隊列的大小/深度 |
uart_queue | UART事件隊列句柄(輸出參數)。如果成功,這裏將寫入一個新的隊列句柄來提供對UART事件的訪問。如果設置爲NULL,驅動程序將不使用事件隊列。 |
用例:實現藍牙接收並打印(這裏用的藍牙4.0波特率是9600,所以爲了避免看到亂碼,需要在make menuconfig中設置monitor的波特率爲9600)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
static const char *TAG = "bluetooth test";
static void ble_task(void *arg)
{
uart_config_t uart_config = {
.baud_rate = 9600, //藍牙波特率
.data_bits = UART_DATA_8_BITS, //8位數據位
.parity = UART_PARITY_DISABLE, //無奇偶校驗
.stop_bits = UART_STOP_BITS_1, //1位停止位
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE //無硬件流
};
uart_param_config(UART_NUM_0, &uart_config); //配置初始化
uart_driver_install(UART_NUM_0, 1024 * 2, 0, 0, NULL); //安裝串口驅動
uint8_t *pBuff = (uint8_t *) malloc(1024);
while (1) {
memset(pBuff, 0, 1024);
int len = uart_read_bytes(UART_NUM_0, pBuff, 1024, 20 / portTICK_RATE_MS);
if(len > 0)
ESP_LOGI(TAG, "pBuff : %s\n", pBuff);
}
}
void app_main(void)
{
xTaskCreate(ble_task, "uart_ble_task", 1024, NULL, 10, NULL);
}
結果:
說明:官方提供的UART的接口可不止這裏介紹的這點,詳見頭文件下的接口說明,這類博文只是快速拉一遍ESP8266的基礎學習而已,要深入瞭解還是去看看官方提供的接口,這裏講不完太多了。