1.设计任务
基于单片机的直流电机控制系统设计
基本要求:利用单片机AT89C51设计直流电机控制系统,能对直流电机进行控制。
创新:能改变显示电机速度;能通过键盘操作改变电机的方向等。
任务区分:B——用米字型数码管显示速度
2. 设计要求
2.1系统方案论证
根据设计任务,分析设计系统的组成,给出实现设计任务的几种方案,分析比较几种设计方案的优略,本着尽量以软件代替硬件,同时力求电路简单,工作可靠的原则,确定总体设计方案。
2.2系统硬件电路设计
根据系统设计方案进行软、硬件的分配,软、硬件设计分别进行。硬件设计包括单片机最小系统和扩展接口及配置,硬件结构在设计时要选择合适的元器件,硬件电路要简洁、工作可靠,需用Proteus绘制整个系统的电路仿真原理图。
主函数
#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define THC0 0xf9
#define TLC0 0x0f //2ms
unsigned char code Duan[]={0x3F, 0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//¹²Òõ¼«ÊýÂë¹Ü£¬0-9¶ÎÂë±í
unsigned char Data_Buffer[8]={0,0,0,0,0,0,0,0}; // ÏÔʾ»º³å
uchar i=0;
sbit AddSpeed=P1^1;
sbit SubSpeed=P1^2;
sbit TurnForward=P1^3;
sbit TurnBackward=P1^4;
sbit Stop=P1^5;
sbit IN1=P3^0;
sbit IN2=P3^1;
sbit PWM_FC=P1^0;
int e ,e1 ,e2 ;
float uk ,uk1 ,duk ;//pidÊä³öÖµ
float Kp=15,Ki=12,Kd=1.6;
int out=0;
uint SpeedSet=380;
uint cnt=0;
uint Inpluse=0,num=0;//Âö³å¼ÆÊý
uint PWMTime=100;//Âö³å¿í¶È
unsigned char arry[];
void SendString(uint ch);
void PIDControl();
void SystemInit();
void delay(uchar x);
void PWMOUT();
void SetSpeed();
void SegRefre();
void delay(uchar x)
{
uint i,j;
for(i=x;i>0;i--)
for(j=50;j>0;j--);
}
void PWMOUT()
{
if(cnt<PWMTime)
{
PWM_FC=1;
}
else
{
PWM_FC=0;
}
if(cnt>1000) cnt=0;
}
void SystemInit()
{
TMOD=0X21;
TH0=THC0;
TL0=TLC0;
TH1=0xC0;
TL1=0XC0;
ET1=1;
ET0=1;
TR0=1;
TR1=1;
EX0=1;
IT0=1;
EA=1;
e =0;
e1=0;
e2=0;
IN1 = 1;
IN2 = 0;
}
void SetSpeed()
{
if(AddSpeed==0)
{
delay(200); //Ïû¶¶´¦Àí
if(AddSpeed==0)
{
SpeedSet+=10;
if(SpeedSet>1500)
{
SpeedSet=1500;
}
}
}
if(SubSpeed==0)
{
delay(200);
if(SubSpeed==0)
{
SpeedSet-=10;
if(SpeedSet<0) SpeedSet=0;
}
}
if(TurnForward==0)
{
delay(200);
if(TurnForward==0)
{
IN1 = 1;
IN2 = 0;
while(TurnForward==0);
}
}
if(TurnBackward==0)
{
delay(200);
if(TurnBackward==0)
{
IN1 = 0;
IN2 = 1;
while(TurnBackward==0);
}
}
if(Stop==0)
{
delay(200);
if(Stop==0)
{
IN1 = 1;
IN2 = 1;
while(Stop==0);
}
}
}
void SegRefre() //ÏÔʾˢÐÂ
{
Data_Buffer[0]=SpeedSet/1000; //·ÖÀëÉ趨ֵ¸÷λ
Data_Buffer[1]=SpeedSet%1000/100;
Data_Buffer[2]=SpeedSet%100/10;
Data_Buffer[3]=SpeedSet%10;
Data_Buffer[4]=num/1000;
Data_Buffer[5]=num%1000/100;
Data_Buffer[6]=num%100/10;
Data_Buffer[7]=num%10;
}
/**************Ö÷º¯Êý************/
void main()
{
SystemInit();
while(1)
{
SetSpeed(); //°´¼üÉ趨ËÙ¶È
SegRefre(); //ÊýÂë¹ÜÏÔʾˢÐÂ
PWMOUT(); //Êä³öPWM
}
}
void int0() interrupt 0
{
Inpluse++; //²É¼¯ÍⲿÂö³å
}
void t0() interrupt 1
{
static unsigned char Bit=0;
static unsigned int time=0;
TH0=THC0;
TL0=TLC0;
Bit++;
time++; //תËÙ²âÁ¿ÖÜÆÚ
if(Bit>8) Bit=0;
P0=0xff;
P2=Duan[Data_Buffer[Bit]]; //ÏÔʾ¶ÎÂë
switch(Bit) //ÊýÂë¹Üλѡ
{
case 0:P0=0X7F;break;
case 1:P0=0XBF;break;
case 2:P0=0XDF;break;
case 3:P0=0XEF;break;
case 4:P0=0XF7;break;
case 5:P0=0XFB;break;
case 6:P0=0XFD;break;
case 7:P0=0XFE;break;
}
if(time>100)
{
time=0;
num=Inpluse*5;
Inpluse=0;
PIDControl();
}
}
void timer_1() interrupt 3
{
cnt++; //cntÔ½´óÕ¼¿Õ±ÈÔ½¸ß2.5Khz
}
void PIDControl() //pidÆ«²î¼ÆËã
{
e=SpeedSet-num;
duk=(Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2))/50;
uk=uk1+duk;
out=(int)uk; //Êä³öΪռ¿Õ±È
if(out>1000)
{
out=1000;
}
else if(out<0)
{
out=0;
}
uk1=uk; //±äÁ¿ÖµÒÆÎ»
e2=e1;
e1=e;
PWMTime=out;
}
仿真图Proteus
完整代码点开链接私信 免费 获取。
【iBot机器人工作室的个人空间-哔哩哔哩】 https://b23.tv/ryUWVKa