📄 main.c~
字号:
/*电池充电电流大小设置函数
current_value------电流大小
pwm_initial_value----PWM控制占空比中ORC的初始值
电流由PID控制器控制PWM的占空比实现*/
#define current_adc_flag 0;
#define voltage_adc_flag 1;
unsigned int giADC_DataSave[10];
unsigned int adc_data;
unsigned char time_20ms_ok;
unsigned char LCD_I_value[3]={0,0,0};
unsigned char LCD_V_value[3]={0,0,0};
void current_adc(unsigned char adc_flag);
int adc_data_cmp();
typedef struct PID {
int SetPoint; // 设定目标 Desired Value
float Proportion; // 比例常数 Proportional Const
float Integral; // 积分常数 Integral Const
float Derivative; // 微分常数 Derivative Const
int LastError; // Error[1]
int PrevError; // Error[2]
int SumError; // 误差累计值
} stPID;
int get_current_value(void) //电流采样电阻采用1欧
{ int i;
get_adc(current_adc_flag); //电流单位是mA
i=adc_data_cmp();
i=i*500/1024;
return i;
}
int get_vlotage_ value(void);
{
int i;
get_adc(current_adc_flag); //电流单位是mA
i=adc_data_cmp();
i=i*500/1024;
return i;
}
void controlled_current (unsigned char current_value,unsigned char pwm_intial_value){
int fi;
int current_data;
int fout;
if (time_20ms_ok){
fi=get_current_value(); //获取真实电流值
LCD_I_value[0]=(unsigned char)(fi/100);
LCD_I_value[1]=(unsigned char)(fi%100/10);
LCD_I_value[2]=(unsigned char)(fi%10);
stPID.Proportion=1;
stPID.Integral=0.5;
stPID.Derivative=0.0;
fout=PIDCalc(&stPID,fi);
active();
}
}
//============================================================================================
//函数:float PIDCalc( PID *pp, int NextPoint )
//语法:float PIDCalc( PID *pp, int NextPoint )
//描述:PID计算
//参数:1、PID数值2、采样当前电流或电池电压值
//返回:PID输出值
//============================================================================================
float PIDCalc( PID *pp, unsigned long NextPoint ) //nextpoint为当前温度
{
int dError,
Error;
Error = pp->SetPoint*10 - NextPoint; // 偏差,这里把温度放大10倍,去掉小数点
//便于处理
pp->SumError += Error; // 积分
dError = pp->LastError - pp->PrevError; // 当前微分
pp->PrevError = pp->LastError;
pp->LastError = Error;
return (pp->Proportion * Error // 比例项
+ pp->Integral * pp->SumError // 积分项
+ pp->Derivative * dError // 微分项
);
}
//========================================================================
//函数: int adc_data_cmp()
//语法: int adc_data_cmp()
//描述: ADC采样数据的均值处理,抗干扰作用
//参数: 无
//返回: 无
//============================================================================================
int adc_data_cmp()
{
int max;
int min;
int Sum;
int i;
max = giADC_DataSave[0];
for(i=0;i<10;i++){
if(giADC_DataSave[i]>max)
max = giADC_DataSave[i]; //取出最大值
}
min = giADC_DataSave[i];
for(i=0;i<10;i++){
if(giADC_DataSave[i]<min)
min = giADC_DataSave[i]; //取出最小值
}
for(i=0;i<10;i++)
Sum += giADC_DataSave[i]; //累计值
Sum = Sum - max-min; //排除最大最小值
return(Sum/8);
}
/*电流ADC采样转换函数
void current_adc()一共采样10次,存在全局变量giADC_DataSave[10]中
用软件消除误差。ADC转换采用单次转换模式。
PA0-----电流采样接口
PA2-----电池电压采样接口
*/
void get_adc(unsigned char adc_flag) //ADC采样函数
{
if (adc_flag==current_adc_flag) c_adc_initial(); //如果标志位位0,初始化电流采样
if (adc_flag==voltage_adc_flag) v_adc_initial(); //若为1,初始化电源电压采样
for (i=0;i<10;i++){
ADCSRA |=0x40h // 置位ADSC开始一次转换
while (ADCSRA&0x40h);
adc_data=ADCL;
adc_data|=(int)ADCH<<8;
giADC_DataSave[i]=adc_data;
}
}
void c_adc_initial(void){
ADMUX=0x41h; //采用内部电源AVCC,AD0单端输入
ADCSRA=0x85h ; //单次转换 置位ADSC开始一次转换
}
void v_adc_initial(void){
ADMUX=0x40h ; //采用内部电源AVCC,AD1单端输入
ADCSRA=0x85h ; //单次转换 置位ADSC开始一次转换
}
/*2ms定时中断,采用TC2的CTC模式比较中断
中断响应函数*/
interrupt [TIM2_COMP] void timer2_comp_isr (void)
{
if(++time_counter1>=10) //20ms到标志
{
time_counter1=0;
time_20ms_ok=1;
}
if (++time_counter2>=500) //1s
{
time_counter2=0;
time_1s_ok=1;
if (++time[0] >=60)
{
time[0]=0;
if (++time[1] >=60)
{
time[1]=0;
time[2]++;
}
}
}
}
/*对PID计算的结果FOUT进行处理,判断误差大小,分别处理*/
void active(void)
{
if (fout<=0) //电流大于设定值,要调小PWM占空比,即减小OCR0
{
if(OCRO--<=1) OCR0=1;
}
else if (fout>10) //当电流差别大于10mA时,PWM增大一个等级
{
OCR0=OCR0+2;
if(OCR0>=254) OCRO=255;
}
else { //当电流差别小于10mA且需要增大时,OCRO++
if(OCRO++>=254) OCRO=255;
}
}
/*PWM初始化,采用快速PWM模式16KHZ,PB3输出方式
作为OC0输出PWM波*/
void pwm_initial(void)
{
DDRB|=0x08;
TCCR0=0x69;
OCR0=pwm_intial_value;
TIMSK=0x01;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -