前言
安信可新款雷达模组Rd-03D已经上市,该雷达采用一发两收的天线,可以实现目标跟踪,实现对区域内目标测距、测角和测速。
本应用示例使用STM32解析Rd-03D的串口数据,检测人体距离雷达的角度,根据角度不同点亮不同的灯珠。-60度到-20度点亮 LED1,-20度到20度点亮LED2,20度到60度点亮LED3
一:Rd-03D引脚说明
J1引脚说明:
J2引脚说明:
二:软件设计框架
三:STM32F103C8T6使用CubeMX搭配HAL库配置
打开CubeMX,选择STM32F103C8T6。
选择两个串口,分别是串口1和串口2,PA9为USART1_TX,PA10为USART1_RX,PA2为USART2_TX,PA3为USART_RX。
选择异步通讯,勾选中断,注意:串口1的波特率为256000,串口2波特率为115200。
设置GPIO口
四:STM32与Rd-03D和LED灯的接线
五:串口数据处理
Rd-03D的串口数据
Rd-03D模组通过串口(TTL电平)与外界通信,雷达串口默认波特率为256000,1停止位,无奇偶校验位。雷达输出检测到的目标信息,包括在区域中的x坐标,y坐标,以及目标的速度值(小端模式)。
上报是数据帧格式:
数据示例:AA FF 03 00 0E 03 B1 86 10 00 68 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 CC
红色部分表示目标1的信息,蓝色表示目标2的信息,绿色表示目标3的信息。
本示例展示解析单目标模式下对角度信息进行解析,所以需对单个目标内的数据进行解析(即目标1),其中单个目标具体包含内容如下:
根据目标X,Y坐标数据帧说明可知,若像上述数据示例,模组将目标1的角度数据转换为相关坐标信息的过程展示如下:
目标1x坐标:OxOE+Ox03*256= 782
0-782= -782 mm;
目标1y坐标:OxB1+Ox86*256 = 34481
34481-2^15= 1713 mm;
六:STM32数据处理
角度计算过程运用到了三角函数知识,求对边比邻边(即x/y)tan(θ)角度,如图:
具体实现代码:
- #define LED_ON_2 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
- #define LED_OFF_2 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
- #define LED_ON_4 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);
- #define LED_OFF_4 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
- #define LED_ON_6 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
- #define LED_OFF_6 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);
- #define PI 3.14159265
- uint8_t RX_BUF[64]={0}; //缓存数组
- uint8_t RX_count=0; //计数位
- uint8_t RX_temp; //缓存字符
- uint16_t range; //感应距离
- int16_t x_pos; //x轴坐标
- int16_t y_pos; //y轴坐标
- double angle; //角度
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//回调函数,检测到雷达发送一帧数据时进行处理
- {
-
- if(huart == &huart1){ //串口1触发中断
- RX_BUF[RX_count++] = RX_temp;//将缓存字符存入缓存数组中
- if((RX_BUF[RX_count-1] == 0xCC)&&(RX_BUF[RX_count-2] == 0x55)){//判断帧尾
- //sprintf(str,"4: %02x,5: %02x,6: %02x,7: %02x\r\n",RX_BUF[4],RX_BUF[5],RX_BUF[6],RX_BUF[7]);
- //HAL_UART_Transmit(&huart2,(uint8_t *)str,strlen(str),0xFFFF);
- if((0x00==RX_BUF[5])&&(0x00==RX_BUF[14])&&(0x00==RX_BUF[22]))//数据比较,雷达检测到无目标
- {
- LED_OFF_2;
- LED_OFF_4;
- LED_OFF_6;
- }
- else {
- x_pos=(RX_BUF[5]<<8)+RX_BUF[4];//获取X坐标
- y_pos=(RX_BUF[7]<<8)+RX_BUF[6];//获取Y坐标
- int16_t tempx,tempy;
- tempx = 0x8000&x_pos;//保留最高位
- x_pos = x_pos&0x7fff;//清除最高位
- if(!tempx){//判断最高位是否为0
- x_pos = -x_pos;//为0则取反(即坐标变负值)
- }
- //跟X坐标同理
- tempy = 0x8000&y_pos;
- y_pos = y_pos&0x7fff;
- if(!tempy){
- y_pos = -y_pos;
- }
-
-
- char x_y_pos[32]={0};
- sprintf(x_y_pos,"x_pos: %d,y_pos: %d\r\n",x_pos,y_pos);
- HAL_UART_Transmit(&huart2,(uint8_t *)x_y_pos,strlen(x_y_pos),0xFFFF); //输出X,Y轴坐标
-
- angle = atan2 (x_pos,y_pos) * 180.0 / PI;//使用三角函数公式反正切函数atan2得角度
- char angle_str[32]={0};
- sprintf(angle_str,"angle: %lf,\r\n",angle);
- HAL_UART_Transmit(&huart2,(uint8_t *)angle_str,strlen(angle_str),0xFFFF); //输出角度
-
- if((angle>=(-60)&&(angle<(-20)))) //-60度到-20度
- {
- LED_ON_2;
- LED_OFF_4;
- LED_OFF_6;
- }
- else if((angle>=(-20)&&(angle<=20))) //-20度到20度
- {
- LED_OFF_2;
- LED_ON_4;
- LED_OFF_6;
- }
- else if((angle>20&&(angle<=60))) //20度到60度
- {
- LED_OFF_2;
- LED_OFF_4;
- LED_ON_6;
- }
-
- }
- while(HAL_UART_GetState(&huart2)==HAL_UART_STATE_BUSY_TX);//判缓存数组是否发送完毕
- memset(RX_BUF,0x00,sizeof(RX_temp));//清空缓存数组
- RX_count = 0;//计数位置零
- }
- HAL_UART_Receive_IT(&huart1,&RX_temp,1);//串口1继续接收数据
- }
- }
复制代码 七:效果演示
https://www.bilibili.com/video/BV1uN41147Qm?p=4&vd_source=a701bf07bcd16747985957dcae125a44
八:源码地址
https://e.coding.net/axk/stm32_rd-03/STM32_Rd03D_LED.git
|