SYD8821 串口模塊使用說明【串口0中斷要屏蔽底層調用】

SYD8821是具有全球領先低功耗(RX 2.4mA @-94.5dBm靈敏度,TX 4.3mA @0dBm輸出功率)的藍牙低功耗SOC芯片,在極低電流下實現了優異的射頻性能,搭配176kB SRAM,512kB flash,非常適合中高階可穿戴、智能家居、物聯網等低功耗應用具體可諮詢:http://www.syd-tek.com/


SYD8821 串口模塊使用說明

如下圖示IO口的功能分佈:


本節博文介紹使用的是串口1,串口的波形從GPIO4,5出來,這裏硬件連線如下:


打開「\SYD8821_SDK\Source Code\SYD8821\uart\Keil」目錄下的工程,可看到主函數如下:

#include "ARMCM0.h"
#include "gpio.h"
#include "pad_mux_ctrl.h"
#include "delay.h"
#include "led_key.h"
#include "uart.h"
#include "queue.h"


int main()
{
uint8_t *buff;
uint16_t buff_size=0;
__disable_irq();
//GPO
pad_mux_write(LED4, 0);
pad_mux_write(LED5, 0);
pad_mux_write(LED6, 0);
pad_mux_write(LED7, 0);
gpo_config(LED4,1);
gpo_config(LED5,1);
gpo_config(LED6,1);
        gpo_config(LED7,1);

//GPI
pad_mux_write(KEY1, 0);
pad_mux_write(KEY2, 0);
pad_mux_write(KEY3, 0);
gpi_config(KEY1, PULL_UP);
gpi_config(KEY2, PULL_UP);
gpi_config(KEY3, PULL_UP);

//uart 1
pad_mux_write(4, 7);
pad_mux_write(5, 7);
uart_1_init(UART_RTS_CTS_DISABLE, UART_BAUD_115200);
uart_write(1,"SYD8821 UART TEST", 18);


//      uart 0
// pad_mux_write(20, 7);
// pad_mux_write(21, 7);
// uart_0_init(UART_RTS_CTS_DISABLE, UART_BAUD_115200);
// uart_write(0,"SYD8821 UART TEST", 18);

__enable_irq();
while(1)
{
gpo_toggle(LED4);
buff_size=uart_queue_size(1,buff);
if (buff_size){
uint8_t temp=0; 
uint16_t i=0;
for(i=0;i<buff_size;i++) {
    uart_read(1,&temp);
  uart_write(1,&temp,1);
}
    gpo_toggle(LED5);
}
}
}

這裏的main函數的while(1)裏的思路是判斷是否buff隊列中有數據,當有數據的時候就把buff隊列中的數據發送出去!

其中串口的配置操作如下:

//uart 1
pad_mux_write(4, 7);     //配置GPIO4爲IO的第7功能,從上面的列表可以看到第7功能是UART_RXD_1
pad_mux_write(5, 7);      //配置GPIO5爲IO的第7功能,從上面的列表可以看到第7功能是UART_TXD_1
uart_1_init(UART_RTS_CTS_DISABLE, UART_BAUD_115200);     //調用uart_1_init函數進行串口1的配置,這裏失能流控功能,並且波特率設置爲115200
uart_write(1,"SYD8821 UART TEST", 18);      //向串口1輸出"SYD8821 UART TEST",該字符串有18個字符(包括結束符)

其中的uart_1_init源代碼如下:

void uart_1_init(uint8_t flowctrl, uint8_t baud)
{
    NVIC_DisableIRQ(UART1_IRQn);
    UART_CTRL[1]->BAUD_SEL = baud;
    UART_CTRL[1]->FLOWCTRL_EN = flowctrl;
    UART_CTRL[1]->INT_RX_MASK = 0;
    UART_CTRL[1]->UART_ENABLE = 1;
    queue_init(&rx_queue[1], rx_buf[1], QUEUE_SIZE);

    NVIC_EnableIRQ(UART1_IRQn);
}

這裏是使能中斷的,當發生中斷的時候將會進入相應的中斷服務函數裏,這裏中斷服務函數如下:

void UART1_IRQHandler(void)
{
    uint8_t int_st = UART_CTRL[1]->INT_STATUS;
    uint8_t clear_int = int_st ^ UART_ALL_INT;
    
    // Clear interrrupt status
    UART_CTRL[1]->INT_STATUS = clear_int;
    
    if (int_st & UART_RX_INT) {
        do {
            enqueue(&rx_queue[1], UART_CTRL[1]->RX_DATA);
        } while (!UART_CTRL[1]->RXFF_EMPTY);
    }

}

這裏把數據存儲到&rx_queue[1]中,然後main函數的主循環將會來讀取這個buff,請看main函數說明!

測試現象如下:

在串口助手發送數據出去,就能夠在本程序看到返回的數據!


這裏上傳本節博客使用到的代碼(工程在:SYD8821_SDK\Source Code\SYD8821\uart):https://download.csdn.net/download/chengdong1314/10304116


串口0中斷要屏蔽底層調用

對於串口0比較特殊,因爲下載代碼也是可以通過串口0的,也就是說底層協議棧是有使用串口0的,既然底層已經有使用串口0,所以這裏如果不做上相應的處理,串口0的中斷是上報不上來的,這裏可以做如下處理:

void uart_0_init(uint8_t flowctrl, uint8_t baud)
{
    NVIC_DisableIRQ(UART0_IRQn);
    UART_CTRL[0]->BAUD_SEL = baud;
    UART_CTRL[0]->FLOWCTRL_EN = flowctrl;
    UART_CTRL[0]->INT_RX_MASK = 0;
    UART_CTRL[0]->UART_ENABLE = 1;
    
    queue_init(&rx_queue[0], rx_buf[0], QUEUE_SIZE);
    
    *(uint32_t *)0x20028024 |=U32BIT(UART0_IRQn);
    *(uint32_t *)0x20028020 |=U32BIT(UART0_IRQn);

    NVIC_EnableIRQ(UART0_IRQn);
}

這樣就屏蔽了底層中斷的調用,而直接上報到應用層!