Renesas R7FA8D1BH (Cortex®-M85)串口应用总结

目录

概述

1 软硬件

1.1 软硬件环境信息

1.2 开发板信息

1.3 调试器信息

2 FSP和KEIL配置串口

2.1 配置参数

2.2 生成基于Keil的软件架构

3 FSP代码

3.1 FSP中UART接口函数 

3.2 案例代码介绍

3.3 案例代码存在的问题

4 UART代码实现

4.1 功能函数介绍

4.2 完整代码

5 测试

5.1 测试功能描述

5.2 运行测试代码


源代码下载地址:

FSP-Project-RA8-uart-test:RenesasR7FA8D1BH(Cortex-M85)串口应用总结资源-CSDN文库

概述

本文主要记录使用Renesas R7FA8D1BH (Cortex®-M85)串口模块时,存在的问题,并详细的记录问题产生的实验现象。笔者通过仔细研究FSP中和UART相关的接口函数和实用案例,通过详细的测试,找到了解决printf函数在打印字符串中不能完整打印数据的问题,并给出解决方案。

1 软硬件

1.1 软硬件环境信息

软硬件信息版本信息
Renesas MCUR7FA8D1BH
KeilMDK ARM 5.38
FSP 版本5.3.0
调试工具:N32G45XVL-STBDAP-LINK

1.2 开发板信息

笔者选择使用野火耀阳开发板_瑞萨RA8,该板块的主控MCU为R7FA8D1BHECBD,7FA8D1BHECBD的内核为ARM Contex-M85。

1.3 调试器信息

对于R7FA8D1BHECBD芯片,其使用的内核为Cortex®-M85 Core, ST-LINK-V2或者J-LINK-V9不支持下载和调试功能。笔者经过多次尝试,发现N32G45XVL-STB板卡上自带的DAP-LINK可以下载和调试R7FA8D1BHECBD。

下图为N32G45XVL-STB开发板实物图:

2 FSP和KEIL配置串口

2.1 配置参数

根据原理图可知,debug UART使用的PIN引脚为PA14和PA15,其对应UART-9接口。

 在FSP上的配置参数如下:

 注意点:

使能SCI接口之后,必须保证该模块对应的时钟被使能,其具体配置方法如下:

 串口中断配置参数:

2.2 生成基于Keil的软件架构

 使用FSP完成参数配置之后,就可以生成基于Keil IED的软件架构,产出项目代码后,使用Keil打卡项目文件,其结果如下:

创建bsp_uart.c文件实现和串口相关的驱动程序。

3 FSP代码

3.1 FSP中UART接口函数 

打开RA Flexible Software Package Documentation  Release v5.3.0,可以看见如下函数

打开文档链接:

RA/sc_v2024-04_fsp_v5.3.0/fsp_documentation/v5.3.0/fsp_user_manual_v5.3.0/group___s_c_i___b___u_a_r_t.html

该页面上对上述函数做了详细的介绍,FSP还提供了一个UART应用的案例功供程序员参考。

3.2 案例代码介绍

案例代码实现功能:

1)在 r_sci_b_uart_basic_example (void)函数中,实现初始化串口,然后接收一个包的数据;完成数据接收后,由进行发送一个包的数据。

2)中断回调函数:void example_callback (uart_callback_args_t * p_args)

接收数据,并根据事件控制字,判断接收或者,发送数据是否完成

uint8_t  g_dest[TRANSFER_LENGTH];
uint8_t  g_src[TRANSFER_LENGTH];
uint8_t  g_out_of_band_received[TRANSFER_LENGTH];
uint32_t g_transfer_complete = 0;
uint32_t g_receive_complete  = 0;
uint32_t g_out_of_band_index = 0;
void r_sci_b_uart_basic_example (void)
{
    /* Initialize p_src to known data */
    for (uint32_t i = 0; i < TRANSFER_LENGTH; i++)
    {
        g_src[i] = (uint8_t) ('A' + (i % 26));
    }
    /* Open the transfer instance with initial configuration. */
    fsp_err_t err = R_SCI_B_UART_Open(&g_uart0_ctrl, &g_uart0_cfg);
    assert(FSP_SUCCESS == err);
    err = R_SCI_B_UART_Read(&g_uart0_ctrl, g_dest, TRANSFER_LENGTH);
    assert(FSP_SUCCESS == err);
    err = R_SCI_B_UART_Write(&g_uart0_ctrl, g_src, TRANSFER_LENGTH);
    assert(FSP_SUCCESS == err);
    while (!g_transfer_complete)
    {
    }
    while (!g_receive_complete)
    {
    }
}
void example_callback (uart_callback_args_t * p_args)
{
    /* Handle the UART event */
    switch (p_args->event)
    {
        /* Received a character */
        case UART_EVENT_RX_CHAR:
        {
            /* Only put the next character in the receive buffer if there is space for it */
            if (sizeof(g_out_of_band_received) > g_out_of_band_index)
            {
                /* Write either the next one or two bytes depending on the receive data size */
                if (UART_DATA_BITS_8 >= g_uart0_cfg.data_bits)
                {
                    g_out_of_band_received[g_out_of_band_index++] = (uint8_t) p_args->data;
                }
                else
                {
                    uint16_t * p_dest = (uint16_t *) &g_out_of_band_received[g_out_of_band_index];
                    *p_dest              = (uint16_t) p_args->data;
                    g_out_of_band_index += 2;
                }
            }
            break;
        }
        /* Receive complete */
        case UART_EVENT_RX_COMPLETE:
        {
            g_receive_complete = 1;
            break;
        }
        /* Transmit complete */
        case UART_EVENT_TX_COMPLETE:
        {
            g_transfer_complete = 1;
            break;
        }
        default:
        {
        }
    }
}

3.3 案例代码存在的问题

笔者在使用案例程序,进行数据发送时,存在如下问题:

问题1:

使用如下代码发送数据时,如果连续发送多包数据,只有第一包发送成功:

err = R_SCI_B_UART_Write(&g_uart0_ctrl, g_src, TRANSFER_LENGTH);
    assert(FSP_SUCCESS == err);
    while (!g_transfer_complete)
    {
    }

问题2: 

连续多次发送数据时,程序会卡在某一个位置,具体位置如下:

问题3:

 定义printf函数的接口,其详细代码如下:

int fputc(int ch, FILE *f)
{
    fsp_err_t err;
    
    (void)f;
    err = R_SCI_B_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
    assert(FSP_SUCCESS == err);
    while (!g_transfer_complete)
    {
    }
    g_transfer_complete = 0;

    return ch;
}

使用printf函数,打印一个字符串,会发现,其只能打印一个byte

4 UART代码实现

4.1 功能函数介绍

1)发送数据函数

代码24行:发送数据接口

代码25行: 判断发送数据是否成功

代码26行:等待中断函数中的发送完成控制字置位

代码28行:实现1ns的延时,这一条语句很重要, 解决了上述3.3小节中的问题

2)设置baud函数

代码40行:计算baud

代码42行:设置baud

代码46行:初始化串口

 3)中断函数

代码第57行:处理串口中断事件

代码第86行:发送数据完成事件函数

4)printf函数结构

代码第103行:串口写数据函数

代码第105行:接收数据完成标志位

代码第107行:延时1ns,这个函数非常重要,没有这句语句,printf发送数据时只发送一个byte

 

4.2 完整代码

 在bsp_uart.c文件中实现如下代码:

 /*
 FILE NAME  :  bsp_uart.c
 Description:  debug uart function library  
 Author     :  tangmingfei2013@126.com
 Date       :  2024/06/03
 */
#include "bsp_uart.h"
#include "string.h"
#include <stdarg.h> 

#define TRANSFER_LENGTH       128

uint8_t  g_src[TRANSFER_LENGTH];
uint8_t  g_out_of_band_received[TRANSFER_LENGTH];
uint32_t g_transfer_complete = 0;
uint32_t g_receive_complete  = 0;
uint32_t g_out_of_band_index = 0;

void r_sci_b_uart0_sendArry ( uint8_t *str, uint32_t len)
{
    fsp_err_t err;

    // send the messsage infor
    err = R_SCI_B_UART_Write(&g_uart0_ctrl,str, len);
    assert(FSP_SUCCESS == err);
    while (!g_transfer_complete)
    {
        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MICROSECONDS);
    }
    g_transfer_complete = 0;
}

void r_sci_b_uart0_set_baud (uint32_t baud_rate)
{
    fsp_err_t err ;
    sci_b_baud_setting_t baud_setting;
    bool                 enable_bitrate_modulation = false;
    uint32_t             error_rate_x_1000         = SCI_B_UART_BAUDRATE_ERROR_PERCENT_5;
    
    err = R_SCI_B_UART_BaudCalculate(baud_rate, enable_bitrate_modulation, error_rate_x_1000, &baud_setting);
    assert(FSP_SUCCESS == err);
    err = R_SCI_B_UART_BaudSet(&g_uart0_ctrl, (void *) &baud_setting);
    assert(FSP_SUCCESS == err);
    
    /* Open the transfer instance with initial configuration. */
    err = R_SCI_B_UART_Open(&g_uart0_ctrl, &g_uart0_cfg);
    assert(FSP_SUCCESS == err);
    
    printf("Board message: R7FA8D1BHECBD-BTB \r\n");
    printf("next Board message: R7FA8D1BHECBD-BTB \r\n");
}


void g_uart0_CallbackFunc (uart_callback_args_t * p_args)
{
    /* Handle the UART event */
    switch (p_args->event)
    {
        /* Received a character */
        case UART_EVENT_RX_CHAR:
        {
            /* Only put the next character in the receive buffer if there is space for it */
            if (sizeof(g_out_of_band_received) > g_out_of_band_index)
            {
                /* Write either the next one or two bytes depending on the receive data size */
                if (UART_DATA_BITS_8 >= g_uart0_cfg.data_bits)
                {
                    g_out_of_band_received[g_out_of_band_index++] = (uint8_t) p_args->data;
                }
                else
                {
                    uint16_t * p_dest = (uint16_t *) &g_out_of_band_received[g_out_of_band_index];
                    *p_dest              = (uint16_t) p_args->data;
                    g_out_of_band_index += 2;
                }
            }
            break;
        }
        /* Receive complete */
        case UART_EVENT_RX_COMPLETE:
        {
            g_receive_complete = 1;
            break;
        }
        /* Transmit complete */
        case UART_EVENT_TX_COMPLETE:
        {
            g_transfer_complete = 1;
            break;
        }
        default:
        {
        }
    }
}


int fputc(int ch, FILE *f)
{
    fsp_err_t err;
    
    (void)f;
    err = R_SCI_B_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
    assert(FSP_SUCCESS == err);
    while (!g_transfer_complete)
    {
        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MICROSECONDS);
    }
    g_transfer_complete = 0;

    return ch;
}



/* End of this file */

5 测试

5.1 测试功能描述

使用printf函数打印字符串,PC端使用终端工具接收数据,测试函数如下:

void log_message(void)
{
    printf("\n   \\ |    /\n");
    printf("- Conxtex-M85 -   test System\n");
    printf(" /     |     \\    build %s %s\n", __DATE__, __TIME__);
    printf(" 2024 - 2029 Copyright by mingfei.tang\n");
}

5.2 运行测试代码

编译代码下载到板卡中,其运行结果如下:

串口终端上接收到的数据

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值