PID控制输出PWM核心代码(基于STM32F103)

注:

1、如果对于PID控制原理不是很了解,可以找些资料看,最好先搞懂原理。

2、程序中Kp、Ki、Kd、199.0可根据实际情况自己修改。

//全局变量
float target=30.0;//目标温度
float error_all=0;
unsigned int show_zkb=0;//这是一个整数,即当前占空比,可用于在屏幕上显示


//PID算法
int PID(float input_wendu)//反馈输入温度,从温度传感器上读取,如DHT11
{
	float Kp=200.0,Ki=10.0,Kd=50.0;
	float error,d1;
	static unsigned char x=0;
	int output_pwm;//反馈输出PWM
	error=input_wendu-target;//实际温度-目标温度=误差
	if(x==0)
	{d1=error,x=~x;}
	error_all=error_all+error;//历史误差求和
	output_pwm=199.0+Kp*error+Ki*error_all+Kd*(error-d1);
	if((error>0)&&(output_pwm>999))//因占空比范围0/1000~1000/1000
	{
		show_zkb=999;
		return 999;
	}
	else if((error<0)&&(output_pwm<0))
	{
		show_zkb=0;
		return 0;
	}
	else
	{
		show_zkb=output_pwm;
		return output_pwm;	
	}
}

  • 15
    点赞
  • 184
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
以下是一个简单的 STM32F103 上使用 PID 算法控制 PWM 的示例代码。假设你已经配置好了定时器 TIM2 作为 PWM 输出。 ```c #include "stm32f10x.h" // PID 控制器的参数 float Kp = 1.0; float Ki = 0.5; float Kd = 0.1; // PID 控制器的状态 float error = 0; float last_error = 0; float integral = 0; float derivative = 0; // 目标 PWM 占空比 uint16_t target_duty_cycle = 500; // 当前 PWM 占空比 uint16_t current_duty_cycle = 0; void TIM2_IRQHandler(void) { // 清除中断标志位 TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 更新当前 PWM 占空比 current_duty_cycle = TIM_GetCapture1(TIM2); // 计算 PID 控制器的输出 error = target_duty_cycle - current_duty_cycle; integral += error; derivative = error - last_error; last_error = error; float output = Kp * error + Ki * integral + Kd * derivative; // 根据 PID 控制器的输出调整 PWM 占空比 current_duty_cycle += (uint16_t)output; if (current_duty_cycle > 1000) { current_duty_cycle = 1000; } else if (current_duty_cycle < 0) { current_duty_cycle = 0; } // 更新 PWM 输出 TIM_SetCompare1(TIM2, current_duty_cycle); } int main(void) { // 初始化 TIM2 定时器作为 PWM 输出 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 1000 - 1; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse = 0; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStruct); TIM_Cmd(TIM2, ENABLE); // 配置中断 NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 进入主循环 while (1) { // 更新目标 PWM 占空比 target_duty_cycle = // 根据实际情况计算目标占空比 } } ``` 在这个示例代码中,我们使用定时器 TIM2 作为 PWM 输出,并且在中断处理函数中计算 PID 控制器的输出并根据输出调整 PWM 占空比。你需要根据实际情况调整 PID 控制器的参数和目标 PWM 占空比。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值