尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
stm32F103C8T6标准库综合实验二感应灯具(RD03雷达)
目录1.传感器准备工作2.redme3.实验项目核心部分3.1 模式菜单(自动模式-常亮模式-常灭模式)3.2 模式循环切换3.3 RD03雷达处理函数3.4 按键切换状态3.5 反射传感器切换模式1.传感器准备工作2.redme/********************************************************************************************/【】程序简介-工程名称 综合实验二 感应灯具RD03雷达-实验平台 野火 STM32F103C8T6-STM32开发板【 】功能简介1-RD03雷达模块定期自动发送数据给开发板开发板接收数据后进行处理再把处理结果返回给上位机2-感应灯部分工作模式(按键/反射传感器切换)1自动模式1.设备上电后为“自动模式“ 核心板绿灯长亮其他板载指示灯灭2.当雷达触发LED4亮否则灭2常亮模式1.设备切换为“常亮模式“ 核心板蓝灯长亮其他板载指示灯灭2.LED4进入亮3常灭模式1.设备切换为“常灭模式“ 核心板红灯长亮其他板载指示灯灭2.LED4进入灭3模式切换按KEY1或者使用手遮挡反射传感器一段固定时间约一秒多程序可自定义可来回循环切换“自动模式”、“常亮模式”、“常灭模式”。【 】实验操作1.保证开发板相关硬件连接正确用USB线连接开发板的USB转串口跟电脑 2.在电脑端打开串口调试助手并配置好相关参数115200 8-N-1 3.编译并下载程序到开发板即可观察现象。 4.复位开发板RD03雷达模块定期自动发送数据给开发板开发板接收数据后进行处理再把处理结果返回给上位机 5-感应灯部分 工作模式(按键/反射传感器切换) 1自动模式 1.设备上电后为“自动模式“ 核心板绿灯长亮其他板载指示灯灭 2.当雷达触发LED4亮否则灭 2常亮模式 1.设备切换为“常亮模式“ 核心板蓝灯长亮其他板载指示灯灭 2.LED4进入亮 3常灭模式 1.设备切换为“常灭模式“ 核心板红灯长亮其他板载指示灯灭 2.LED4进入灭 3模式切换按KEY1或者使用手遮挡反射传感器一段固定时间约一秒多程序可自定义可来回循环切换“自动模式”、“常亮模式”、“常灭模式”。/*********************************************************************************************/【*】 引脚分配KEY1-PA0 按键按下为高电平 核心板板载默认下拉且硬件有消抖NRST-NRST 按键按下为低电平 核心板板载默认上拉且硬件有消抖LED_R-LED1-PA1 核心板板载LED灯低电平亮LED_G-LED2-PA2 核心板板载LED灯低电平亮LED_B-LED3-PA3 核心板板载LED灯低电平亮LED4-PB5 用户自定义LED灯低电平亮DEBUG_TX-USART1_TXD-PA9 PA9作为USART1的TXD 核心板默认使用 PA9 做 DEBUG_TXDEBUG_RX-USART1_RXD-PA10 PA10作为USART1的RXD 核心板默认使用 PA10 做 DEBUG_RXRD03_TX-USART3_TXD-PB10 PB10作为USART3的TXD RD03雷达模块串口_TXRD03_RX-USART3_RXD-PB11 PB11作为USART3的RXD RD03雷达模块串口_RX热敏模块AO —不接TRACK_DO —PA11循迹传感器达不到阈值的时候D0是高电平达到阈值的时候D0是低电平VDD —3V3GND —GND/*********************************************************************************************/3.实验项目核心部分3.1 模式菜单(自动模式-常亮模式-常灭模式)由于需要三种模式所以定义一个枚举模式枚举/* 模式切换 */typedefenum{Sensor_Light_Mode_Auto0,//自动模式Sensor_Light_Mode_AlwaysOn1,//常亮模式Sensor_Light_Mode_AlwaysOff2,//常灭模式Sensor_Light_Mode_NUM3,//用来统计枚举数量作为临界点判断}Sensor_Light_Mode_Type;再定义一个结构体用来封装感应灯信息/*感应灯/反射传感器 模式状态信息*/typedefstruct{Sensor_Light_Mode_Type mode;ReflectSensor_StateType last_state;uint32_ttime;}Sensor_Light_Mode_State_Info;各个模式处理的功能函数模块/** * brief 感应灯具 模式配置(指定模式配置) * param mode感应灯模式 * retval 无 */voidSensor_Light_Set_Mode(Sensor_Light_Mode_Type mode){switch(mode){//自动模式caseSensor_Light_Mode_Auto:{/* 绿灯常亮(G) 其他灯灭(R、B、LED4) */LED_GPIO_OFF(R_LED1_GPIO_PORT,R_LED1_GPIO_PIN,LED_LOW_TRIGGER);LED_GPIO_ON(G_LED2_GPIO_PORT,G_LED2_GPIO_PIN,LED_LOW_TRIGGER);LED_GPIO_OFF(B_LED3_GPIO_PORT,B_LED3_GPIO_PIN,LED_LOW_TRIGGER);LED_GPIO_OFF(LED4_GPIO_PORT,LED4_GPIO_PIN,LED_LOW_TRIGGER);printf(Sensor_Light_Mode_Auto\n);/* 保存当前模式状态(自动模式) */Sensor_Light_ModeState.modeSensor_Light_Mode_Auto;break;}//常亮模式caseSensor_Light_Mode_AlwaysOn:{/* 蓝灯、LED4常亮(B、LED4) 其他灯灭(R、G) */LED_GPIO_OFF(R_LED1_GPIO_PORT,R_LED1_GPIO_PIN,LED_LOW_TRIGGER);LED_GPIO_OFF(G_LED2_GPIO_PORT,G_LED2_GPIO_PIN,LED_LOW_TRIGGER);LED_GPIO_ON(B_LED3_GPIO_PORT,B_LED3_GPIO_PIN,LED_LOW_TRIGGER);LED_GPIO_ON(LED4_GPIO_PORT,LED4_GPIO_PIN,LED_LOW_TRIGGER);printf(Sensor_Light_Mode_AlwaysOn\n);/* 保存当前模式状态(常亮模式) */Sensor_Light_ModeState.modeSensor_Light_Mode_AlwaysOn;break;}//常灭模式caseSensor_Light_Mode_AlwaysOff:{/* 红灯常亮(R) 其他灯灭(G、B、LED4) */LED_GPIO_ON(R_LED1_GPIO_PORT,R_LED1_GPIO_PIN,LED_LOW_TRIGGER);LED_GPIO_OFF(G_LED2_GPIO_PORT,G_LED2_GPIO_PIN,LED_LOW_TRIGGER);LED_GPIO_OFF(B_LED3_GPIO_PORT,B_LED3_GPIO_PIN,LED_LOW_TRIGGER);LED_GPIO_OFF(LED4_GPIO_PORT,LED4_GPIO_PIN,LED_LOW_TRIGGER);printf(Sensor_Light_Mode_AlwaysOff\n);/* 保存当前模式状态(常灭模式) */Sensor_Light_ModeState.modeSensor_Light_Mode_AlwaysOff;break;}default:break;}}自动模式绿灯亮红灯、蓝灯灭LED4受到雷达影响常亮模式蓝灯亮绿灯红灯灭LED4亮常灭模式红灯亮绿灯蓝灯灭LED4灭初始化是自动模式所以可以在初始化部分调用该函数传递模式是自动模式3.2 模式循环切换枚举定义结构体封装/* 模式切换 */typedefenum{Sensor_Light_Mode_Auto0,//自动模式Sensor_Light_Mode_AlwaysOn1,//常亮模式Sensor_Light_Mode_AlwaysOff2,//常灭模式Sensor_Light_Mode_NUM3,//用来统计枚举数量作为临界点判断}Sensor_Light_Mode_Type;/*感应灯/反射传感器 模式状态信息*/typedefstruct{Sensor_Light_Mode_Type mode;ReflectSensor_StateType last_state;uint32_ttime;}Sensor_Light_Mode_State_Info;模式循环切换函数模块/** * brief 感应灯具 模式配置(循环切换[自动-常亮-常灭]) * param 无 * retval 无 */voidSensor_Light_SwitchMode(void){Sensor_Light_Mode_Type mode_temp(Sensor_Light_Mode_Type)(Sensor_Light_ModeState.mode1);if(mode_tempSensor_Light_Mode_NUM){mode_tempSensor_Light_Mode_Auto;}Sensor_Light_Set_Mode(mode_temp);}每一次调用这个函数当前模式枚举的值1当如果达到3就切换到自动模式同时还需要调用设置模式函数3.3 RD03雷达处理函数当检测到有人LED4亮无人LED4灭同时是只能在自动模式才能处理。思路在RD03应用层定义RD03枚举枚举有人和无人然后用结构体封装在RD03应用层中将检测的有人和无人状态保存在结构体封装的枚举里面由于该结构体变量设置的作用域是static只能被自己的源文件夹访问不可以被其他源文件访问所以我还需要写一个对外扩展的函数接口返回被封装的雷达检测状态结构体变量。在雷达处理函数中1.判断当前是不是自动模式如果是才有以下操作2.通过雷达状态对外扩展的函数接口获取雷达检测状态有人/无人3.判断当前有人LED4亮4.判断当前无人LED4灭RD03状态枚举以及结构体封装// 雷达目标检测状态枚举typedefenum{RD03_STATUS_NONE0,// 无人RD03_STATUS_DETECTED1,// 有人}Rd03_StatusTypeDef;typedefstruct{Rd03_StatusTypeDef human_status;// 枚举有人/无人状态uint16_tdistance;// 检测距离}Rd03_ResultInfo;对外扩展雷达结构体检测信息staticRd03_ResultInfo Rd03_Result{RD03_STATUS_NONE,0};/** * brief RD03串口 目标信息获取 * param 无 * retval 无 */Rd03_ResultInfoRD03_GetResult(void){//获取人状态: 有人/无人 距离returnRd03_Result;}感应灯具雷达处理函数/** * brief 感应灯具 RD03雷达数据处理函数 * param 无 * retval 无 */voidSensor_Light_Rd03_DataHandle(void){//自动模式if(Sensor_Light_ModeState.modeSensor_Light_Mode_Auto){//获取雷达检测结果: 有人/无人/距离Rd03_ResultInfo resultRD03_GetResult();//有人 LED4点亮if(result.human_statusRD03_STATUS_DETECTED){LED_GPIO_ON(LED4_GPIO_PORT,LED4_GPIO_PIN,LED_LOW_TRIGGER);}//无人 LED4灭elseif(result.human_statusRD03_STATUS_NONE){LED_GPIO_OFF(LED4_GPIO_PORT,LED4_GPIO_PIN,LED_LOW_TRIGGER);}}}3.4 按键切换状态只需要在按键任务处理函数里面去调用循环切换函数即可/** * brief 按键 任务 * param 无 * retval 无 */voidKey_Task(void){if(key_task.flag1){KEY_Evnet current_event;current_eventKEY_SystickScan(key1_info);/* 短按*/if(current_eventEVENT_SHORT_RELEASE){//模式切换(自动-常亮-常灭)Sensor_Light_SwitchMode();}Key_TaskReset();}}3.5 反射传感器切换模式反射传感器有两种状态遮挡/无遮挡所以需要定义一个枚举接着将反射传感器枚举状态变量封装在结构体里面。还需要在结构体里面定义一个保存时间的。思路定义一个临时枚举变量用来获取当前反射传感器检测到有遮挡还是无遮挡。定义一个静态结构体变量这个变量封装了反射传感器两种状态的变量以及还有一个时间变量初始化反射传感器状态是无遮挡时间是0通过分支判断分支1.初始化是无遮挡当前检测状态是有遮挡结构体反射传感器有无遮挡状态设置遮挡状态并且时间变量记录当前起始时间这个时间通过配置定时器每1ms中断一次定义了一个变量每次值1通过返回该变量的值获取时间。分支2 变量结构体保存的状态是遮挡状态当前状态是无遮挡每隔20ms轮询一次检测意思是上一次检测的状态是遮挡状态保存起来了当前反射传感器检测状态是无遮挡就是在遮挡小于1s范围内取消遮挡了。结构体反射传感器有无遮挡状态设置无遮挡状态分支3 变量结构体保存的状态是遮挡状态当前状态是遮遮挡定义一个时间临时变量判断当前的时间 与第一次分支1记录的时间做差值结果大于1200而这个1200可以用一个宏定义封装起来当结果大于1200说明时间到了调用循环切换函数结构体保存的时间不是初始化0.时间到了切换状态保存时间初始话0的后果假设时间初始化0当我手一直遮挡就算1200到了我还是在遮挡也就是分支3还在进去的临时时间变量值- 0 肯定大于1200的就会瞬间又切换模式了也就是说我第一次遮挡了模式切换了然后瞬间20ms轮询给人感觉瞬间秒切换下一个模式了。正确做法是保存的时间保存通过获取当前的时间函数的时间值。就算下一次20ms轮询继续进去结构体时间变量记录上一次模式切换的时间。时间临时变量保存下一次20ms轮询的时间做差值只是20ms并不会大于1200不会出现瞬间切换下一根模式这种问题。遮挡枚举结构体定义// 反射式红外传感器状态枚举typedefenum{Sensor_Light_TRACK_NO_BLOCK0,// 无遮挡收到反射光Sensor_Light_TRACK_BLOCKED1// 有遮挡挡住没有反射}ReflectSensor_StateType;/*感应灯/反射传感器 模式状态信息*/typedefstruct{Sensor_Light_Mode_Type mode;ReflectSensor_StateType last_state;uint32_ttime;}Sensor_Light_Mode_State_Info;遮挡模式切换处理函数/** * brief 感应灯具 反射传感器 数据处理函数 * param 无 * retval 无 */voidSensor_Light_Track_DataHandle(void){ReflectSensor_StateType curr_state;//Bit_SET(没有检测到物体)、Bit_RESET(检测到物体)if(TRACK_Scan(TRACK_GPIO_PORT,TRACK_GPIO_PIN)Bit_RESET){curr_stateSensor_Light_TRACK_BLOCKED;}else{curr_stateSensor_Light_TRACK_NO_BLOCK;}//上一次检测状态是初始化当前检测状态是有遮挡if(Sensor_Light_ModeState.last_stateSensor_Light_TRACK_NO_BLOCKcurr_stateSensor_Light_TRACK_BLOCKED){Sensor_Light_ModeState.last_stateSensor_Light_TRACK_BLOCKED;Sensor_Light_ModeState.timeSysTick_GetCount();}//上一次检测状态是遮挡当前检测状态是无遮挡elseif(Sensor_Light_ModeState.last_stateSensor_Light_TRACK_BLOCKEDcurr_stateSensor_Light_TRACK_NO_BLOCK){Sensor_Light_ModeState.last_stateSensor_Light_TRACK_NO_BLOCK;Sensor_Light_ModeState.time0;}//上一次检测状态和当前状态都是遮挡状态elseif(Sensor_Light_ModeState.last_stateSensor_Light_TRACK_BLOCKEDcurr_stateSensor_Light_TRACK_BLOCKED){int32_tcurr_timeSysTick_GetCount();//获取当前的时间if(curr_time-Sensor_Light_ModeState.timeSWITCH_HOLD_MS){Sensor_Light_SwitchMode();Sensor_Light_ModeState.timeSysTick_GetCount();}}}
RELATED

相关推荐

告别手写前端:Infinite Monitor自然语言生成Widget的5大核心场景与上手教程

告别手写前端:Infinite Monitor自然语言生成Widget的5大核心场景与上手教程

【免费下载链接】infinite-monitor Monitor anything in real time 项目地址: https://gitcode.com/gh_mirrors/in/infinite-monitor 点击查看 免费下载 Infinite Monitor 是一款 AI 驱动的仪表盘构建工具:用自然语言描述你想要的 Widget,AI…

📅 2026/10/31 1:57:02
10分钟跑通Polymarket Copy Trading Bot:新手快速开始指南(钱包+USDC+MongoDB全配置)

10分钟跑通Polymarket Copy Trading Bot:新手快速开始指南(钱包+USDC+MongoDB全配置)

【免费下载链接】polymarket-copy-trading-bot 项目地址: https://gitcode.com/gh_mirrors/mar/polymarket-copy-trading-bot 点击查看 免费下载 本文带你 10 分钟从零跑通 Polymarket Copy Trading Bot(Polymarket 跟单机器人):…

📅 2026/10/31 1:57:02
Sealos 集群部署与应用交付实战指南:一条命令拉起 K8s,再十分钟上线一个应用

Sealos 集群部署与应用交付实战指南:一条命令拉起 K8s,再十分钟上线一个应用

Sealos 集群部署与应用交付实战指南:一条命令拉起 K8s,再十分钟上线一个应用 【免费下载链接】Sealos 以应用为中心的智能云操作系统 项目地址: https://gitcode.com/labring/Sealos 搭建一个能跑业务的 Kubernetes 集群,传统做法是把…

📅 2026/10/31 1:57:02
MORE NEWS

更多资讯

📰

VSCode中Vue i18n提效工具配置与实战

1. 为什么需要VSCode中的Vue i18n提效工具在Vue项目开发中,国际化(i18n)是让应用支持多语言的关键功能。传统i18n工作流程存在几个痛点:开发人员需要频繁在代码和语言文件之间切换;难以实时预览翻译效果;新增语言键值时需要手动同…

📰

生产管理系统源码拆解:工单闭环与报工入库实战

简介:这份生产管理系统源代码面向制造型企业信息化开发者与计算机专业学习者,提供一套可直接研读或二次开发的完整业务系统实现,覆盖生产计划、物料需求计划、库存管理、生产进度跟踪、质量控制、订单管理、报表分析、系统集成及权限控制等核…

📰

Spring Boot多数据源与分库分表实战:动态路由与分片方案

简介:这份资源面向需要掌握多数据源与分库分表技术的 Spring Boot 开发者,聚焦同一数据库内水平分表与跨库分库的落地实现。项目基于 Spring Boot 搭建,多数据源部分采用 mybatis-plus 的 dynamic-datasource,分库分表由 sharding…

📰

MySQL 8.0 ZIP包安装指南与配置优化

1. MySQL 8.0.44 ZIP包安装概述MySQL作为最流行的开源关系型数据库之一,其安装方式多样。对于Windows平台用户而言,通过官方提供的ZIP压缩包进行安装,相比MSI安装器具有更高的灵活性和可控性。这种安装方式特别适合需要自定义配置路径、同时运…

📰

前端自适应设计:核心原理与最佳实践

1. 前端自适应设计的核心价值与挑战在移动互联网时代,用户访问网站的终端设备呈现爆炸式增长。根据最新统计,全球活跃的移动设备数量已超过150亿台,屏幕尺寸从3英寸的智能手表到85英寸的智能电视不等。这种设备碎片化现象使得传统的固定宽度网…

📰

计算机整数表示:补码原理与编程实践

1. 整数在计算机中的表示基础计算机内部所有数据最终都以二进制形式存储和处理。整数作为最基本的数据类型之一,其表示方式直接影响着程序的正确性和性能。现代计算机系统通常采用补码(Twos complement)表示有符号整数,这种设计使…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬