AiPi-Eyes-S1是安信可開源團隊專門為Ai-M61-32S設計的一款開發板,支持WiFi6、BLE5.3。所搭載的Ai-M61-32S 模組具有豐富的外設接口,具體包括 DVP、MJPEG、Dispaly、AudioCodec、USB2.0、SDU、以太網 (EMAC)、SD/MMC(SDH)、SPI、UART、I2C、I2S、PWM、GPDAC、GPADC、ACOMP 和 GPIO 等。
AiPi-Eyes-S1集成了SPI屏幕接口,DVP攝像頭接口,外置ES8388音頻編解碼芯片以及預留TF卡座,并且引出USB接口,可接入USB攝像頭。
從零開始學習小安派:
1、零基礎開發小安派-Eyes-S1【入門篇】——初識小安派-Eyes-S1
2、零基礎開發小安派-Eyes-S1【入門篇】——安裝VMware與Ubuntu
3、入門篇:零基礎開發小安派-Eyes-S1——新建工程并燒錄調試
4、零基礎開發小安派-Eyes-S1入門篇——Win下SSH連接Linux
5、零基礎開發小安派-Eyes-S1【入門篇】——Samba共享文件夾
6、零基礎開發小安派-Eyes-S1【入門篇】——工程文件架構
7、零基礎開發小安派-Eyes-S1【外設篇】——GPIO 輸入輸出
8、零基礎開發小安派-Eyes-S1【外設篇】——GPIO中斷編程
9、零基礎開發小安派-Eyes-S1【外設篇】——PWM
通用異步收發傳輸器(Universal Asynchronous Receiver/Transmitter, 通常稱為 UART) 是一種異步收發傳輸器,提供了與外部設備進行全雙工數據交換的靈活方式。BL616/BL618 共有 2 組 UART,配合 DMA 使用,可以實現高效的數據通信。
01、了解小安派-Eyes-S1 的 UART
小安派的 UART 是全雙工異步通訊,具有豐富的中斷控制,DMA 傳輸、485 協議、10Mbps 波特率、LIN 總線協議等等特征。其有三個時鐘源,分別是 XCK、160Mhz CLK 和 BCLK。UART 的控制器分為兩個功能模塊:發送器和接收器。
數據位長度可選 5 / 6 / 7 / 8 比特
#define UART_DATA_BITS_5 0
#define UART_DATA_BITS_6 1
#define UART_DATA_BITS_7 2
#define UART_DATA_BITS_8 3
#define UART_DATA_BITS_9 4
停止位長度可選 0.5 / 1 / 1.5 / 2 比特
#define UART_STOP_BITS_0_5 0
#define UART_STOP_BITS_1 1
#define UART_STOP_BITS_1_5 2
#define UART_STOP_BITS_2 3
支持 奇 / 偶 / 無 / 校驗比特
#define UART_PARITY_NONE 0
#define UART_PARITY_ODD 1
#define UART_PARITY_EVEN 2
#define UART_PARITY_MARK 3
#define UART_PARITY_SPACE 4
可配置 MSB / LSB 優先輸出
#define UART_LSB_FIRST 0
#define UART_MSB_FIRST 1
1.struct bflb_uart_config_s
說明:uart 初始化配置結構體
struct bflb_uart_config_s {
uint32_t baudrate;
uint8_t direction;
uint8_t data_bits;
uint8_t stop_bits;
uint8_t parity;
uint8_t bit_order;
uint8_t flow_ctrl;
uint8_t tx_fifo_threshold;
uint8_t rx_fifo_threshold;
};
2.bflb_uart_init
說明: 初始化 uart。使用之前需要開啟 uart ip 時鐘、設置 uart 時鐘源和分頻值、選擇 gpio 為 uart 中的一個功能。
void bflb_uart_init(struct bflb_device_s *dev, const struct bflb_uart_config_s *config);
3.bflb_uart_deinit
說明: 反初始化 uart。
void bflb_uart_deinit(struct bflb_device_s *dev);
4.bflb_uart_link_txdma
說明: uart tx dma 使能開關。
void bflb_uart_link_txdma(struct bflb_device_s *dev, bool enable);
5.bflb_uart_link_rxdma
說明: uart rx dma 使能開關。
void bflb_uart_link_rxdma(struct bflb_device_s *dev, bool enable);
6.bflb_uart_putchar
說明: 通過 uart 阻塞式發送一個字符。
int bflb_uart_putchar(struct bflb_device_s *dev, int ch);
7.bflb_uart_getchar
說明: 通過 uart 異步接收一個字符。
int bflb_uart_getchar(struct bflb_device_s *dev);
8.bflb_uart_put
說明:通過 uart 輪詢發送數據。
int bflb_uart_put(struct bflb_device_s *dev, uint8_t *data, uint32_t len);
9.bflb_uart_put_block
說明:通過 uart 阻塞式發送數據。
int bflb_uart_put_block(struct bflb_device_s *dev, uint8_t *data, uint32_t len);
10.bflb_uart_get
說明:通過 uart 異步阻塞接收數據。
int bflb_uart_get(struct bflb_device_s *dev, uint8_t *data, uint32_t len);
11.bflb_uart_txready
說明: 查詢 uart tx fifo 是否準備就緒,準備好才可以填充字符
bool bflb_uart_txready(struct bflb_device_s *dev);
12.bflb_uart_txempty
說明: 查詢 uart tx fifo 是否為空。
bool bflb_uart_txempty(struct bflb_device_s *dev);
13.bflb_uart_rxavailable
說明: 查詢 uart rx 是否有數據。
bool bflb_uart_rxavailable(struct bflb_device_s *dev);
14.bflb_uart_txint_mask
說明: uart tx fifo 閾值中斷屏蔽開關,開啟后超過設定閾值則觸發中斷。
void bflb_uart_txint_mask(struct bflb_device_s *dev, bool mask);
15.bflb_uart_rxint_mask
說明: uart rx fifo 閾值中斷和超時屏蔽開關,開啟后超過設定閾值則或者超時則觸發中斷。
void bflb_uart_rxint_mask(struct bflb_device_s *dev, bool mask);
16.bflb_uart_errint_mask
說明:uart 錯誤中斷屏蔽開關。
void bflb_uart_errint_mask(struct bflb_device_s *dev, bool mask);
17.bflb_uart_get_intstatus
說明: 獲取 uart 中斷標志。
uint32_t bflb_uart_get_intstatus(struct bflb_device_s *dev);
返回的中斷標志有以下選項:
#define UART_INTSTS_TX_END (1 << 0)
#define UART_INTSTS_RX_END (1 << 1)
#define UART_INTSTS_TX_FIFO (1 << 2)
#define UART_INTSTS_RX_FIFO (1 << 3)
#define UART_INTSTS_RTO (1 << 4)
#define UART_INTSTS_PCE (1 << 5)
#define UART_INTSTS_TX_FER (1 << 6)
#define UART_INTSTS_RX_FER (1 << 7)
#if !defined(BL602)
#define UART_INTSTS_RX_LSE (1 << 8)
#endif
#if !defined(BL602) && !defined(BL702)
#define UART_INTSTS_RX_BCR (1 << 9)
#define UART_INTSTS_RX_ADS (1 << 10)
#define UART_INTSTS_RX_AD5 (1 << 11)
#endif
18.bflb_uart_int_clear
說明: 清除 uart 中斷標志。
void bflb_uart_int_clear(struct bflb_device_s *dev, uint32_t int_clear);
清除值可填入以下參數:
#define UART_INTCLR_TX_END (1 << 0)
#define UART_INTCLR_RX_END (1 << 1)
#define UART_INTCLR_RTO (1 << 4)
#define UART_INTCLR_PCE (1 << 5)
#if !defined(BL602)
#define UART_INTCLR_RX_LSE (1 << 8)
#endif
#if !defined(BL602) && !defined(BL702)
#define UART_INTCLR_RX_BCR (1 << 9)
#define UART_INTCLR_RX_ADS (1 << 10)
#define UART_INTCLR_RX_AD5 (1 << 11)
#endif
19.bflb_uart_feature_control
說明:uart 其他特性相關控制,一般不常用。
int bflb_uart_feature_control(struct bflb_device_s *dev, int cmd, size_t arg);
cmd 可以填入以下參數:
#define UART_CMD_SET_BAUD_RATE (0x01)
#define UART_CMD_SET_DATA_BITS (0x02)
#define UART_CMD_SET_STOP_BITS (0x03)
#define UART_CMD_SET_PARITY_BITS (0x04)
#define UART_CMD_CLR_TX_FIFO (0x05)
#define UART_CMD_CLR_RX_FIFO (0x06)
#define UART_CMD_SET_RTO_VALUE (0x07)
#define UART_CMD_SET_RTS_VALUE (0x08)
#define UART_CMD_GET_TX_FIFO_CNT (0x09)
#define UART_CMD_GET_RX_FIFO_CNT (0x0a)
#define UART_CMD_SET_AUTO_BAUD (0x0b)
#define UART_CMD_GET_AUTO_BAUD (0x0c)
#define UART_CMD_SET_BREAK_VALUE (0x0d)
#define UART_CMD_SET_TX_LIN_VALUE (0x0e)
#define UART_CMD_SET_RX_LIN_VALUE (0x0f)
#define UART_CMD_SET_TX_RX_EN (0x10)
#define UART_CMD_SET_TX_RS485_EN (0x11)
#define UART_CMD_SET_TX_RS485_POLARITY (0x12)
#define UART_CMD_SET_ABR_ALLOWABLE_ERROR (0x13)
#define UART_CMD_SET_SW_RTS_CONTROL (0x14)
#define UART_CMD_IR_CONFIG (0x15)
#define UART_CMD_SET_TX_FREERUN (0x16)
#define UART_CMD_SET_TX_END_INTERRUPT (0x17)
#define UART_CMD_SET_RX_END_INTERRUPT (0x18)
#define UART_CMD_SET_TX_TRANSFER_LEN (0x19)
#define UART_CMD_SET_RX_TRANSFER_LEN (0x20)
#define UART_CMD_SET_TX_EN (0x21)
#define UART_CMD_SET_BCR_END_INTERRUPT (0x22)
#define UART_CMD_GET_BCR_COUNT (0x23)
02、示例:UART 發送,中斷接收
小安派-Eyes-S1 具有兩組串口,UART0 已經被映射為 prtinf 函數,也就是 LOG 函數,我們還剩下一組 UART1 可使用,而且小安派的 GPIO 可以任意配置為 UART 的 TX 或 RX,這里使用 GPIO_1 和 GPIO_0 配置為 UART1。
實現的效果是,在主函數里輪詢發送數據,當 UART1 接收到其他數據時,觸發接收中斷并使用 UART0 發送,也就是 LOG 函數發送出來,實現透傳的效果。
Main
//頭文件
#include "bflb_mtimer.h"
#include "bflb_uart.h"
#include "bflb_gpio.h"
#include "board.h"
//設置名為uart1的外設句柄
struct bflb_device_s *uart1;
//定義需要輪詢發送的數據
static uint8_t uart_txbuf[4] = { 0,1,2,3 };
void uart_isr(int irq, void *arg);
//初始化串口配置,如波特率,數據位和停止位
//tx_fifo_threshold 和 rx_fifo_threshold 參數設置表示為fifo中斷的觸發閾值
static void uart_init(void)
{
struct bflb_device_s* gpio;
struct bflb_uart_config_s cfg = {
.baudrate = 115200,
.data_bits = UART_DATA_BITS_8,
.stop_bits = UART_STOP_BITS_1,
.parity = UART_PARITY_NONE,
.flow_ctrl = 0,
.tx_fifo_threshold = 4,
.rx_fifo_threshold = 4,
};
gpio = bflb_device_get_by_name("gpio");
uart1 = bflb_device_get_by_name("uart1");
//將GPIO_1和GPIO_0設置為TX和RX
bflb_gpio_uart_init(gpio, GPIO_PIN_1, GPIO_UART_FUNC_UART1_TX);
bflb_gpio_uart_init(gpio, GPIO_PIN_0, GPIO_UART_FUNC_UART1_RX);
bflb_uart_init(uart1, &cfg);
bflb_uart_txint_mask(uart1, true);
bflb_uart_rxint_mask(uart1, false);
bflb_irq_attach(uart1->irq_num, uart_isr, NULL);
bflb_irq_enable(uart1->irq_num);
}
//中斷服務函數,觸發中斷后會進入該函數
void uart_isr(int irq, void *arg)
{
uint32_t intstatus = bflb_uart_get_intstatus(uart1);
//這里注釋了fifo管道的RX中斷觸發,fifo的觸發方式也就是上面設置的字節數4,也就是要接收4個字節以上數據才會觸發fifo中斷
// if (intstatus & UART_INTSTS_RX_FIFO) {
// printf("rx fiforn");
// while (bflb_uart_rxavailable(uart1)) {
// printf("0x%02xrn", bflb_uart_getchar(uart1));
// }
// }
//接收超時中斷,當一段時間內數據沒有接收后便會停止,在觸發中斷后,輪詢使用prtintf發送uart1接收到的字符,停止接收后清空中斷標志等待下一次發送
if (intstatus & UART_INTSTS_RTO) {
printf("rtorn");
while (bflb_uart_rxavailable(uart1)) {
printf("0x%02xrn", bflb_uart_getchar(uart1));
}
bflb_uart_int_clear(uart1, UART_INTCLR_RTO);
}
}
int main(void)
{
board_init();
uart_init();
//主函數每兩秒輪詢一次發送 uart_txbuf 數據
while (1) {
bflb_mtimer_delay_ms(2000);
bflb_uart_put(uart1,uart_txbuf,4);
}
}
實現效果
uart1 每兩秒發送一次 00 01 02 03 ,左邊框中可以看見持續接收到數據,當 uart1 接收到其他數據時如 AA BB CC DD EE FF 或 11 22 33 ,可以在右邊的 uart0 框中看見接收到的數據,可以看見觸發的中斷方式為 RTO 超時。可以嘗試 fifo 的方式看看兩種方式的差異性,在后續處理串口協議時,面對不同的協議采用不同的方式來應對。
審核編輯 黃宇
-
usb
+關注
關注
60文章
7936瀏覽量
264474 -
uart
+關注
關注
22文章
1235瀏覽量
101354
發布評論請先 登錄
相關推薦
評論