SYD8821 串口模块使用说明【串口0中断要屏蔽底层调用】

2023-05-16

 

SYD8821是具有全球领先低功耗(RX 2.4mA @-94.5dBm灵敏度,TX 4.3mA @0dBm输出功率)的蓝牙低功耗SOC芯片,在极低电流下实现了优异的射频性能,搭配176kB SRAM,512kB flash,非常适合中高阶可穿戴、智能家居、物联网等低功耗应用具体可咨询:http://www.sydtek.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);
}

这样就屏蔽了底层中断的调用,而直接上报到应用层!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SYD8821 串口模块使用说明【串口0中断要屏蔽底层调用】 的相关文章

随机推荐