eefocus_4231172 发表于 2026-8-9 14:58:58

【瑞萨RA-eco-RA6M4评测】- TOF测距实践篇

本帖最后由 eefocus_4231172 于 2026-8-10 09:38 编辑

一、前言
本篇文章是上一篇《【瑞萨RA-eco-RA6M4评测】- TOF测距准备篇》文章的延续,如何配置UWB模块作为主机和从机,且如何进行测距。


二、开发板图片
1、瑞萨开发板图片




2、UWB模块


三、正文
1、配置UWB模块1为从机

按上图的步骤进行设置。


2、配置UWB模块2为主机

按上图的步骤进行设置。


3、主机测试数据完成后的通信协议

如上图所示,我们只需要解析出里面的距离信息就好了

4、软件编写

void analyse_distance()
{
    unsigned short distance = 0;
    if((DataBuff1 == 0xf0) && (DataBuff1 == 0x05))
    {
      distance = (DataBuff1 << 8) | (DataBuff1);
      printf("distance = %d cm\r\n",distance);
    }
}
上述代码的功能是解析距离信息,并通过串口进行打印。
备注:DataBuff1中的数据是通过RX引脚P100,进行接收的,然后printf的打印是通过另外一个串口,TX为P110打印出来的。

5、主函数程序编写

if(Rx_flag_finish1==1)
      {
            analyse_distance();
            Rx_flag_finish1 = 0;
            RxLine1 = 0;
      }上述代码的意思为检测到接收结束,然后调用解析函数将距离信息打印出来。

6、完整代码
#include "hal_data.h"
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER

void printf_usart(void);

fsp_err_t err = FSP_SUCCESS;
volatile bool uart_send_complete_flag = false;
volatile bool uart1_send_complete_flag = false;

uint8_t RxBuff;      //进入中断接收数据的数组
uint8_t RxBuff1;      //进入中断接收数据的数组1

uint8_t DataBuff; //保存接收到的数据的数组
volatile uint8_t DataBuff1; //保存接收到的数据的数组

int RxLine=0;         //接收到的数据长度
int Rx_flag=0;                  //接受到数据标志
int Rx_flag_finish=0;                  //接受完成或者时间溢出

volatile int RxLine1=0;         //接收到的数据长度
volatile int Rx_flag1=0;                  //接受到数据标志
volatile int Rx_flag_finish1=0;                  //接受完成或者时间溢出

void user_uart_callback (uart_callback_args_t * p_args)
{
    if(p_args->event == UART_EVENT_TX_COMPLETE)
    {
      uart_send_complete_flag = true;
    }
    if(p_args->event ==   UART_EVENT_RX_CHAR)
    {
      RxBuff = p_args->data;
      RxLine++;                      //每接收到一个数据,进入回调数据长度加1
      DataBuff=RxBuff;//把每次接收到的数据保存到缓存数组
      Rx_flag=1;
      if(RxBuff==0xff)            //接收结束标志位,这个数据可以自定义,根据实际需求,这里只做示例使用,不一定是0xff
      {
            Rx_flag_finish=1;
      }
      RxBuff=0;
      err = R_GPT_Reset(&g_timer0_ctrl);
      assert(FSP_SUCCESS == err);
    }
}

void user_uart1_callback (uart_callback_args_t * p_args)
{
    if(p_args->event == UART_EVENT_TX_COMPLETE)
    {
      uart1_send_complete_flag = true;
    }
    if(p_args->event ==   UART_EVENT_RX_CHAR)
    {
      RxBuff1 = p_args->data;
      RxLine1++;                      //每接收到一个数据,进入回调数据长度加1
      DataBuff1=RxBuff1;//把每次接收到的数据保存到缓存数组
      if(RxBuff1==0xaa)            //接收结束标志位,这个数据可以自定义,根据实际需求,这里只做示例使用,不一定是0xff
      {
            Rx_flag_finish1=1;
      }
      RxBuff1=0;
    }
}

#ifdef __GNUC__                                 //串口重定向
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
      err = R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
      if(FSP_SUCCESS != err) __BKPT();
      while(uart_send_complete_flag == false){}
      uart_send_complete_flag = false;
      return ch;
}
int _write(int fd,char *pBuffer,int size)
{
    for(int i=0;i<size;i++)
    {
      __io_putchar(*pBuffer++);
    }
    return size;
}
/* Callback function */
    void timer0_callback(timer_callback_args_t *p_args)
{
      /* TODO: add your own code here */
      if (TIMER_EVENT_CYCLE_END == p_args->event)
      {
            if(Rx_flag==1)
            {
                printf_usart();
                Rx_flag=0;
            }
      }
}

void analyse_distance()
{
    unsigned short distance = 0;
    if((DataBuff1 == 0xf0) && (DataBuff1 == 0x05))
    {
      distance = (DataBuff1 << 8) | (DataBuff1);
      printf("distance = %d cm\r\n",distance);
    }
}

void hal_entry(void)
{
    /* TODO: add your own code here */
    /* Open the transfer instance with initial configuration. */
    err = R_SCI_UART_Open(&g_uart0_ctrl, &g_uart0_cfg);
    assert(FSP_SUCCESS == err);

    err = R_SCI_UART_Open(&g_uart1_ctrl, &g_uart1_cfg);

    assert(FSP_SUCCESS == err);

    while(1)
    {
      R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT100->160
      if(Rx_flag_finish1==1)
      {
            // printf("enter\r\n");
            analyse_distance();
            Rx_flag_finish1 = 0;
            RxLine1 = 0;
      }
    }
#if BSP_TZ_SECURE_BUILD
       /* Enter non-secure code */
       R_BSP_NonSecureEnter();
   #endif
   }

void printf_usart(void)
{

    printf("length=%d\r\n",RxLine);
    for(int i=0;i<RxLine;i++)
      printf("data:[%d] = 0x%x\r\n",i,DataBuff);
    memset(DataBuff,0,sizeof(DataBuff));//清空缓存数组
    //memset()作用:可以方便的清空一个结构类型的变量或数组。
    //例句:memset(aTxbuffer,0,sizeof(aTxbuffer))用memset清空aTxbuffer。
    RxLine=0;//清空接收长度
    Rx_flag_finish=0;
    Rx_flag = 0;
}
/*******************************************************************************************************************//**
* This function is called at various points during the startup process.This implementation uses the event that is
* called right before main() to set up the pins.
*
* @paramevent    Where at in the start up process the code is currently at
**********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
    if (BSP_WARM_START_RESET == event)
    {
#if BSP_FEATURE_FLASH_LP_VERSION != 0

      /* Enable reading from data flash. */
      R_FACI_LP->DFLCTL = 1U;

      /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
         * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
    }

    if (BSP_WARM_START_POST_C == event)
    {
      /* C runtime environment and system clocks are setup. */

      /* Configure pins. */
      R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);
    }
}

#if BSP_TZ_SECURE_BUILD

BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();

/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{

}
#endif

int _close(int file) {
    return -1;   // 不支持关闭,返回错误
}

int _lseek(int file, int ptr, int dir) {
    return 0;    // 不支持定位,返回0
}

int _read(int file, char *ptr, int len) {
    return 0;    // 无输入,返回0(可在此通过UART实现接收)
}

int _fstat(int file, struct stat *st) {
    st->st_mode = S_IFCHR;   // 标记为字符设备
    return 0;
}

int _isatty(int file) {
    return 1;    // 假设所有文件描述符都是终端
}

7、测试视频
https://www.bilibili.com/video/BV1NJu168EUG/



页: [1]
查看完整版本: 【瑞萨RA-eco-RA6M4评测】- TOF测距实践篇