标题:
正点原子stm32mini开发板做2015年国赛题目双向DCDC程序
[打印本页]
作者:
zhf1234
时间:
2019-1-7 10:25
标题:
正点原子stm32mini开发板做2015年国赛题目双向DCDC程序
电压采集曲线拟合
0.png
(30.71 KB, 下载次数: 55)
下载附件
2019-1-13 02:12 上传
PID参数调整
0.png
(6.75 KB, 下载次数: 67)
下载附件
2019-1-13 02:12 上传
单片机源程序如下:
#include "stm32f10x.h"
#include "key.h"
#include "timer.h"
#include "Filter.h"
#include "sys.h"
#include "PWM_OUTPUT.h"
#include "led.h"
#include "12864.h"
#include "adc.h"
#include "delay.h"
#include "SHOW.h"
#include "PID.h"
#define uchar unsigned char
/**********************************************************/
//全局宏定义说明
#define ERROR 0
#define TURE 1
#define Medium_High 3840
#define HIGHT_LIMIT 4320 //90%
#define LOW_LIMIT 2640 //55%
#define Init_Uset 3600 //初始目标值3600
#define initial_value 60.0
#define start 2
#define end 0
#define target_index 15
/**********************************************************/
//外部函数调用说明:
void system_init(void);
void Query_button(void); //键盘扫描函数
extern __IO uint16_t ADC_ConvertedValue[BUF_SIZE];
extern u32 Adc_Feedback(float *QUEUE, u8 chip);
extern void PID_init(PID *pp, float Kp, float Ki, float Kd);
extern PID Voltage_PID;
extern void TIM2_In_Init(u16 arr,u16 psc); // 定时器TIM2
extern void TIM4_In_Init(u16 arr,u16 psc); // 定时器TIM2
extern void LCD_refresh(void); // 显示刷新扫描函数
void Set_mode(void); // 模式选择
void Increase_current(void); // 加电流
void Current_reduction(void); // 减电流
extern void EXIT_PB4_Config(void);
/**********************************************************/
/**********************************************************/
//变量定义
u8 Integral_judge; //积分分离式的标志
u16 NUM_Fliter = 450; //滤波次数设置
int U_Set = 300; //设定目标值
float QUEUE[20] = {0,0};
float ADC_add,filter_Value,filter_Value_End; // 采样值,与滤波值
u8 Step_into_target_marks=0; // 步进目标值标志位
float fsc = initial_value,*Duty = &fsc;
u16 CCR1_Val = 0;
u16 CCR1_Val_init = 2520;
SqQueue Q; // ADC采样值序列
int aim_value ;
u8 Key_symbol1=0,Key_symbol2=0,Key_symbol3=0; // 按键标志 key1 key2 key3
extern float Pv,Kp,Ki,Kd;
u8 real_time_control_lcd=0;
u8 PID_control_sign=end; // PID开启标志位
u8 Refresh_LCD1=0,Refresh_LCD2=0,Refresh_LCD3=0; // LCD1,LCD2,LCD3 三块屏幕刷新标志
int adjust_current[21]={1659,1735,1811,1889,1966,2045,2124,2203,
2283,2364,2445,2527,2609,2692,2775,2859,2944,3029,3115,3201,3289};//恒流数组
int Point_target=0;
u16 Ini_value_tim2=10-1,Divid_tim2_val=72-1; // 定时器2装载初始值和分频值 10us//PID调整量,PID设定值
/**********************************************************/
int main()
{
U_Set = adjust_current[0] ; //设定初始目标值U_Set
PWM_set(Duty); //PWM输出
system_init(); //系统参数初始化
Get_Adc(); //获取adc值
Set_Up_QUEUE( &Q ); //建立一个空队列
// ADC_add=Update_QUEUE(20,1); //取得队列
ADC_add = Update_QUEUE_1(20,1); //取得队列
filter_Value = filter1(QUEUE,ADC_add,20); //滤波
aim_value=Adc_Feedback(QUEUE,1); //显示当前的采样值
PID__init(&Voltage_PID, &Kp, &Ki, &Kd);
while (1)
{
/* while(flag==1&&flag1==1)
{
check(); //扫描按键
if (rcvF == 1)
{
rcvF=0;
keyHandle(keyVal);
PWM_set(Duty);
flag=0;
}
}*/
// aim_value = Adc_Feedback(QUEUE,1);
// filter_Value_End = AA_Filter(&Q,QUEUE,1); //两次滤波,显示 实际值
// string_display = conversion_of_number_systems(filter_Value_End, string_display) ;
// Write_add(2,1);
// displaychar(string_display);
if( PID_control_sign == start ) //开PID
{
while( U_Set-aim_value>=2 || U_Set-aim_value <= -2) //PID算法
{
Pv=PID_Feedback(U_Set, aim_value);
CCR1_Val=CCR1_Val + Pv/0.36; //0。36
if( CCR1_Val >= Medium_High ) //80%
CCR1_Val = Medium_High;
else if( CCR1_Val <= LOW_LIMIT ) //40%
CCR1_Val = LOW_LIMIT;
TIM3->CCR2 = CCR1_Val;
aim_value = Adc_Feedback(QUEUE,1);
}
}
aim_value=Adc_Feedback(QUEUE,1); //显示当前的采样值
}
return 0;
// string_display = conversion_of_number_systems(2, string_display) ;
// displaychar(string_display);
}
/*名称:system_init()
*输入:无
*输出:无
*说明:各个模块初始化
*/
void system_init()
{
NVIC_Configuration(); // 2位抢占优先级,8位响应优先级
delay_init(); // 延时初始化
Lcd_Init_IO(); // 12864初始化
Lcd_Init();
EXIT_PB4_Config(); // 开PB4中断
Key_IO_Init(); // 按键IO初始化
ADC1_Init(); // ADC初始化
TIM2_In_Init(Ini_value_tim2,Divid_tim2_val);
TIM4_In_Init(Ini_value_tim2,Divid_tim2_val);
}
/*
* 函数介绍 : 按键扫描
* 输入参数 : 无
* 输出参数 : 无
* 返回值 : 无
*/
void Query_button()
{
if(Key_symbol1 == 1) // 按键0按下
{
PID_control_sign=end; // 关PID
Step_into_target_marks=1; // 开启步进目标标志位
Set_mode(); // 设定模式
Key_symbol1 = 0; // 清标志位1
Refresh_LCD1 =0; // 屏幕显示关
LCDclear(); // LCD清屏
}
if(Key_symbol2 == 1) // 按键1按下
{
Increase_current(); // 加电流
Key_symbol2 = 0; // 清标志位2
}
if(Key_symbol3 == 1) // 按键2按下
{
Current_reduction(); // 减电流
Key_symbol3 = 0; // 清标志位2
}
}
/*
* 函数介绍 : Increase_current() 电流加0.05A 以及步进调整电流2A
* 输入参数 : 无
* 输出参数 : 无
* 返回值 : 无
*/
void Increase_current()
{
if( Step_into_target_marks==1 ) //开启步进目标值模式
{
if(U_Set>HIGHT_LIMIT)
{
Step_into_target_marks=0; //关闭步进目标值模式
U_Set = Init_Uset; //目标值恢复初始值
TIM3->CCR2 = U_Set; // 更新PWM值
PID_control_sign=start; //开PID
Point_target=0;
}
else
{
U_Set = U_Set+target_index; //步进目标值
TIM3->CCR2 = U_Set; // 更新PWM值
}
}
else //步进电流模式
{
if(Point_target == 21) //达到两A停止
{
Point_target = 20;
}
else
{
U_Set = adjust_current[Point_target] ; //PID目标值调整
Point_target++; //自加0.05A
}
}
}
/*
* 函数介绍 : Set_mode() 选择模式充电,放电自动
* 输入参数 : 无
* 输出参数 : 无
* 返回值 : 无
*/
void Set_mode()
{
}
/*
* 函数介绍 : LCD是否需要刷新判断 并响应程序
* 输入参数 : 无
* 输出参数 : 无
* 返回值 : 无
*/
void LCD_refresh()
{
}
/*
* 函数介绍 : Current_reduction() 电流减0.05A
* 输入参数 : 无
* 输出参数 : 无
* 返回值 : 无
*/
void Current_reduction()
{
if(Step_into_target_marks==1) //开启步进目标值模式
{
if(U_Set <LOW_LIMIT )
{
Step_into_target_marks=0; // 清步进目标值模式
U_Set = Init_Uset; // 目标值恢复初始值
TIM3->CCR2 = U_Set; // 更新PWM值
PID_control_sign =start; //开PID
Point_target=0; // 准备步进调整电流
}
else
{
U_Set=U_Set-target_index;
TIM3->CCR2 = U_Set; // 更新PWM值
}
}
else //开启步进电流模式
{
if(Point_target == -1)
{
Point_target = 0;
}
else
{
U_Set = adjust_current[Point_target] ; // PID目标值调整
Point_target--; // 减0.05A
}
}
}
复制代码
所有资料51hei提供下载:
双向DC-DC(old version).7z
(208.92 KB, 下载次数: 95)
2019-1-13 02:10 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
shui0419
时间:
2022-8-28 02:24
感谢楼主分享,要是有个原理图就好了
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1