光伏双轴跟踪结构(STM32学习之驱动舵机)

目录

1.1  本系统双轴跟踪系统机械结构设计

1.2  舵机的选型

1.3  舵机的控制原理

 1.4  原理介绍&代码浅析

 1.4.1  STM32定时器的输出比较简介

1.4.2  PWM简介

 1.4.3  高级定时器的输出比较通道

1.4.4  代码浅析

        PSC、ARR、CCR参数的确定

servo.c

servo.h


1.1  本系统双轴跟踪系统机械结构设计

       为了能够在俯仰和水平两个方位上跟踪太阳,获得更多的能量,本系统采用高度角-方位角式双轴跟踪结构,即在单轴式跟踪的结构上,再增加一个传动轴,实现同时满足二维空间上对太阳的全方位跟踪。这样就可以使太阳能电池板全天候保持与光线垂直,从而获最大辐射量,以提高发电效率。高度角-方位角式双轴跟踪结构如图1所示。

图1    高度角-方位角式双轴跟踪结构

1.2  舵机的选型

        本系统选用TS90A型号的模拟舵机,与一般的模拟舵机SG90相比,其采用了金属的马达齿、金属的电位器齿轮轴、以及有档点可限位的齿轮,使舵机转动更加顺滑,物理稳定性更强。如图2所示为TS90A舵机。

图2    TS90A舵机

1.3  舵机的控制原理

        舵机是一种根据输入PWM信号占空比来控制输出角度的装置。其控制原理如下:控制电路板接受来自信号线的控制信号,控制电机转动,电机带动一系列齿轮组,减速后传动至输出舵盘。舵机的输出轴和位置反馈电位计是相连的,舵盘转动的同时,带动位置反馈电位计,电位计将输出一个电压信号到控制电路板,进行反馈,然后控制电路板根据所在位置决定电机的转动方向和速度,从而达到目标停止。

        输入PWM信号要求:周期为20ms(即50Hz),高电平宽度为0.5ms~2.5ms。

        舵机工作控制信号时序图:

        波形按照这个规定,准确地输出就能控制舵机了。 

舵机接线:
棕色——GND
红色——5V
橙色——PWM

 1.4  原理介绍&代码浅析

 1.4.1  STM32定时器的输出比较简介

        OC(Output Compare)输出比较

        输出比较可以通过比较CNT(计数器)与CCR(捕获/比较器)的寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。

        每个高级定时器和通用定时器都拥有4个输出比较通道。

        高级定时器的前3个通道额外拥有死去生成和互补输出的功能。

        输出比较模式及输出比较相关的内容请移步到
江协科技的STM32教程中 P15 [6-3]TIM输出比较https://www.bilibili.com/video/BV1th411z7sn?p=15&vd_source=b4d125df2ebf1ab26fbed06ba725ac39

1.4.2  PWM简介

        PWM(Pulse Width Modulation)脉冲宽度调制

        在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域。

        PWM参数:

        频率=1/Ts        占空比=TON/Ts        分辨率=占空比变化步距

PWM频率: Freq = CK_PSC/(PSC+1)/(ARR+1)        即 计数器的更新频率公式

PWM占空比: Duty = CCR/(ARR+1)        CCR是自己设定的值

PWM分辨率: Reso = 1/(ARR+1)

 1.4.3  高级定时器的输出比较通道

       ( 本部分为补充学习内容,本项目的制作并未使用到,可忽略此部分内容。)

        下图为高级定时器的输出比较部分的原理框图: 

图3    高级定时器的输出比较部分的原理框图

         该图比通用定时器主要多出蓝色框框的地方。高级定时器的输出比较通道常外接如图4所示的推挽电路。

图4    推挽电路

        推挽电路:通常是VCC与GND之间连接两个功率开关器件,常为MOS管,两个管之间为输出电路。

        推挽电路的工作流程:在推挽电路中,若上管导通,下管断开,输出为高电平;若下管导通,上管断开,输出为低电平;若上下管都导通,那就是电源短路,这样是不允许的;若上下管都断开,那输出就是高阻态。

        两个推挽电路可构成H桥电路,可以控制直流电机正反转; 三个推挽电路可用于驱动三相无刷电机。

         为了避免换相导通时短暂出现上下管同时导通的问题,就有了 高级定时器中的死区生成电路(见图3),其会在上管关闭的时候,延迟一小段时间,再导通下管。

1.4.4  代码浅析

        PSC、ARR、CCR参数的确定


        因        PWM频率: Freq = CK_PSC/(PSC+1)/(ARR+1)       

        即         Freq = 72M/(PSC+1)/(ARR+1) = 1/20ms = 50Hz

                    为了方便计算设置 (PSC+1) = 72,则 (ARR+1) = 20k


        因        PWM占空比: Duty = CCR/(ARR+1)        

                                0.5ms = Duty * 20ms,则 0.5ms时Duty = 0.025

                                即        Duty = CCR/(ARR+1) = 0.025,已知(ARR+1) = 20k

                                则        0.5ms时 CCR = 500

                同理可得 2.5ms时,CCR = 2500


        参数确定后,代入如下代码的相应位置: 

servo.c

#include "servo.h"

void Servo_Init()
{
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//使能定时器2时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  			//使能GPIOA时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;					
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_0;			//PA1、0 作为复用推挽输出引脚,这样引脚的控制权会交给片上外设,定时器才可通过该引脚输出PWM波形
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	TIM_InternalClockConfig(TIM2);									//初始化时基单元
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_Period= 20000 - 1;					//周期 ARR
	TIM_TimeBaseStructure.TIM_Prescaler= 72 - 1;					//预分频器 PSC
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);					//对时基单元的参数进行初始化
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
//	TIM_OCStructInit(&TIM_OCInitStructure);							//若不想把所有成员都列一遍去赋值,则可以调用此函数先赋一个初始值,然后再更改想改的值。
																	//这样做的好处是可避免:比如高级定时器想当通用定时器使用,则高级定时器才用到的成员变量就不需要赋值,万一哪一次将其恢复高级定时器用,则会出现有些成员变量少赋值,导致程序执行出现问题
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;					//输出比较模式:PWM模式1
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;		//输出使能
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;			//输出比较极性:高极性,即有效电平是高电平
	TIM_OCInitStructure.TIM_Pulse=0;								//用于设置CCR寄存器的初始值
	TIM_OC1Init(TIM2,&TIM_OCInitStructure);							//输出比较通道1初始化
	TIM_OC2Init(TIM2,&TIM_OCInitStructure);							//输出比较通道2初始化,因为是同一个定时器的不同通道,会共用一个计数器,因此它们的频率需要相同,相位也是同步的,但占空比由各自的CCR决定
	
	TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable);
	TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable);				//TIMx_CCRx寄存器能够在任何时候通过软件进行更新以控制波形,这个通过软件写入控制波形的值是立即生效还是在定时器发生下一次更新事件时被更新的,
																	//是由TIM_OCxPreloadConfig(TIMx, TIM_OCPreload_Enable);函数决定的。
																	//Enable:下一次更新事件时被更新;
																	//Disable:立即生效
	
	TIM_Cmd(TIM2,ENABLE);											//启动定时器
}

//0				500
//180			2500

void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);									//改变CCR的值,500-2500对应0°到180°
}

void PWM_SetCompare2(uint16_t Compare)
{
	TIM_SetCompare2(TIM2, Compare);
}

void Servo1_SetAngle(float Angle)
{
	PWM_SetCompare1(Angle / 180 * 2000 + 500); 
}

void Servo2_SetAngle(float Angle)
{
	PWM_SetCompare2(Angle / 180 * 2000 + 500); 
}

servo.h

#ifndef __SERVO_H
#define __SERVO_H

#include "sys.h"


void Servo_Init(void);
void Servo1_SetAngle(float Angle);
void Servo2_SetAngle(float Angle);

#endif

每一句代码后面都有注释解释清楚这一步是干嘛的。

<think>好的,我现在需要帮助用户设计一个基于STM32双轴太阳能追踪系统的实现方案和控制算法。首先,我需要回顾用户提供的引用内容,看看有哪些现有的资源可以利用。 根据引用[1],用户提到了光电传感单元、舵机驱动、雨滴传感器和光伏跟踪算法。这些部分可能涉及到传感器的数据采集和舵机控制。引用[2]和[3]则详细描述了太阳跟踪系统的设计,包括光敏传感器、电机控制以及系统整体架构。用户需要的是具体的实现方案和控制算法,所以我需要将这些信息整合起来,给出一个结构清晰的步骤。 首先,系统架构部分应该包括硬件组成和软件流程。硬件方面,需要选择STM32微控制器作为核心,然后考虑光敏传感器模块(比如四象限光电二极管)、双轴舵机或步进电机、电源管理模块以及可能的环境传感器如雨滴传感器。软件部分需要数据采集、控制算法、电机驱动和用户界面等模块。 接下来是硬件设计部分。传感器布局方面,四象限光电二极管需要合理布置在太阳能板周围,确保能够准确检测光强差异。电机驱动部分,根据引用[1]中的舵机驱动,可能需要使用PWM信号控制舵机的角度。电源管理方面,需要稳定的电压转换模块,同时考虑低功耗设计。 然后是控制算法的设计。这里可能需要分步讨论。首先,数据采集部分,如何通过ADC和DMA(如引用[1]提到的ADC+DMA)高效读取传感器数据。然后,方向判断算法,比如比较四个象限的光强差异,确定太阳的位置偏差。接着是双轴控制策略,可能需要使用PID算法来调整舵机的转动角度,确保平稳跟踪。此外,引用[3]提到光线传感器和电机驱动,可能需要结合这些信息优化算法。 还需要考虑其他功能,比如雨滴传感器触发保护机制,自动复位功能,以及手动模式切换,这些都能提升系统的实用性。 在软件实现部分,需要初始化各个外设,配置ADC和DMA,设置PWM输出,以及实现主循环中的控制逻辑。引用[1]中的代码示例可能对初始化ADC和舵机控制有帮助,但需要具体到双轴系统的实现。 最后,测试与优化部分需要考虑实际环境中的测试,比如不同天气条件下的表现,以及如何通过参数调整提高响应速度和稳定性。可能还需要考虑能耗优化,确保系统长时间运行。 现在需要确保回答符合用户的要求:结构清晰,分步骤,引用相关文献。同时,用户可能希望了解具体的算法实现细节,比如PID参数如何调整,或者如何处理传感器数据的具体方法。需要将这些内容以中文清晰表达,并正确使用LaTeX格式,比如数学公式用$$包围,变量用$符号。 可能还需要生成相关问题,比如关于PID参数整定方法,或者如何集成多个传感器,这些都需要在最后部分列出。</think>### STM32双轴太阳能追踪系统实现方案 #### 一、系统架构设计 $$系统架构 = 光电传感单元 + 电机驱动单元 + 控制算法核心$$ 硬件组成: 1. **STM32微控制器**(如STM32F4系列)作为主控芯片[^2] 2. **四象限光电二极管**阵列(光强方向检测) 3. **双轴舵机系统**(水平/垂直方向各配200°旋转范围舵机)[^1] 4. **电源管理模块**(支持太阳能板供电与锂电池切换) 5. **环境监测模块**(雨滴传感器、风速传感器) 软件流程: ``` 初始化 → 数据采集 → 光强分析 → 控制算法 → 电机驱动 → 状态反馈 ``` #### 二、硬件设计要点 1. **传感器布局**: - 四象限光电二极管以$10cm \times 10cm$网格布置在太阳能板四角 - 采用$ADC1$的通道0-3进行四路光强信号采集,启用DMA传输 2. **电机驱动**: ```c // 舵机角度控制示例(水平轴) void Set_Horizon_Angle(float angle){ TIM3->CCR1 = 1500 + angle*11.11; // 对应0.5ms-2.5ms脉冲 } ``` 3. **电源管理**: - 使用TPS5430降压模块实现$12V \rightarrow 5V \rightarrow 3.3V$转换 - 配备TP4056锂电池充电管理电路 #### 三、控制算法实现 1. **方向判断算法**: $$ \Delta X = \frac{(I_A + I_D) - (I_B + I_C)}{I_{total}},\quad \Delta Y = \frac{(I_A + I_B) - (I_C + I_D)}{I_{total}} $$ 其中$I_{total} = \sum_{i=A}^D I_i$,当$|\Delta X|>0.1$或$|\Delta Y|>0.1$时触发调整[^3] 2. **双轴PID控制**: ```c typedef struct { float Kp, Ki, Kd; float integral, prev_error; } PID_Controller; float PID_Update(PID_Controller* pid, float error) { pid->integral += error * dt; float derivative = (error - pid->prev_error) / dt; pid->prev_error = error; return pid->Kp*error + pid->Ki*pid->integral + pid->Kd*derivative; } ``` 3. **特殊模式处理**: -
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值