使用stm32f103rct6标准库写用MPPT算法控制PWM波ADC多通道采集使电压输出恒为30V的代码
时间: 2023-07-16 11:11:36 浏览: 160
这是一个比较复杂的控制系统,需要涉及到多个模块的代码编写。以下是大致的流程和代码框架:
1. 初始化ADC和PWM模块,设置对应的GPIO引脚。
```c
#include "stm32f10x.h"
void ADC_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Configure PA1 as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable ADC1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* Configure ADC1 */
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);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
void PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOB clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* Configure PB0 as PWM output */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Enable TIM3 clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Configure TIM3 */
TIM_TimeBaseStructure.TIM_Period = 8399;
TIM_TimeBaseStructure.TIM_Prescaler = 999;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Configure TIM3 Channel 3 */
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_OC3Init(TIM3, &TIM_OCInitStructure);
/* Enable TIM3 outputs */
TIM_CtrlPWMOutputs(TIM3, ENABLE);
/* Enable TIM3 */
TIM_Cmd(TIM3, ENABLE);
}
```
2. 实现MPPT算法,根据当前电压和电流计算出最佳功率点的电压值。
```c
#define VOLTAGE_MAX 36
#define VOLTAGE_MIN 0
#define POWER_MAX (VOLTAGE_MAX * VOLTAGE_MAX / 4)
float MPPT(float voltage, float current)
{
static float voltage_old = 0;
static float power_old = 0;
static float delta_v = 0;
static float delta_p = 0;
/* Calculate change in voltage and power */
delta_v = voltage - voltage_old;
delta_p = voltage * current - power_old;
/* Update old values */
voltage_old = voltage;
power_old = voltage * current;
/* Calculate duty cycle */
float duty_cycle = TIM3->CCR3 / (float)TIM3->ARR;
if (delta_p > 0 && voltage > VOLTAGE_MIN && voltage < VOLTAGE_MAX) {
duty_cycle += 0.01;
} else if (delta_p < 0) {
duty_cycle -= 0.01;
}
duty_cycle = duty_cycle > 1 ? 1 : duty_cycle < 0 ? 0 : duty_cycle;
/* Calculate target voltage */
float target_voltage = voltage + delta_v * delta_p / POWER_MAX;
return target_voltage;
}
```
3. 在主循环中读取ADC采集的电压和电流值,并根据MPPT算法计算出目标电压值,然后调整PWM的占空比以达到目标电压值。
```c
int main(void)
{
ADC_Init();
PWM_Init();
while (1) {
/* Read voltage */
uint16_t adc_value = ADC_GetConversionValue(ADC1);
float voltage = adc_value * 3.3 / 4095 * 11;
/* Read current */
float current = ...; // read current from another ADC channel
/* Calculate target voltage using MPPT */
float target_voltage = MPPT(voltage, current);
/* Adjust PWM duty cycle to reach target voltage */
uint16_t duty_cycle = target_voltage / 36 * 8399;
TIM3->CCR3 = duty_cycle;
/* Wait for next ADC conversion */
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
}
}
```
需要注意的是,以上代码只是一个大致的框架,实际上还需要考虑很多细节问题,例如ADC采集周期、PWM调节精度、电路保护等等。实际上的代码编写需要根据具体的电路和要求进行调整。
阅读全文