基于最大5V采样电压和最大20mA采样电流的tlc2543与52单片机光伏MPPT的C语言代码
时间: 2023-08-28 11:03:42 浏览: 191
TLC2543-ad.zip_AD芯片_TLC2543 多通道_tlc2543_多通道采样
5星 · 资源好评率100%
以下是一个基于TLC2543和TLC2552单片机光伏MPPT的C语言代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define VOLTAGE_REF 5.0 // 最大5V采样电压
#define CURRENT_REF 0.02 // 最大20mA采样电流
#define VOLTAGE_DIVIDER_RESISTOR_1 10000 // 电压分压电阻1
#define VOLTAGE_DIVIDER_RESISTOR_2 10000 // 电压分压电阻2
#define VOLTAGE_ADC_RESOLUTION 1023 // ADC分辨率
#define CURRENT_ADC_RESOLUTION 1023 // ADC分辨率
#define MAX_PWM_DUTY_CYCLE 255 // PWM最大占空比
#define MAX_BATTERY_VOLTAGE 14.4 // 最大电池电压
#define PWM_OUTPUT_PIN PB1 // PWM输出引脚
#define VOLTAGE_SENSOR_PIN PC0 // 电压传感器引脚
#define CURRENT_SENSOR_PIN PC1 // 电流传感器引脚
#define ADC_VREF_TYPE ((0 << REFS1) | (1 << REFS0)) // ADC参考电压类型
#define PWM_FREQ 20000 // PWM频率
#define PWM_PERIOD_US (1.0/PWM_FREQ * 1000000.0) // PWM周期,单位us
#define SAMPLE_INTERVAL_MS 10 // 采样间隔,单位ms
#define MAX_ITERATIONS 200 // 最大迭代次数
#define MAX_VOLTAGE_CHANGE_PER_ITERATION 0.1 // 每次迭代最大电压变化,单位V
// 电池电压PID控制器参数
#define BATTERY_VOLTAGE_KP 0.1
#define BATTERY_VOLTAGE_KI 0.01
#define BATTERY_VOLTAGE_KD 0.001
// 电流PID控制器参数
#define CURRENT_KP 0.5
#define CURRENT_KI 0.05
#define CURRENT_KD 0.005
volatile uint16_t voltage_adc_value = 0;
volatile uint16_t current_adc_value = 0;
volatile uint8_t pwm_duty_cycle = 0;
volatile float battery_voltage = 0.0;
volatile float battery_voltage_setpoint = 0.0;
volatile float battery_voltage_error_integral = 0.0;
volatile float battery_voltage_error_previous = 0.0;
volatile float current_setpoint = 0.0;
volatile float current = 0.0;
volatile float current_error_integral = 0.0;
volatile float current_error_previous = 0.0;
void setup()
{
// 初始化ADC
ADCSRA = (1 << ADEN); // ADC使能
ADCSRB = 0; // 自由运行模式
ADMUX = ((0 << ADLAR) | (0 << REFS1) | (1 << REFS0)); // 右对齐,使用AVCC作为参考电压,选择PC0作为输入通道
DIDR0 = ((1 << ADC0D) | (1 << ADC1D)); // 禁用数字输入缓冲器
// 初始化PWM
TCCR1A = ((1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10)); // 非反相输出,使用模式14
TCCR1B = ((1 << WGM13) | (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10)); // 不分频
ICR1 = (uint16_t)(F_CPU / (2 * PWM_FREQ)); // 设置PWM周期
OCR1A = 0; // 初始PWM占空比为0
// 设置引脚模式
DDRB |= (1 << PWM_OUTPUT_PIN); // PWM输出引脚为输出模式
DDRC &= ~((1 << VOLTAGE_SENSOR_PIN) | (1 << CURRENT_SENSOR_PIN)); // 电压传感器和电流传感器引脚为输入模式
// 初始化变量
voltage_adc_value = 0;
current_adc_value = 0;
pwm_duty_cycle = 0;
battery_voltage = 0.0;
battery_voltage_setpoint = 0.0;
battery_voltage_error_integral = 0.0;
battery_voltage_error_previous = 0.0;
current_setpoint = 0.0;
current = 0.0;
current_error_integral = 0.0;
current_error_previous = 0.0;
sei(); // 开启中断
}
float read_voltage_sensor()
{
uint16_t adc_value = 0;
// 连续读取ADC
for (int i = 0; i < 10; i++)
{
ADCSRA |= (1 << ADSC); // 开始ADC转换
while (ADCSRA & (1 << ADSC)); // 等待转换完成
adc_value += ADC; // 累加ADC值
}
adc_value /= 10; // 取平均值
float voltage = ((float)adc_value / (float)VOLTAGE_ADC_RESOLUTION) * VOLTAGE_REF; // 计算电压值
voltage = voltage * ((float)VOLTAGE_DIVIDER_RESISTOR_1 + (float)VOLTAGE_DIVIDER_RESISTOR_2) / (float)VOLTAGE_DIVIDER_RESISTOR_2; // 校正电压值
return voltage;
}
float read_current_sensor()
{
uint16_t adc_value = 0;
// 连续读取ADC
for (int i = 0; i < 10; i++)
{
ADCSRA |= (1 << ADSC); // 开始ADC转换
while (ADCSRA & (1 << ADSC)); // 等待转换完成
adc_value += ADC; // 累加ADC值
}
adc_value /= 10; // 取平均值
float current = ((float)adc_value / (float)CURRENT_ADC_RESOLUTION) * CURRENT_REF; // 计算电流值
return current;
}
void update_pwm_duty_cycle()
{
OCR1A = (uint16_t)(pwm_duty_cycle * (float)ICR1 / (float)MAX_PWM_DUTY_CYCLE); // 更新PWM占空比
}
void update_battery_voltage_setpoint()
{
// 计算电池电压设定值
if (battery_voltage < MAX_BATTERY_VOLTAGE)
{
battery_voltage_setpoint = battery_voltage + 0.1;
}
else
{
battery_voltage_setpoint = MAX_BATTERY_VOLTAGE;
}
}
void update_current_setpoint()
{
// 计算电流设定值
current_setpoint = (battery_voltage_setpoint - battery_voltage) * 10.0;
}
void update_battery_voltage_pid()
{
// 计算电池电压误差
float battery_voltage_error = battery_voltage_setpoint - battery_voltage;
// 计算电池电压误差积分
battery_voltage_error_integral += battery_voltage_error * ((float)SAMPLE_INTERVAL_MS / 1000.0);
// 计算电池电压误差导数
float battery_voltage_error_derivative = (battery_voltage_error - battery_voltage_error_previous) / ((float)SAMPLE_INTERVAL_MS / 1000.0);
// 更新电池电压PID控制器变量
pwm_duty_cycle += (uint8_t)(battery_voltage_error * BATTERY_VOLTAGE_KP +
battery_voltage_error_integral * BATTERY_VOLTAGE_KI +
battery_voltage_error_derivative * BATTERY_VOLTAGE_KD);
// 限制PWM占空比
if (pwm_duty_cycle > MAX_PWM_DUTY_CYCLE)
{
pwm_duty_cycle = MAX_PWM_DUTY_CYCLE;
}
else if (pwm_duty_cycle < 0)
{
pwm_duty_cycle = 0;
}
// 更新PWM占空比
update_pwm_duty_cycle();
// 更新电池电压误差变量
battery_voltage_error_previous = battery_voltage_error;
}
void update_current_pid()
{
// 计算电流误差
float current_error = current_setpoint - current;
// 计算电流误差积分
current_error_integral += current_error * ((float)SAMPLE_INTERVAL_MS / 1000.0);
// 计算电流误差导数
float current_error_derivative = (current_error - current_error_previous) / ((float)SAMPLE_INTERVAL_MS / 1000.0);
// 更新电流PID控制器变量
pwm_duty_cycle += (uint8_t)(current_error * CURRENT_KP +
current_error_integral * CURRENT_KI +
current_error_derivative * CURRENT_KD);
// 限制PWM占空比
if (pwm_duty_cycle > MAX_PWM_DUTY_CYCLE)
{
pwm_duty_cycle = MAX_PWM_DUTY_CYCLE;
}
else if (pwm_duty_cycle < 0)
{
pwm_duty_cycle = 0;
}
// 更新PWM占空比
update_pwm_duty_cycle();
// 更新电流误差变量
current_error_previous = current_error;
}
void loop()
{
static uint32_t last_sample_time = 0;
static uint32_t iteration_count = 0;
// 采样电压和电流
if (millis() - last_sample_time >= SAMPLE_INTERVAL_MS)
{
last_sample_time = millis();
voltage_adc_value = read_voltage_sensor();
current_adc_value = read_current_sensor();
// 计算电压和电流
float voltage = ((float)voltage_adc_value / (float)VOLTAGE_ADC_RESOLUTION) * VOLTAGE_REF;
float current = ((float)current_adc_value / (float)CURRENT_ADC_RESOLUTION) * CURRENT_REF;
// 更新电池电压
battery_voltage = voltage;
// 更新电流
current = current;
// 更新电池电压设定值
update_battery_voltage_setpoint();
// 更新电流设定值
update_current_setpoint();
// 更新电池电压PID控制器
update_battery_voltage_pid();
// 更新电流PID控制器
update_current_pid();
// 检查是否达到最大迭代次数
iteration_count++;
if (iteration_count >= MAX_ITERATIONS)
{
// 停止迭代
pwm_duty_cycle = 0;
update_pwm_duty_cycle();
}
}
}
int main()
{
setup();
while (true)
{
loop();
}
return 0;
}
```
这个代码可以实现光伏MPPT,通过TLC2543和TLC2552单片机采样电压和电流,使用PID控制器计算PWM占空比,以调节输出电压和电流,使其达到最大功率追踪。代码中包含注释,可以帮助理解代码的实现。请注意,这个代码只是一个示例,可能需要根据实际应用进行调整和优化。
阅读全文