358 基于单片机 PID直流电机控制系统设计【毕设课设】

完整版 电路图和程序代码 下载地址

https://pan.baidu.com/s/1RfYvweDxuF1L-OIg3cxVMA?pwd=8888

部分代码展示

#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char 
#define uint unsigned int

uchar i=0;
sbit AddSpeed=P1^0;//加速按键置位 
sbit SubSpeed=P1^1;//减速按键置位 
sbit Turn=P1^2;//正转按键置位 
sbit Stop=P1^3;//停止按键置位 
sbit IN1=P3^6;
sbit IN2=P3^7;//控制电机正反转和停止状态 
sbit PWM_FC=P1^7;//输出PWM口 
bit ENA=1;

sbit E=P2^7;		//1602使能引脚	  仿真
sbit RW=P2^6;		//1602读写引脚	
sbit RS=P2^5;		//1602数据/命令选择引脚


float pid_p=0.5,pid_i=0.1,pid_d=0;//0.002	//PID三个参数 初值
unsigned int lastError=0;
long int sumError=0;//sum偏差和
int out=0;		   //PWM高电平时间控制标志位
int SpeedSet=0;//速度初值 
uint cnt=0;	     //PWM的周期标志位
uint Inpluse=0,num=0;//脉冲计数
int pid_val_mid=0;//脉冲宽度
//void PIDControl();//PID控制子函数 
void SystemInit();//定时器和中断初始化子函数
void delay(uchar x); //延时子函数
void delayus (uchar x); 
void PWMOUT();		//PWM输出子函数
void SetSpeed();	//按键进行速度和转向控制子函数
void SegRefre();	//显示刷新子函数


void delay(uchar x);

void L1602_Write_char(uchar hang,uchar lie,char sign);

void L1602_init(void);

void L1602_Write_string(uchar hang,uchar lie,uchar *p);

void L1602_Write_Com(uchar del);
/**************主函数************/
void main()				//定时器和中断初始化
{
	SystemInit();
	L1602_init();
	L1602_Write_string(1,1,"spdset:   ");
	L1602_Write_string(2,1,"speed:   ");
	while(1)
	{
		SetSpeed();		//按键设定速度
		SegRefre();		//显示器显示刷新	
		if(SpeedSet==0)
		{
			ENA=0;
		}
	}
}
/***************pid偏差计算子函数 ***************/
unsigned int PID()
{  

  int dError=0,Error=0,B;
	
	Error=SpeedSet-num;//当前误差
   sumError=Error+sumError;//误差和
   dError=Error-lastError;//误差偏差
   lastError=Error;

	
	if(Error>10)
	{
	B=100;
	}
	else if (Error<-10)
	{
	B=0;
	}
	else
	{
	  B=pid_p*Error+pid_i*sumError+pid_d*dError;
	}
	if(B>100) pid_val_mid=100;
   if(B<0) pid_val_mid=0;
	if(B>=0&&B<=100)
   pid_val_mid=B;
	 return(0);
}
/**************延时子函数**************/
void delay(uchar x)//延时子函数平
{
	uint i,j;
	for(i=x;i>0;i--)
		for(j=50;j>0;j--);
}

void delayus(uchar x)
{
  uchar i;
  while(x--)
  for(i=0;i<110;i++);
}


/************PWM输出子函数*************/ 
void PWMOUT()		   //输出PWM脉冲子函数,进行PWM高低电平时间的判别 
{
	if(cnt<pid_val_mid)	   //高电时间为PID输出PWMTime	    
	{
		PWM_FC=1;
	}
	else
	{
		PWM_FC=0;
	}
	if(cnt>=100) 
		cnt=0;	 //100次定时器T1中断触发时间为一个PWM周期为1ms,故所取PWM频率为1k
}
/****************定时器和中断初始化子函数*************************/
void SystemInit()//定时器和中断初始化子函数
{
	TMOD=0X11;//TOMD寄存器设置,T0为16位定时器,T1为8位自动重装定时器 
	TH0=(65536-2000)/256;
	TL0=(65536-2000)%256; //定时器T0定时2ms 
	TH1=0xfc;		      
	TL1=0X66;		   //定时器T1定时10us
	ET1=1;      //T1中断允许 
	ET0=1;      //T0中断允许 
	TR0=1;      //启动定时器T0 
	TR1=1;      //启动定时器T0 
	EX0=1;     //允许外部中断0,中断0用来测量转速
	IT0=1;      //跳变沿触发方式计数 
	EA=1;       //全局中断允许 
	IN1 = 1;    //默认电机初始转向为正向 
	IN2 = 0;
}
/**************按键进行速度和转向控制子函数**************/ 
void SetSpeed()              //按键进行速度和转向控制子函数
{
	if(AddSpeed==0)           //加速按键按下 
	{
		delay(200);			  //按键消抖处理
		if(AddSpeed==0)
		{
			SpeedSet=SpeedSet+50;
			if(SpeedSet>500)  
			{
				SpeedSet=500;  
			}
		      while(AddSpeed==0);
		}
	}
	if(SubSpeed==0)           //减速按键按下  
	{
		delay(200);           //按键消抖处理
		if(SubSpeed==0)       
		{
			SpeedSet=SpeedSet-50;
			if(SpeedSet<=0) 
            {
			SpeedSet=0;       
		    }
			while(SubSpeed==0);
		}
	}
	if(Turn==0)         //正/反转按键按下 
	{
		delay(200);            //按键消抖处理  
		if(Turn==0)     //实现电机正反转切换 
		{
		   IN1 = ~IN1;
		   IN2 = ~IN2;
		   while(Turn==0);
		}
	}
	if(Stop==0)                  //停止按键按下
	{
		delay(200);              //按键消抖处理 
		if(Stop==0)              //实现电机停止 
		{
   ENA=~ENA;
		   while(Stop==0);
		}
	}

}

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值