随着对瑞萨RA系列单片机学习的深入,逐渐掌握了基本的开发技巧。
本篇来到项目实践篇:即毫米波雷达测距仪项目。
整个项目的架构如图:
看起来有点绕,但也挺简单:
毫米波雷达模块的TX 输出探测信号,被MCU的RX侦测到,产生中断,接收数据,并经过运算(毫米波雷达输出的是原始信号,需要经过运算,才能得到我们想要的数据),将运算结果通过TXD引脚发出,进而被U2(CH340串口转USB)的RXD引脚接收到,最后输送到电脑端。
本次使用的毫米波雷达模块是:海凌科LD2450
LD2450是一款24G毫米波雷达系列中的运动目标跟踪/目标存在检测传感器模组,包含极简化24GHz雷达传感器硬件和智能算法固件。
传感器硬件由AloT毫米波雷达芯片、高性能一发两收微带天线和低成本MCU及外围辅助威廉希尔官方网站
组成。智能算法固件采用FMCW波形和雷达芯片专有的先进信号处理技术。支持串口输出检测数据,即插即用,可灵活应用于不同的智能场景和终端产品。
好了,言归正传,我们先了解下毫米波雷达的串口协议。
默认5V,其实3.3V也是支持的,在图中右上方有3.3V引脚。
模块IO输出电平为3.3V。串口默认波特率256000, 1停止位,无奇偶校验位。
该模块一上电,就会以0.2秒的间隔发送 30Byte的探测码。
如:
AA FF 03 00** 0E 03 B1 86 10 00 40 01** 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 CC
其中有价值的信息就是 0E 03 B1 86 10 00 40 01这一串,分别表示了X轴坐标,Y轴坐标,运动速度,分辨率。
当然原始数据需要经过运算,
得到X轴坐标,Y轴坐标,距离就好办了。
公式如图:
好了开始启动我们的项目:
unsigned char rec_buf[30];
unsigned char buff3[10];
int len=0;
int x=0;
}
///* 重定向 printf 输出 */
//#if defined __GNUC__ && !defined __clang__
//int _write(int fd, char *pBuffer, int size); //防止编译警告
//int _write(int fd, char *pBuffer, int size)
//{
// (void)fd;
// R_SAU_UART_Write(&g_uart0_ctrl, (uint8_t *)pBuffer, (uint32_t)size);
// while(uart_send_complete_flag == false);
// uart_send_complete_flag = false;
//
// return size;
//}
//#else
//int fputc(int ch, FILE *f)
//{
// (void)f;
// R_SAU_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
// while(uart_send_complete_flag == false);
// uart_send_complete_flag = false;
//
// return ch;
//}
//#endif
/* 串口中断回调 */
void uart_callback (uart_callback_args_t * p_args)
{
switch (p_args->event)
{
case UART_EVENT_RX_CHAR:
{
/* 把串口接收到的数据发送回去 */
rec_buf[len] = p_args->data;
len++;
if(len==30)
{
// 解析x和y距离
unsigned int x_distance = rec_buf[4] | (rec_buf[5] << 8);
unsigned int y_distance = rec_buf[6] | (rec_buf[7] << 8);
// 检查x_distance的最高位
if (rec_buf[5] & 0x80)
{
// x_distance最高位为1,表示正数,减去最高位的1。y永远为正直接减去0x8000
x_distance -= 0x8000;
y_distance -= 0x8000;
}
else // 最高位为0 表示x负距离。y永远为正直接减去0x8000
{
y_distance -= 0x8000;
}
//计算距离
unsigned int distance = sqrt(pow(x_distance,2)+ pow(y_distance,2));
//转换为10进制字符串
itoa(distance,buff3,10);
R_SAU_UART_Write(&g_uart0_ctrl,buff3,10);
len=0;
}
break;
}
case UART_EVENT_TX_COMPLETE:
{
uart_send_complete_flag = true;
break;
}
default:
break;
}
}
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
unsigned char buff1[]="毫米波雷达实验\r\n";
R_SAU_UART_Open(&g_uart0_ctrl, &g_uart0_cfg);
R_SAU_UART_Write(&g_uart0_ctrl, buff1, strlen(buff1));
while (!uart_send_complete_flag);
printf("Please Wait…… \r\n");
while(1){}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
需要说明:
uart_callback ,是串口每接手到1Byte都会产生中断,因此我们要收到毫米波雷达模块发来的30Byte完整信息,再做运算,因此:
rec_buf[len] = p_args->data; //每接受到1Byte数据
len++;
if(len==30) //收到毫米波雷达模块发来的30Byte完整信息
{
运算函数
R_SAU_UART_Write(&g_uart0_ctrl,buff3,10); //将运算结果发至串口
len=0; //计数归零,从新开始接收下一个完整信息
}
如下为程序演示结果:
(显示人距离毫米波雷达的距离,单位mm)
海凌科的这款毫米波雷达模块,实际上还具备蓝牙功能,配套官方提供的手机APP,可以直观查看探测结果,对比下来我们用瑞萨运算的结果是一致的(单位mm)。
更多回帖