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);
}
这样就屏蔽了底层中断的调用,而直接上报到应用层!