#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "adc.h"
#include "dac.h"
#include "PID.h"
#include "timer.h"
u16 dacval=0;
float temputure,vc,tc,temp3,temp4,temp5,temp6,text,text2;
PidTypeDef t1;
int clock;
float targetad;
float targettemp=45;
float last_temperature = 0;
float temperature_change_rate = 0;
unsigned char rapid_change_flag = 0;
int len,t;
float Kp_temp = 30.0f;
float Ki_temp = 1.0f;
float Kd_temp = 100.0f;
unsigned char USART_Temp[4];
#define CHART_MAX_POINTS 100
#define CHART_X 40
#define CHART_Y 250
#define CHART_WIDTH 190
#define CHART_HEIGHT 60
#define TEMP_MIN 0.0
#define TEMP_MAX 100.0
float actual_temp_history[CHART_MAX_POINTS];
float target_temp_history[CHART_MAX_POINTS];
u16 data_count = 0;
u16 chart_update_counter = 0;
float adtotemp(u16 a){
vc = (float)(a-2048)*(4.79/2048)+0.38;
tc = 31.315*(vc-0.38);
float cornum = 0.0f;
tc = tc + cornum;
if(tc < 0) { tc = 0; }
return tc;
}
u16 temptoad(float temp) {
return (u16)(2048 + temp * 13.66f);
}
void printshuju(void){
//printf("%.2fs%.2f\n",targettemp,temputure);
printf("%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f\n",targettemp,temputure,Kp_temp,Ki_temp,Kd_temp,t1.IPart,t1.PIDOut);
}
void USPID_GetValue(void)
{
if(USART_Temp[0]=='p')
{
Kp_temp=(USART_Temp[1]-'0')*100.0+(USART_Temp[2]-'0')*10.0+(USART_Temp[3]-'0')*1.0; //p123=P123
}
if(USART_Temp[0]=='i')
{
Ki_temp=(USART_Temp[1]-'0')*1.0+(USART_Temp[2]-'0')*0.1+(USART_Temp[3]-'0')*0.01; //i123=i1.23
}
if(USART_Temp[0]=='d')
{
Kd_temp=(USART_Temp[1]-'0')*10.0+(USART_Temp[2]-'0')*1.0+(USART_Temp[3]-'0')*0.1; //d123=d12.3
}
if(USART_Temp[0]=='t')
{
targettemp=(USART_Temp[1]-'0')*100.0+(USART_Temp[2]-'0')*10.0+(USART_Temp[3]-'0')*1.0; //p123=P123
}
}
void Draw_Chart_Axis(void)
{
u16 i;
LCD_Fill(CHART_X - 35, CHART_Y - 20, CHART_X + CHART_WIDTH + 5, CHART_Y + CHART_HEIGHT + 15, WHITE);
POINT_COLOR = BLACK;
LCD_DrawLine(CHART_X, CHART_Y, CHART_X, CHART_Y + CHART_HEIGHT);
LCD_DrawLine(CHART_X, CHART_Y + CHART_HEIGHT, CHART_X + CHART_WIDTH, CHART_Y + CHART_HEIGHT);
for(i = 0; i <= 4; i++)
{
u16 y_pos = CHART_Y + i * (CHART_HEIGHT / 4);
LCD_DrawLine(CHART_X - 3, y_pos, CHART_X, y_pos);
}
for(i = 0; i <= 5; i++)
{
u16 x_pos = CHART_X + i * (CHART_WIDTH / 5);
LCD_DrawLine(x_pos, CHART_Y + CHART_HEIGHT, x_pos, CHART_Y + CHART_HEIGHT + 3);
}
LCD_ShowString(CHART_X + 40, CHART_Y - 15, 200, 16, 12, (u8*)"Temperature Chart");
LCD_ShowString(CHART_X - 35, CHART_Y - 5, 30, 16, 12, (u8*)"100");
LCD_ShowString(CHART_X - 28, CHART_Y + CHART_HEIGHT / 4 - 5, 30, 16, 12, (u8*)"75");
LCD_ShowString(CHART_X - 28, CHART_Y + CHART_HEIGHT / 2 - 5, 30, 16, 12, (u8*)"50");
LCD_ShowString(CHART_X - 28, CHART_Y + CHART_HEIGHT * 3 / 4 - 5, 30, 16, 12, (u8*)"25");
LCD_ShowString(CHART_X - 20, CHART_Y + CHART_HEIGHT - 5, 30, 16, 12, (u8*)"0");
LCD_ShowString(CHART_X - 35, CHART_Y + CHART_HEIGHT / 2 - 20, 30, 16, 12, (u8*)"T");
LCD_ShowString(CHART_X - 35, CHART_Y + CHART_HEIGHT / 2 - 8, 30, 16, 12, (u8*)"(C)");
LCD_ShowString(CHART_X + CHART_WIDTH - 20, CHART_Y + CHART_HEIGHT + 5, 50, 16, 12, (u8*)"Time");
POINT_COLOR = RED;
LCD_DrawLine(CHART_X + 5, CHART_Y - 10, CHART_X + 15, CHART_Y - 10);
POINT_COLOR = BLACK;
LCD_ShowString(CHART_X + 18, CHART_Y - 13, 50, 16, 12, (u8*)"Actual");
POINT_COLOR = BLUE;
LCD_DrawLine(CHART_X + 60, CHART_Y - 10, CHART_X + 70, CHART_Y - 10);
POINT_COLOR = BLACK;
LCD_ShowString(CHART_X + 73, CHART_Y - 13, 50, 16, 12, (u8*)"Target");
}
void Update_Temp_Data(float actual_temp, float target_temp)
{
u16 i;
if(data_count >= CHART_MAX_POINTS)
{
for(i = 0; i < CHART_MAX_POINTS - 1; i++)
{
actual_temp_history[i] = actual_temp_history[i + 1];
target_temp_history[i] = target_temp_history[i + 1];
}
actual_temp_history[CHART_MAX_POINTS - 1] = actual_temp;
target_temp_history[CHART_MAX_POINTS - 1] = target_temp;
}
else
{
actual_temp_history[data_count] = actual_temp;
target_temp_history[data_count] = target_temp;
data_count++;
}
}
void Draw_Temp_Chart(void)
{
u16 i;
u16 x1, y1, x2, y2;
float temp_scaled;
u16 points_to_draw;
Draw_Chart_Axis();
points_to_draw = (data_count < CHART_MAX_POINTS) ? data_count : CHART_MAX_POINTS;
if(points_to_draw < 2) return;
POINT_COLOR = RED;
for(i = 0; i < points_to_draw - 1; i++)
{
temp_scaled = (actual_temp_history[i] - TEMP_MIN) / (TEMP_MAX - TEMP_MIN);
if(temp_scaled > 1.0) temp_scaled = 1.0;
if(temp_scaled < 0.0) temp_scaled = 0.0;
x1 = CHART_X + (i * CHART_WIDTH) / (CHART_MAX_POINTS - 1);
y1 = CHART_Y + CHART_HEIGHT - (u16)(temp_scaled * CHART_HEIGHT);
temp_scaled = (actual_temp_history[i + 1] - TEMP_MIN) / (TEMP_MAX - TEMP_MIN);
if(temp_scaled > 1.0) temp_scaled = 1.0;
if(temp_scaled < 0.0) temp_scaled = 0.0;
x2 = CHART_X + ((i + 1) * CHART_WIDTH) / (CHART_MAX_POINTS - 1);
y2 = CHART_Y + CHART_HEIGHT - (u16)(temp_scaled * CHART_HEIGHT);
LCD_DrawLine(x1, y1, x2, y2);
}
POINT_COLOR = BLUE;
for(i = 0; i < points_to_draw - 1; i++)
{
temp_scaled = (target_temp_history[i] - TEMP_MIN) / (TEMP_MAX - TEMP_MIN);
if(temp_scaled > 1.0) temp_scaled = 1.0;
if(temp_scaled < 0.0) temp_scaled = 0.0;
x1 = CHART_X + (i * CHART_WIDTH) / (CHART_MAX_POINTS - 1);
y1 = CHART_Y + CHART_HEIGHT - (u16)(temp_scaled * CHART_HEIGHT);
temp_scaled = (target_temp_history[i + 1] - TEMP_MIN) / (TEMP_MAX - TEMP_MIN);
if(temp_scaled > 1.0) temp_scaled = 1.0;
if(temp_scaled < 0.0) temp_scaled = 0.0;
x2 = CHART_X + ((i + 1) * CHART_WIDTH) / (CHART_MAX_POINTS - 1);
y2 = CHART_Y + CHART_HEIGHT - (u16)(temp_scaled * CHART_HEIGHT);
LCD_DrawLine(x1, y1, x2, y2);
}
}
int main(void)
{
u16 adcx;
float temp;
float temp2;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
TIM3_Int_Init(500-1,8400-1);
uart_init(115200);
LED_Init();
LCD_Init();
Adc_Init();
Dac1_Init();
PID_Init(&t1, 1, Kp_temp, Ki_temp, Kd_temp, 2047.0f, 1000.0f);
POINT_COLOR=RED;
LCD_ShowString(30,30,200,16,16,"VOL:");
LCD_ShowString(30,50,200,16,16,"VAL:");
LCD_ShowString(30,70,200,16,16,"OUT:");
LCD_ShowString(30,90,200,16,16,"temputure:");
LCD_ShowString(30,110,200,16,16,"Kp:");
LCD_ShowString(30,130,200,16,16,"Ki:");
LCD_ShowString(30,150,200,16,16,"Kd:");
LCD_ShowString(30,170,200,16,16,"PIDout:");
LCD_ShowString(30,190,200,16,16,"targetad:");
LCD_ShowString(30,210,200,16,16,"targettemp:");
POINT_COLOR=BLUE;
Draw_Chart_Axis();
while(1)
{
targetad=temptoad(targettemp);
adcx=Get_Adc_Average(ADC_Channel_1,20);
LCD_ShowxNum(134,50,adcx,4,16,0);
LCD_ShowxNum(134,170,dacval,4,16,0);
LCD_ShowxNum(134,190,targetad,4,16,0);
temputure=adtotemp(adcx);
targetad=temptoad(targettemp);
float temp_diff = temputure - last_temperature;
if(temp_diff < 0) temp_diff = -temp_diff;
temperature_change_rate = temp_diff / 0.01f;
last_temperature = temputure;
float pid_output = PID_Cal_Temp(&t1, targettemp, temputure);
dacval = 2048 + (uint16_t)pid_output;
temp=(float)adcx*(3.3/4096);
adcx=temp;
LCD_ShowxNum(134,30,adcx,1,16,0);
temp-=adcx;
temp*=1000;
if(dacval<2500)dacval=2500;
if(dacval>4095)dacval=4095;
DAC_SetChannel1Data(DAC_Align_12b_R,dacval);
printf("%c\n" ,USART_Temp[0] );
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;
for(t=0;t<len;t++)
{
USART_SendData(USART1, USART_RX_BUF[t]);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
}
USART_Temp[0]=USART_RX_BUF[0];
USART_Temp[1]=USART_RX_BUF[1];
USART_Temp[2]=USART_RX_BUF[2];
USART_Temp[3]=USART_RX_BUF[3];
printf("\n");
USPID_GetValue();
USART_RX_STA=0;
}
printshuju();
LCD_ShowxNum(150,30,temp,3,16,0X80);
LCD_ShowxNum(134,70,dacval,4,16,0);
LCD_ShowxNum(134,90,temputure,4,16,0);
temp2=temputure-(int)temputure;
temp2*=1000;
LCD_ShowxNum(175,90,temp2,3,16,0X80);
LCD_ShowxNum(134,110,Kp_temp,4,16,0);
temp3=Kp_temp-(int)Kp_temp;
temp3*=1000;
LCD_ShowxNum(175,110,temp3,3,16,0X80);
LCD_ShowxNum(134,130,Ki_temp,4,16,0);
temp4=Ki_temp-(int)Ki_temp;
temp4*=1000;
LCD_ShowxNum(175,130,temp4,3,16,0X80);
LCD_ShowxNum(134,150,Kd_temp,4,16,0);
temp5=Kd_temp-(int)Kd_temp;
temp5*=1000;
LCD_ShowxNum(175,150,temp5,3,16,0X80);
LCD_ShowxNum(134,210,targettemp,4,16,0);
temp6=targettemp-(int)targettemp;
temp6*=1000;
LCD_ShowxNum(175,210,temp6,3,16,0X80);
chart_update_counter++;
if(chart_update_counter >= 50)
{
chart_update_counter = 0;
Update_Temp_Data(temputure, targettemp);
Draw_Temp_Chart();
}
delay_ms(10);
}
}
#include "stm32f4xx.h"
#include <math.h>
#include "PID.h"
int Flag;
int need_to_be_charged;
float cap_volt,Wire;
PidTypeDef moterR;
PidTypeDef moterL;
PidTypeDef AD;
PidTypeDef moter1;
PidTypeDef moter2;
PidTypeDef moter3;
PidTypeDef moter4;
void PID_Init(PidTypeDef *pid, uint8_t mode, const float Kp,const float Ki,const float Kd ,float max_out, float max_iout)
{
pid->Mode = mode;
pid->Kp = Kp;
pid->Ki = Ki;
pid->Kd = Kd;
pid->PIDOutLimit = max_out;
pid->IPartLimit = max_iout;
pid->err = pid->old_err = pid->oldd_err = pid->PPart = pid->IPart = pid->DPart = pid->PIDOut = 0.0f;
}
float PID_Cal_Temp(PidTypeDef *Pid, float Target_Temp, float Real_Temp)
{
Pid->old_err = Pid->err;
Pid->target = Target_Temp;
Pid->real = Real_Temp;
Pid->err = Target_Temp - Real_Temp;
float kp = Pid->Kp;
float ki = Pid->Ki;
float kd = Pid->Kd;
if (fabsf(Pid->err) > 5.0f) {
kp *= 1.2f;
ki *= 0.3f;
kd *= 0.8f;
} else if (fabsf(Pid->err) > 2.0f) {
kp *= 1.0f;
ki *= 0.8f;
kd *= 1.2f;
} else {
kp *= 0.6f;
ki *= 1.5f;
kd *= 1.0f;
}
Pid->PPart = kp * Pid->err;
Pid->IPart += ki * Pid->err;
if (Pid->IPart > Pid->IPartLimit)
Pid->IPart = Pid->IPartLimit;
else if (Pid->IPart < -Pid->IPartLimit)
Pid->IPart = -Pid->IPartLimit;
float derivative = Pid->err - Pid->old_err;
Pid->DPart = kd * derivative;
Pid->PIDOut = Pid->PPart + Pid->IPart + Pid->DPart;
if (Pid->PIDOut > Pid->PIDOutLimit)
Pid->PIDOut = Pid->PIDOutLimit;
if (Pid->PIDOut < 0)
Pid->PIDOut = 0;
return Pid->PIDOut;
}#ifndef __PID_H_
#define __PID_H_
#include <stdint.h>
extern int Flag;
extern int need_to_be_charged;
extern float V0,V1,cap_volt,Wire;
typedef struct
{
uint8_t Mode;
float Kp;
float Ki;
float Kd;
float target;
float real;
float err;
float old_err;
float oldd_err;
float err_integral;
float PPart;
float IPart;
float DPart;
float PIDOut;
float IPartLimit;
float PIDOutLimit;
}PidTypeDef;
extern PidTypeDef moterR;
extern PidTypeDef moterL;
extern PidTypeDef AD;
extern PidTypeDef moter1;
extern PidTypeDef moter2;
extern PidTypeDef moter3;
extern PidTypeDef moter4;
void PID_Init(PidTypeDef *pid, uint8_t mode, const float Kp,const float Ki,const float Kd ,float max_out, float max_iout);
float PID_Cal_Temp(PidTypeDef *Pid, float Target_Temp, float Real_Temp);
#endif
我是否已经完成了统一使用温度值进行 PID 控制?但是main.c中PID_Cal_Temp报错是为什么