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函數說明!
測試現象如下:
在串口助手發送數據出去,就能夠在本程序看到返回的數據!
串口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);
}
這樣就屏蔽了底層中斷的調用,而直接上報到應用層!