基于STM32F103C8的双轴太阳能自动追光系统Proteus仿真
基于 STM32F103C8 的双轴太阳能自动追光系统 Proteus 仿真前言本文设计了一套基于 STM32F103C8 的双轴太阳能自动追光系统。系统使用东、南、西、北四个光敏电阻检测光照方向通过两个步进电机分别控制水平轴和俯仰轴使太阳能板朝向光照更强的方向。系统具有自动追光和手动控制两种工作模式。自动模式根据四路光敏电阻的 ADC 数据计算东西方向、南北方向的光照差值手动模式通过五个独立按键调整双轴角度。USART3 连接 Proteus 虚拟终端支持模式切换、角度设置、状态查询和帮助命令。OLED 显示当前工作模式、四路光强、总光强和双轴角度。开发环境如下项目说明主控芯片STM32F103C8开发工具Keil MDK 5编译器ARM Compiler 5固件库STM32F10x 标准外设库仿真软件Proteus显示模块0.96 英寸 OLED执行机构两个四相步进电机电机驱动两片 ULN2003A通信接口USART39600 bit/s完整工程资料免费获取点赞 收藏本文并在评论区留言“太阳能追光系统”即可免费获取完整工程网盘链接。工程资料包含Keil 源码、Proteus 仿真文件、可直接加载的 HEX 文件和项目演示视频。闲鱼店铺大嘴花电子专注单片机仿真与实物定制支持 STM32、51 单片机、Arduino、Proteus 仿真等。有需要仿真文件、代码程序、实物制作的朋友都可以咨询。价格优惠沟通好需求后定制方案谢谢支持一、系统运行总图图 1 太阳能双轴追光系统 Proteus 运行总图整个系统由 STM32 最小系统、四路光敏检测、双轴步进电机、ULN2003A 驱动、五个控制按键、OLED 和虚拟终端组成。运行截图中OLED 已进入AUTO自动追光模式显示总光强T:4072四路 ADC 数据分别为E:1258、S:973、W:1008、N:1074水平轴与俯仰轴角度显示为M1:064.00、M2:-064.00。虚拟终端同步输出AUTO、MANU、HELP、M1和M2命令说明说明显示、串口和控制程序已经共同运行。四个光敏电阻按照方位分布E东侧光敏电阻S南侧光敏电阻W西侧光敏电阻N北侧光敏电阻。水平轴根据东、西光照差值转动俯仰轴根据南、北光照差值转动。两个方向的光强差进入阈值范围后电机停止追光机构保持当前位置。二、系统功能本系统实现以下功能采集东、南、西、北四路光敏电阻电压每路 ADC 连续采样 8 次并计算平均值计算东西方向光强差和南北方向光强差自动控制水平轴向东或向西转动自动控制俯仰轴向南或向北转动总光强低于夜间阈值时停止自动追光按键切换自动模式和手动模式手动调节水平轴和俯仰轴角度OLED 显示模式、光强和双轴角度虚拟终端发送命令控制模式和目标角度查询当前四路光强、差值和电机位置。系统控制流程如下系统初始化 ↓ 读取四路光敏 ADC ↓ 计算东西、南北光强差 ↓ 处理串口命令与模式按键 ↓ 自动模式执行双轴追光 手动模式处理四个角度按键 ↓ 每 200 ms 刷新 OLED ↓ 返回四路光敏采集三、STM32 最小系统与控制接口图 2 STM32 最小系统、按键、虚拟终端和 OLED主控采用 STM32F103C8。复位电路由 10 kΩ 上拉电阻、按键和电容组成外部晶振连接 PD0、PD1。3.1 引脚分配功能STM32 引脚东侧光敏 ADCPA0 / ADC1_IN0南侧光敏 ADCPA1 / ADC1_IN1西侧光敏 ADCPA2 / ADC1_IN2北侧光敏 ADCPA3 / ADC1_IN3模式切换按键PA5水平轴角度增加PA6水平轴角度减小PA7俯仰轴角度增加PA11俯仰轴角度减小PA12OLED SCLPB8OLED SDAPB9USART3 TXPB10USART3 RXPB11水平轴步进电机PB12、PB13、PB14、PB15俯仰轴步进电机PB0、PB1、PB2、PB33.2 按键功能五个按键均配置为上拉输入按下时引脚变为低电平。按键引脚功能KEY1PA5自动/手动模式切换KEY2PA6手动模式下水平角度 2.5°KEY3PA7手动模式下水平角度 -2.5°KEY4PA11手动模式下俯仰角度 2.5°KEY5PA12手动模式下俯仰角度 -2.5°按键检测包含 20 ms 消抖并在按键释放后返回一次有效按键事件uint8_tKey_Mode_Pressed(void){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)Bit_RESET){Delay_ms(20);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)Bit_RESET){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)Bit_RESET);Delay_ms(20);return1;}}return0;}四、四路光敏电阻检测图 3 东、南、西、北四路光敏电阻四个光敏电阻分别连接 ADC1 的通道 03#defineCH_EASTADC_Channel_0#defineCH_SOUTHADC_Channel_1#defineCH_WESTADC_Channel_2#defineCH_NORTHADC_Channel_3ADC 使用单次软件触发方式数据右对齐采样时间为 239.5 个周期uint16_tMyADC_GetValue(uint8_tchannel){ADC_RegularChannelConfig(ADC1,channel,1,ADC_SampleTime_239Cycles5);ADC_SoftwareStartConvCmd(ADC1,ENABLE);while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)RESET);returnADC_GetConversionValue(ADC1);}每一路 ADC 连续读取 8 次并计算平均值#defineFILTER_COUNT8uint16_tRead_ADC_Avg(uint8_tch){uint32_tsum0;uint8_ti;for(i0;iFILTER_COUNT;i){sumMyADC_GetValue(ch);}return(uint16_t)(sum/FILTER_COUNT);}四路数据保存在LightData_t结构体中typedefstruct{uint16_teast;uint16_tsouth;uint16_twest;uint16_tnorth;int16_tlr_err;int16_tud_err;uint16_ttotal;}LightData_t;方向差值计算公式为东西差值 LR East - West 南北差值 UD South - North 总光强 Total East South West North对应程序如下voidRead_Light(LightData_t*d){d-eastRead_ADC_Avg(CH_EAST);d-southRead_ADC_Avg(CH_SOUTH);d-westRead_ADC_Avg(CH_WEST);d-northRead_ADC_Avg(CH_NORTH);d-lr_err(int16_t)d-east-(int16_t)d-west;d-ud_err(int16_t)d-south-(int16_t)d-north;d-totald-eastd-southd-westd-north;}五、双轴自动追光算法自动追光使用三个参数#defineTRACK_THRESHOLD80#defineSTEP_INTERVAL_MS60#defineNIGHT_THRESHOLD400参数数值作用光强差阈值80差值绝对值超过 80 时驱动对应轴自动控制周期60 ms自动模式每 60 ms 执行一次判断夜间总光强阈值400四路总光强低于 400 时停止追光完整追光函数如下voidTrack_Sun(constLightData_t*d){if(d-totalNIGHT_THRESHOLD){return;}if(d-lr_errTRACK_THRESHOLD){Step_Once(m1,1,1);}elseif(d-lr_err-TRACK_THRESHOLD){Step_Once(m1,1,-1);}if(d-ud_errTRACK_THRESHOLD){Step_Once(m3,3,1);}elseif(d-ud_err-TRACK_THRESHOLD){Step_Once(m3,3,-1);}}水平轴控制规则东西差值水平轴动作LR 80水平轴正向步进LR -80水平轴反向步进-80 ≤ LR ≤ 80水平轴保持俯仰轴控制规则南北差值俯仰轴动作UD 80俯仰轴正向步进UD -80俯仰轴反向步进-80 ≤ UD ≤ 80俯仰轴保持每次自动调整只执行一个步进。系统持续采样和修正直到东西差值与南北差值均进入阈值范围。六、双步进电机与 ULN2003A 驱动图 4 水平轴、俯仰轴与双 ULN2003A 驱动图 5 两片 ULN2003A 驱动接口系统使用两个四相步进电机电机 M1 控制水平轴电机 M3 控制俯仰轴。6.1 水平轴输出水平轴使用 PB12PB15staticvoidMotor1_Output(uint8_ts){switch(s0x03){case0:/* 1100 */break;case1:/* 0110 */break;case2:/* 0011 */break;case3:/* 1001 */break;}}6.2 俯仰轴输出俯仰轴使用 PB0PB3采用相同的四拍双相励磁顺序1100 → 0110 → 0011 → 1001正转时相序索引加 1反转时相序索引减 1voidStep_Once(StepperState*m,uint8_tmotor_id,intdir){if(dir0){m-seq(m-seq1)0x03;m-cur_steps;}else{m-seq(m-seq3)0x03;m-cur_steps--;}Motor_Output(motor_id,m-seq);Delay_ms(STEP_DELAY_MS);}电机参数如下#defineSTEPS_PER_REV720L#defineSTEP_DELAY_MS5每圈设为 720 步因此每步角度 360° ÷ 720 0.5°手动按键每次执行 5 步#defineMANUAL_STEP_COUNT5因此每次按键改变角度5 × 0.5° 2.5°串口目标角度范围限制为 -180°180°。七、自动模式与手动模式系统上电后默认进入自动模式uint8_tg_mode_auto1;7.1 自动模式自动模式每隔 60 ms 调用一次Track_Sun()if(g_mode_auto){if(millis()-last_trackSTEP_INTERVAL_MS){last_trackmillis();Track_Sun(light);}}7.2 手动模式KEY1 切换模式。进入手动模式后KEY2KEY5 控制双轴if(Key_HAdd_Pressed()){Step_N(m1,1,1,MANUAL_STEP_COUNT);}if(Key_HSub_Pressed()){Step_N(m1,1,-1,MANUAL_STEP_COUNT);}if(Key_VAdd_Pressed()){Step_N(m3,3,1,MANUAL_STEP_COUNT);}if(Key_VSub_Pressed()){Step_N(m3,3,-1,MANUAL_STEP_COUNT);}按键控制与串口角度控制均使用同一组电机状态变量因此 OLED 显示的角度与实际累计步数保持一致。八、OLED 数据显示OLED 使用 PB8、PB9 模拟 I2COLED 信号STM32 引脚SCLPB8SDAPB9OLED 每 200 ms 刷新一次#defineOLED_REFRESH_MS200显示内容如下显示区域内容第 1 行工作模式、四路总光强第 2 行东侧、南侧 ADC第 3 行西侧、北侧 ADC第 4 行水平轴、俯仰轴角度显示格式MODE:AUTO T:xxxx E:xxxx S:xxxx W:xxxx N:xxxx M1:xxx.xx M2:xxx.xxM1、M2 的角度由累计步数除以 2 得到floatmotor1_steps(float)m1.cur_steps/2.0f;floatmotor3_steps(float)m3.cur_steps/2.0f;九、虚拟终端与串口命令图 6 按键、虚拟终端与 OLED图 7 虚拟终端帮助信息与 OLED 启动提示上电后OLED 首先显示按键和串口操作提示虚拟终端输出完整帮助菜单。该截图适合放在串口协议介绍之前让读者先看到实际人机交互效果再阅读命令格式。系统使用 USART3串口信号STM32 引脚TXPB10RXPB11串口参数波特率9600 bit/s 数据位8 位 停止位1 位 校验位无 硬件流控无串口接收使用 RXNE 中断以回车或换行作为一条命令结束标志。9.1 命令表命令功能AUTO切换到自动追光模式MANU切换到手动模式Q查询当前系统状态QUERY查询当前系统状态HELP显示命令帮助M145水平轴移动到 45°M1-30水平轴移动到 -30°M245俯仰轴移动到 45°M2-15俯仰轴移动到 -15°执行 M1 或 M2 角度命令后系统自动切换到手动模式。9.2 状态查询发送Q或QUERY后虚拟终端返回MODEAUTO Exxxx Sxxxx Wxxxx Nxxxx TOTxxxx LRxxxx UDxxxx M1xxxx M2xxxx返回数据包含当前工作模式四路 ADC 数据四路总光强东西方向差值南北方向差值水平轴累计步数俯仰轴累计步数。十、主程序设计系统初始化顺序如下SysTick_MyInit();MyADC_Init();Motor_GPIO_Init();Key_GPIO_Init();OLED_Init();USART3_MyInit();Show_Boot_Tips();主循环完成五项任务读取四路光敏数据解析 USART3 命令处理模式和目标角度执行自动追光或手动控制定时刷新 OLED。核心结构如下while(1){Read_Light(light);if(g_cmd_ready){USART3_ProcessCommand();}/* 处理串口模式、角度和查询标志 */if(Key_Mode_Pressed()){g_mode_auto!g_mode_auto;}if(g_mode_auto){/* 每 60 ms 自动追光 */}else{/* 处理四个手动角度按键 */}if(millis()-last_oledOLED_REFRESH_MS){last_oledmillis();OLED_ShowData(light);}}SysTick 每 1 ms 进入一次中断并累加g_ms_ticks。自动追光和 OLED 刷新均使用时间差判断不使用长时间主循环延时。十一、工程目录实际参与编译的应用文件如下program ├─ Hardware │ ├─ adc.c │ ├─ adc.h │ ├─ motor.c │ ├─ motor.h │ ├─ OLED.c │ ├─ OLED.h │ ├─ OLED_Data.c │ ├─ OLED_Data.h │ ├─ usart.c │ └─ usart.h ├─ User │ ├─ main.c │ ├─ stm32f10x_conf.h │ ├─ stm32f10x_it.c │ └─ stm32f10x_it.h ├─ Library ├─ Start ├─ Objects │ └─ Project.hex └─ Project.uvprojxtracker.c、tracker.h保存在 Hardware 目录中但未加入当前 Keil 工程。当前运行的追光算法位于User/main.c。十二、Keil 编译与 Proteus 运行12.1 Keil 编译打开program/Project.uvprojx选择Target 1执行 Build生成program/Objects/Project.hex。工程编译结果0 Error(s), 0 Warning(s)工程目录中保存的Project.build_log.htm记录了 μVision V5.40、ARM Compiler V5.05 update 1并显示0 Error(s), 0 Warning(s)。链接映射文件记录的资源占用为Total RO Size 21676 Bytes21.17 kB Total RW Size 2776 Bytes 2.71 kB Total ROM Size 21760 Bytes21.25 kB图 08Keil Build Output 编译成功12.2 Proteus 运行打开项目中的 Proteus 仿真文件双击 STM32F103C8Program File 选择program/Objects/Project.hex启动仿真调节四个 LDR 的光照强度观察水平轴和俯仰轴转动使用 KEY1 切换自动、手动模式使用 KEY2KEY5 调节双轴角度打开虚拟终端发送控制命令观察 OLED 显示数据。图 09STM32 Program File 配置截图十三、功能测试13.1 东西方向追光增大东侧光敏电阻的光照使East - West 80水平轴正向步进。增大西侧光敏电阻的光照使East - West -80水平轴反向步进。东西差值进入 -8080 后水平轴停止。图 10东西方向追光对比图13.2 南北方向追光增大南侧光敏电阻的光照使South - North 80俯仰轴正向步进。增大北侧光敏电阻的光照使South - North -80俯仰轴反向步进。南北差值进入 -8080 后俯仰轴停止。图 11南北方向追光对比图13.3 手动角度控制切换到手动模式后KEY2水平轴 2.5°KEY3水平轴 -2.5°KEY4俯仰轴 2.5°KEY5俯仰轴 -2.5°。图 12手动控制角度13.4 串口角度控制虚拟终端发送M145水平轴移动到 45°。图 13串口角度命令执行十四、总结本设计完成了基于 STM32F103C8 的双轴太阳能自动追光系统。系统使用四路 ADC 获取东、南、西、北光照数据通过东西差值和南北差值控制两个步进电机实现水平轴和俯仰轴自动追光。五个按键完成模式切换和手动角度调节USART3 虚拟终端完成远程命令控制与状态查询OLED 实时显示系统运行数据。工程综合使用了 STM32 ADC、GPIO、SysTick、USART 中断、软件 I2C 和步进电机相序控制形成了光照采集、方向判断、双轴执行、人机交互和数据显示的完整控制系统。