使用stm32f103rct6标准库写用MPPT算法控制PWM使电压输出恒为30V的代码
时间: 2023-06-27 15:04:27 浏览: 257
下面是一个基本的使用 MPPT 算法控制 PWM 输出电压为 30V 的代码:
```c
#include "stm32f10x.h"
#define Vref 3.3f // ADC 参考电压
#define Vpvmax 50.0f // PV 面板最大电压
#define Voutmax 30.0f // 输出电压最大值
#define Voutmin 0.0f // 输出电压最小值
#define Ioutmax 5.0f // 输出电流最大值
float Vpv = 0.0f; // PV 面板电压
float Ipv = 0.0f; // PV 面板电流
float Vout = 0.0f; // 输出电压
float Iout = 0.0f; // 输出电流
float Duty = 0.0f; // PWM 占空比
void ADC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE);
}
float ADC_GetValue(void)
{
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
return ADC_GetConversionValue(ADC1) * Vref / 4095.0f;
}
void PWM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = 1000 - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_Cmd(TIM1, ENABLE);
}
void MPPT(void)
{
float Pmax = 0.0f;
for(int i = 0; i <= 1000; i++)
{
Duty = i / 1000.0f;
Vpv = ADC_GetValue();
Ipv = (Vpv / Vpvmax) * Ioutmax;
Iout = Ipv;
Vout = Duty * Voutmax;
if(Vout <= Vpv)
{
if((Duty + 0.001f) > 1.0f)
{
break;
}
else
{
continue;
}
}
if(Iout > Ioutmax)
{
if((Duty - 0.001f) < 0.0f)
{
break;
}
else
{
continue;
}
}
if((Vpv * Ipv) > Pmax)
{
Pmax = Vpv * Ipv;
Duty += 0.001f;
}
else
{
break;
}
}
TIM_SetCompare1(TIM1, Duty * 1000.0f);
}
int main(void)
{
ADC_Init();
PWM_Init();
while(1)
{
MPPT();
}
}
```
说明:
1. 首先,需要定义一些常量,包括 ADC 参考电压、PV 面板最大电压、输出电压最大值、输出电压最小值和输出电流最大值。
2. 初始化 ADC 和 PWM。ADC 配置为单次采样模式,连续转换模式,GPIO 引脚 PA0,采样时间 55.5 个周期;PWM 使用 TIM1_CH1 输出,GPIO 引脚 PA8,PWM 周期为 1ms,占空比为 0。
3. 在 MPPT 函数中,使用迭代法,不断调整占空比 Duty,使得输出电压 Vout 接近目标电压 30V,并且 PV 面板工作在最大功率点。具体实现方法:
- 先设定一个最大功率值 Pmax,初值为 0。
- 从占空比 Duty = 0 开始,每次增加 0.001,直到占空比 Duty = 1。
- 计算当前的 PV 面板电压 Vpv 和电流 Ipv。
- 根据占空比 Duty 计算输出电压 Vout 和输出电流 Iout。
- 如果输出电压小于等于 PV 面板电压,则增加占空比。
- 如果输出电流大于输出电流最大值,则减小占空比。
- 如果当前功率大于最大功率 Pmax,则增加占空比 0.001,更新 Pmax。
- 如果当前功率小于最大功率 Pmax,则退出循环。
4. 在主函数中,循环调用 MPPT 函数,实现 MPPT 算法控制 PWM 输出电压为 30V。
阅读全文