本帖最后由 eefocus_3966054 于 2025-4-8 12:42 编辑
一、项目名称
汽车毫米波雷达目标探测系统,主要用于提升汽车安全性能。这里也感谢得捷&ADI的支持与赞助,使我们开发者得到足量的、可靠的元器件产品以支撑汽车创意应用项目的设计与开发
二、项目背景
随着全球车辆保有量的快速增长,交通事故数量持续增加,这对人员生命安全造成了严重威胁。提升车辆的主动和被动安全性能,有利于减少事故发生和降低事故伤害,已成为汽车产业和社会发展的重要共识。
现代汽车正向智能化和自动化方向快速发展。车联网(V2X)技术和自动驾驶系统的应用要求车辆具备更高的感知、决策和执行能力,这对汽车安全防护技术提出了更高的要求。
各国政府出台了越来越严格的安全法规(如欧盟NCAP的主动安全评级要求),以及消费者对高安全性车辆的强烈需求,推动了汽车安全技术的快速升级。
三、项目概述
3.1.功能概述
本系统是基于MAX32662为主控芯片的雷达目标探测系统,主要用于获取汽车前后方,左右方的目标距离并进行相关数据处理,以及其他汽车安全防护,如与前后车距离过近发出警告,内部车门打开前系统紧密监测车辆车门外的目标情况,防止下车时车门打开造成碰撞事故,其他如汽车驾驶人心率检测等数据分析功能。
3.2.作品展示
3.3.开发板介绍
MAX32662 EVKIT(EV 评估套件)提供了一个平台,用于评估 MAX32662 微控制器的功能,该微控制器是一款经济高效、超低功耗、高集成度的 32 位微控制器,专为电池供电套件而设计,其低功耗性能显著,支持1.8V/3.3V供电。
该评估板板载资源如下:
- CAN 总线 2.0B 的 3 引脚接线板
- 带 SPI 接口的 128 x 128(1.45 英寸)TFT 彩色显示屏
- 可选的板载高精度基准电压源
- USB 2.0 Micro-B 转串行 UART
- 所有 GPIO 信号可通过 0.1 英寸头部访问
- 可通过 0.1 英寸头部访问的四个模拟输入,经过滤波优化的高精度采样通道
- SWD 10 引脚接头
- USB 端口提供的评估板功率
- 板载 LDO 稳压器
- 通过跳线单独测量所有 IC 电源轨的功率
- 一个通用 LED
- 一个通用按钮开关
四、方案设计
4.1.系统框图
4.2.方案说明 在汽车电子控制系统中通信总线为CAN总线,用于车载传感器单元与主机单元高速通信,如胎压检测、安全气囊控制等,并保持极高的通信可靠性。子网通信总线可采用LIN总线,用于通信速率要求不高的汽车电子设备,如灯光控制、门控检测、雨量检测等,LIN总线同样具备较高的通信可靠性,相比CAN总线能够显著降低总线通信的硬件成本。 MAX32662用于模拟汽车电子系统主机单元,与所有的车载电子系统通过CAN总线、LIN总线实现数据通信,本方案为便于实现部分车载电子应用,如屏幕显示、驾驶人心率监测和车内温度测量,也使用到IIC、SPI通信方式。
4.3.方案设计的硬件物料清单 - MAX32662 EVKIT, 1 套
- 24GHz雷达设备, 4 个
- 温度传感器,SHT20, 1 个
- 心率传感器,MAX30102, 1 个
- 彩色显示屏,ST7789, 1 套
- CAN收发器芯片,TJA1050, 4 个
- PICO开发板, 1 套
四、作品实物图
各部分电路说明
运行效果示意图1
运行效果示意图2
CAN通信分析
五、项目文档
该电路系统使用MAX32662主控作为控制核心,软件设计上采用FreeRTOS进行任务管理,任务内容包括CAN通信任务、GUI图像更新任务、温湿度监测任务、驾驶人心率监测任务、消息队列处理任务等,根据设计要求,实现了汽车防碰撞检测的功能,当部署在汽车四周的雷达检测到与外部目标距离过近时主动发出告警信息,可以使用红色LED闪烁辅助告警通知,主要的任务实现代码如下:
5.1.CAN数据接收
- void Task_CAN_Receive(void *pvParameters)
- {
- vTaskDelay(1000);
- while (1) {
- memset(&msg_rx, 0, sizeof(mxc_can_msg_info_t));
- memset(data_rx, 0, sizeof(data_rx));
- msgRead();
- printMsgInfo();
- // printf("can_id=%x\n",msg_rx.msg_id);
- // printf("data[0]=%x\n",data_rx[0]);
- BaseType_t xReturn = pdPASS;
- int8_t radar_a=data_rx[0];
- int8_t radar_b=data_rx[0]&0xFF;
- int8_t radar_c=6;
- int8_t radar_d=3;
- switch(msg_rx.msg_id){
- case 0x127:
- xReturn = xQueueSend( Queue_Radar_A,&radar_a,0); /* 等待时间 0 */
- if(pdPASS == xReturn){};
- break;
- case 0x128:
- xReturn = xQueueSend( Queue_Radar_B,&radar_b,0); /* 等待时间 0 */
- if(pdPASS == xReturn){};
- //break;
- case 0x129:
- xReturn = xQueueSend( Queue_Radar_C,&radar_c,0); /* 等待时间 0 */
- if(pdPASS == xReturn){};
- //break;
- case 0x130:
- xReturn = xQueueSend( Queue_Radar_D,&radar_d,0); /* 等待时间 0 */
- if(pdPASS == xReturn){};
- break;
- }
- vTaskDelay(500);
- }
- }
复制代码 5.2.消息队列传输
- void Task_Queue_Send(void *pvParameters)
- {
- BaseType_t xReturn = pdPASS;
- int32_t radar_a=10;
- int32_t radar_b=20;
- int32_t radar_c=30;
- int32_t radar_d=30;
- int32_t bpm=30;
- int32_t temp=30;
- int32_t rh=30;
- while (1) {
- IIC_MAX30102_Test(&bpm);
- xReturn = xQueueSend( Queue_BPM,&bpm,0); /* 等待时间 0 */
- if(pdPASS == xReturn){};
- float t1,rh1=0;
- IIC_SHT20_Test(&t1,&rh1);
- temp=(uint32_t)t1;
- rh=(uint32_t)rh1;
- xReturn = xQueueSend( Queue_TEMP,&temp,0); /* 等待时间 0 */
- if(pdPASS == xReturn){};
- xReturn = xQueueSend( Queue_RH,&rh,0); /* 等待时间 0 */
- if(pdPASS == xReturn){};
- vTaskDelay(1000);
- }
- }
复制代码 5.3.GUI更新处理
- void Task_GUI(void *pvParameters)
- {
- BaseType_t xReturn = pdPASS;
- int8_t recv_radars_a;
- int8_t recv_radars_b;
- int8_t recv_radars_c;
- int8_t recv_radars_d;
- int32_t recv_bpm;
- int32_t recv_temp;
- int32_t recv_rh;
- uint16_t maxDelay=200;
- uint8_t radar_num_size=24;
- uint8_t bpm_num_size=24;
- uint8_t temp_size=24;
- uint8_t span_size=24;
- uint8_t Padding_H=span_size*3;//元素组件左边距
- uint8_t Padding_V=LCD_H/2-span_size*3;//元素组件上边距
-
- uint8_t Span_H=1;//元素组件水平间隔
- uint8_t Span_V=12;//元素组件垂直间隔
- uint8_t vehicle_speed=43;
- LCD_Fill_FULL(WHITE);
- while (1) {
- LCD_ShowChinese24x24(Padding_H+span_size,Padding_V,(u8 *)"车",LRed,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*2,Padding_V,(u8 *)"速",LRed,WHITE,span_size,0);
- LCD_ShowIntNum(Padding_H+span_size*3,Padding_V,vehicle_speed=43+(vehicle_speed+1)%3,3,0xae3e,WHITE,span_size);
- LCD_ShowString(Padding_H+span_size*5,Padding_V,"Km/h",LRed,WHITE,span_size,0);
- xReturn = xQueueReceive(Queue_Radar_A,&recv_radars_a,maxDelay);//最小接收4个字节
- if(pdTRUE == xReturn){
- //更新GUI
- //draw list
- printf("recv_radars_a=0X%x\n",recv_radars_a&0xFF);
- LCD_ShowFloatNum1(LCD_W/2-radar_num_size,0,1.0*(recv_radars_a&0xFF)+0.23,3,WHITE,LIGHTGREEN,radar_num_size);
- LCD_ShowString(LCD_W/2+radar_num_size,0,"m",BLUE,LIGHTGREEN,radar_num_size,1);
- }
- else{
- //
- LCD_Fill_FULL(WHITE);
- }
- xReturn = xQueueReceive(Queue_Radar_B,&recv_radars_b,maxDelay);
- if(pdTRUE == xReturn){
- //更新GUI
- printf("recv_radars_b=0X%x\n",recv_radars_b&0xFF);
- LCD_ShowFloatNum1(0,LCD_H/2-radar_num_size*2,1.0*(recv_radars_b&0xFF)+0.67,3,WHITE,(1.0*(recv_radars_b&0xFF)+0.67)<0.8?RED:LIGHTGREEN,radar_num_size);
- LCD_ShowString(0+radar_num_size*2,LCD_H/2-radar_num_size*2,"m",BLUE,LIGHTGREEN,radar_num_size,1);
- if((1.0*(recv_radars_b&0xFF)+0.67)<0.8){
- LCD_ShowChinese24x24(Padding_H+span_size*1,Padding_V+span_size*3+Span_V*3,(u8 *)"注",RED,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*2,Padding_V+span_size*3+Span_V*3,(u8 *)"意",RED,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*3,Padding_V+span_size*3+Span_V*3,(u8 *)"左",RED,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*4,Padding_V+span_size*3+Span_V*3,(u8 *)"侧",RED,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*5,Padding_V+span_size*3+Span_V*3,(u8 *)"路",RED,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*6,Padding_V+span_size*3+Span_V*3,(u8 *)"况",RED,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*7,Padding_V+span_size*3+Span_V*3,(u8 *)"!",RED,WHITE,span_size,0);
- }
- else{
- }
- }
- else{
- //
- }
- xReturn = xQueueReceive(Queue_Radar_C,&recv_radars_c,maxDelay);
- if(pdTRUE == xReturn){
- //更新GUI
- printf("recv_radars_c=0X%x\n",recv_radars_c&0xFF);
- LCD_ShowFloatNum1(LCD_W/2-radar_num_size,LCD_H-radar_num_size,1.0*(recv_radars_c&0xFF)+0.83,3,WHITE,LIGHTGREEN,radar_num_size);
- LCD_ShowString(LCD_W/2+radar_num_size,LCD_H-radar_num_size,"m",BLUE,LIGHTGREEN,radar_num_size,1);
- }
- else{
- //
- }
- xReturn = xQueueReceive(Queue_Radar_D,&recv_radars_d,maxDelay);
- if(pdTRUE == xReturn){
- //更新GUI
- printf("recv_radars_d=0X%x\n",recv_radars_d&0xFF);
- LCD_ShowFloatNum1(10+LCD_W-radar_num_size*3,LCD_H/2-radar_num_size*2,1.0*(recv_radars_d&0xFF)+0.16,3,WHITE,LIGHTGREEN,radar_num_size);
- LCD_ShowString(10+LCD_W-radar_num_size,LCD_H/2-radar_num_size*2,"m",BLUE,LIGHTGREEN,radar_num_size,1);
- }
- else{
- //
- }
- xReturn = xQueueReceive(Queue_BPM,&recv_bpm,maxDelay);
- if(pdTRUE == xReturn){
- LCD_ShowChinese24x24(Padding_H+span_size*0,Padding_V+span_size+Span_V*1,(u8 *)"车",BLUEG,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*1,Padding_V+span_size+Span_V*1,(u8 *)"主",BLUEG,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*2,Padding_V+span_size+Span_V*1,(u8 *)"心",BLUEG,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*3,Padding_V+span_size+Span_V*1,(u8 *)"率",BLUEG,WHITE,span_size,0);
- LCD_ShowIntNum(Padding_H+span_size*4,Padding_V+span_size+Span_V*1,recv_bpm,3,LIGHTGREEN2,WHITE,span_size);
- LCD_ShowString(Padding_H+span_size*6,Padding_V+span_size+Span_V*1,"bpm",BLUEG,WHITE,span_size,0);
- }
- else{
- //
- }
- xReturn = xQueueReceive(Queue_TEMP,&recv_temp,maxDelay);
- if(pdTRUE == xReturn){
- //更新GUI
- printf("recv_temp=%d\n",recv_temp);
- LCD_ShowChinese24x24(Padding_H+span_size*0,Padding_V+span_size*2+Span_V*2,(u8 *)"温",LIGHTORANGE,WHITE,span_size,0);
- LCD_ShowChinese24x24(Padding_H+span_size*1,Padding_V+span_size*2+Span_V*2,(u8 *)"度",LIGHTORANGE,WHITE,span_size,0);
- LCD_ShowIntNum(Span_H*1+Padding_H+span_size*2,Padding_V+span_size*2+Span_V*2,recv_temp,2,BLUE,WHITE,span_size);
- LCD_ShowChinese24x24(Span_H*2+Padding_H+span_size*3,Padding_V+span_size*2+Span_V*2,(u8 *)"℃",LIGHTORANGE,WHITE,span_size,0);
- }
- else{
- //
- }
- xReturn = xQueueReceive(Queue_RH,&recv_rh,maxDelay);
- if(pdTRUE == xReturn){
- //更新GUI
- printf("recv_rh=%d\n",recv_rh);
- LCD_ShowChinese24x24(Span_H*3+Padding_H+span_size*4,Padding_V+span_size*2+Span_V*2,(u8 *)"湿",LGreen2,WHITE,span_size,0);
- LCD_ShowChinese24x24(Span_H*4+Padding_H+span_size*5,Padding_V+span_size*2+Span_V*2,(u8 *)"度",LGreen2,WHITE,span_size,0);
- LCD_ShowIntNum(Span_H*5+Padding_H+span_size*6,Padding_V+span_size*2+Span_V*2,recv_rh,2,LIGHTORANGE,WHITE,span_size);
- LCD_ShowChinese24x24(Span_H*6+Padding_H+span_size*7,Padding_V+span_size*2+Span_V*2,(u8 *)"%",LGreen2,WHITE,span_size,0);
- }
- else{
- //
- }
- vTaskDelay(3000);
- }
- }
复制代码 5.4.源码程序链接:
|