[AIROC™ 蓝牙]【英飞凌CYW20829测评】4.串口收发实现

UART通用异步接收器/发送器,是嵌入式开发中最常用的设备间通信协议之一,在开发中经常会用它来打印调试信息,可以最少使用2个引脚(TX和RX)实现数据传输(设备间需要共地),如果是单向传输可以只用一个引脚,在使用串口时需要关注的是数据流以及波特率。一个数据流由10个数据位组成,包含1位起始位,7位有效数据位,1位奇偶校验位,1位停止位。uart串口信号线上空闲时常驻高电平,当检测到低电平下降沿时认为数据传输开始,到停止位时数据传输结束,一共10位数据位组成一个数据包。
 


在开发板上UART需要使用到的引脚已经引出并与板载调试工具KITPROG3相连,可以通过KITPROG3进行串口通讯
 


初始化串口,波特率115200,数据位8,停止位1,无校验

复制

cyhal_uart_t uart_obj;

void app_uart_init(void)

{

    cyhal_uart_cfg_t uart_config =

    {

        .data_bits          = 8,

        .stop_bits          = 1,

        .parity             = CYHAL_UART_PARITY_NONE,

        .rx_buffer          = NULL,

        .rx_buffer_size     = 0

    };

    cyhal_uart_init(&uart_obj, CYBSP_BT_UART_TX, CYBSP_BT_UART_RX,CYBSP_BT_UART_CTS,CYBSP_BT_UART_RTS, NULL,&uart_config);

    cyhal_uart_set_baud(&uart_obj, 115200, NULL);

}


简单实现一下将接收到的数据原样返回

复制

int main(void)

{

    cy_rslt_t result;

    uint8_t read_data;

    result = cybsp_init();

    if (result != CY_RSLT_SUCCESS)

    {

        CY_ASSERT(0);

    }

    app_uart_init();

    __enable_irq();

    for (;;)

    {

        if (CY_RSLT_SUCCESS == cyhal_uart_getc(&uart_obj,&read_data, 0))

        {

            cyhal_uart_putc(&uart_obj,read_data);

        }

    }

}


运行效果
 


接下来实现printf重定向串口,在ModusEclipse中的实现方法和Keil不同,需要重写的是_write方法,代码如下

复制

#if !defined(CY_RETARGET_IO_NO_FLOAT)

__asm(".global _printf_float");

#endif

int32_t _write(int32_t fd, const cy_char8_t* ptr, int32_t len)

{

    int32_t nChars = 0;

    (void)fd;

    if (ptr != NULL)

    {

        cy_rslt_t rslt = CY_RSLT_SUCCESS;

        for (; nChars < len; ++nChars)

        {

            if (CY_RSLT_SUCCESS == rslt)

            {

                rslt = cyhal_uart_putc(&uart_obj, *ptr);

            }

            else

            {

                break;

            }

            ++ptr;

        }

    }

    return (nChars);

}


需要注意的是,在使用GNU的printf时,一定要记住在发送的内容后添加\n或者在printf后使用fflush(stdout),来立即刷新输出流,否则printf不会输出任何数据。这是由于printf的数据流在扫描到\n以前会被保存在缓存中,直到\n出现或是fflush(stdout)强制刷新才会输出数据,如果我们在printf数据的末尾不加入\n或fflush(stdout),这个printf数据就不会被发送出去,之前没加\n搞了半天都没输出,测试代码如下

复制

int main(void)

{

    cy_rslt_t result;

    uint8_t printf_count = 0;

    result = cybsp_init();

    if (result != CY_RSLT_SUCCESS)

    {

        CY_ASSERT(0);

    }

    app_uart_init();

    printf("APP Start\n");

    __enable_irq();



    for (;;)

    {

        Cy_SysLib_Delay(1000);

        printf_count += 1;

        printf("printf test count %d\n",printf_count);

    }

}


运行效果
 


上面的串口接收是阻塞式的,如果没有数据就会一直在接收那里等待,之后的代码不会被执行,接下来用串口中断实现数据接收,代码如下

复制

cyhal_uart_t uart_obj;

uint8_t uart_rx_buffer[1];

void APP_UartCB(void *callback_arg, cyhal_uart_event_t event)

{

    switch(event)

    {

    case CYHAL_UART_IRQ_RX_DONE:

        cyhal_uart_putc(&uart_obj, uart_rx_buffer[0]);

        cyhal_uart_read_async(&uart_obj,uart_rx_buffer,1);

        break;

    default:

        break;

    }

}



void app_uart_init(void)

{

    cyhal_uart_cfg_t uart_config =

    {

        .data_bits          = 8,

        .stop_bits          = 1,

        .parity             = CYHAL_UART_PARITY_NONE,

        .rx_buffer          = NULL,

        .rx_buffer_size     = 0

    };

    cyhal_uart_init(&uart_obj, CYBSP_BT_UART_TX, CYBSP_BT_UART_RX,CYBSP_BT_UART_CTS,CYBSP_BT_UART_RTS, NULL,&uart_config);

    cyhal_uart_set_baud(&uart_obj, 115200, NULL);

    cyhal_uart_register_callback(&uart_obj,APP_UartCB,NULL);

    cyhal_uart_enable_event(&uart_obj, CYHAL_UART_IRQ_RX_DONE, 2, true);

    cyhal_uart_read_async(&uart_obj,uart_rx_buffer,1);

}

int main(void)

{

    cy_rslt_t result;

    uint8_t printf_count = 0;

    result = cybsp_init();

    if (result != CY_RSLT_SUCCESS)

    {

        CY_ASSERT(0);

    }

    app_uart_init();

    printf("APP Start\n");

    __enable_irq();



    for (;;)

    {

        Cy_SysLib_Delay(1000);

        printf_count += 1;

        printf("printf test count %d\n",printf_count);

    }

}


运行效果,可以看到即使没有接收到数据时主循环中的打印也还在继续


---------------------
作者:yuyy1989
链接:https://bbs.21ic.com/icview-3385092-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值