仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg51.h>
- #include "lcd1602.h"
- #define THC0 0xf9
- #define TLC0 0x0f //
- /***********端口定义**************/
- //按键
- sbit StopAndStart =P0^0;
- sbit KeyTurnForward =P0^1;
- sbit KeyTurnBackward=P0^2;
- sbit KeyAddSpeed =P0^3;
- sbit KeySubSpeed =P0^4;
- //电机
- sbit CONT1=P2^3;
- sbit CONT2=P2^4;
- sbit EN =P2^5;
- //
- sbit LED1 = P2^0;
- sbit LED2 = P2^1;
- sbit LED3 = P2^2;
- /*^^^^^^^^转态变量^^^^^^^^^^*/
- unsigned char motoEn;
- unsigned char motoDirection;
- /***********变量定义**************/
- unsigned int SpeedSet = 100; //速度设置
- unsigned int Impluse = 0; //脉冲计数
- unsigned int num = 0; //速度显示
- unsigned int cnt = 0;
- unsigned int PWMTime=500; //脉冲宽度
- int e,e1,e2;
- float uk,uk1,duk; //PID输出值
- float Kp=15,Ki=12,Kd=1.6;
- int out=0;
- /*^^^^^^^^延时函数^^^^^^^^^^*/
- void delay_xms(unsigned char ms)
- {
- unsigned int i,j;
- for(i=0;i<ms;i++)
- {
- for(j=0;j<333;j++);
- }
- }
- /*########系统初始化########*/
- void SystemInit()
- {
- //外部中断0
- IT0 = 1; //下降沿触发
- EX0 = 1; //开外部中断
- EA = 1; //开总中断
- //定时器0 1
- ET0=1; //开定时器中断
- TMOD=0X21;//T0方式2 T1方式2
- TH0 = THC0;
- TL0 = TLC0;
- TR0 = 1; //启动定时器0
- TH1=0x10;
- TL1=0x10;
- ET1=1;
- TR1=1;
- e = 0;
- e1 = 0;
- e2 = 0;
- motoEn=0;
- motoDirection=1;
- //LCD
- LCD1602_Init();
-
- }
- /*########按键扫描##########*/
- void key_scan()
- {
- //启/停
- if(StopAndStart == 0) //判断按下
- {
- delay_xms(10);
- if(StopAndStart == 0)
- {
-
- while(StopAndStart == 0 ); //判断松手
- //执行按键功能
- motoEn=~motoEn;
- //EN=1;
- }
- }
-
- //正转
- if(KeyTurnForward == 0) //判断按下
- {
- delay_xms(10);
- if(KeyTurnForward == 0)
- {
-
- while(KeyTurnForward == 0 ); //判断松手
- //执行按键功能
- motoDirection=1;
- //CONT1 = 1;
- //CONT2 = 0;
- }
- }
- //反转
- if(KeyTurnBackward == 0) //判断按下
- {
- delay_xms(10);
- if(KeyTurnBackward == 0)
- {
- while(KeyTurnForward == 0 ); //判断松手
- //执行按键功能
- motoDirection=0;
- //CONT1 = 0;
- //CONT2 = 1;
- }
- }
-
- //加速
- if(KeyAddSpeed == 0)
- {
- delay_xms(10);
- if(KeyAddSpeed == 0) //判断按下
- {
- unsigned char i=0;
- while(KeyAddSpeed == 0 && i<255){delay_xms(1);i++;} //判断松手
- //执行按键功能
- SpeedSet += 5;
- if(SpeedSet>300)
- {
- SpeedSet = 300;
- }
- }
- }
- //减速
- if(KeySubSpeed == 0) //判断按下
- {
- delay_xms(10);
- if(KeySubSpeed == 0)
- {
- unsigned char i=0;
- while(KeySubSpeed == 0 && i<255){delay_xms(1);i++;} //判断松手
- //执行按键功能
- SpeedSet -= 5;
- if(SpeedSet<0)
- {
- SpeedSet = 0;
- }
- }
- }
- }
- /*##########电机状态动作###########*/
- void MotoControl()
- {
- if(motoEn == 0)
- {
- EN=0;
- CONT1=0;
- CONT2=0;
- LED1 = 1;
- }
- else
- {
- EN=1;
- LED1 = 0;
- if(motoDirection == 1)
- {
- CONT1=1;
- CONT2=0;
- LED2 = 0;
- LED3 = 1;
- }
- else
- {
- CONT1=0;
- CONT2=1;
- LED2 = 1;
- LED3 = 0;
- }
- }
- }
- /*########LCD显示###########*/
- void LCDDis()
- {
- LCD1602_4num(0,8,num);
- LCD1602_4num(1,8,SpeedSet);
- }
- /*^^^^^^^^PWM 输出^^^^^^^^^*/
- void PWMOUT()
- {
- if(motoDirection == 1)
- {
- if(cnt<PWMTime)
- {
- CONT1=1;
- }
- else
- {
- CONT1=0;
- }
- }
- else
- {
- if(cnt<PWMTime)
- {
- CONT2=1;
- }
- else
- {
- CONT2=0;
- }
- }
- if(cnt>1000) cnt = 0;
- }
- /*########PID调速############*/
- 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;
- }
- /********************/
- void main()
- {
- SystemInit();
- while(1)
- {
- key_scan();//按键扫描
- LCDDis();//LCD显示
- MotoControl();//根据按键扫描出的结果做出响应
- PWMOUT();
-
- }
- }
- /*@@@@@@@@@@外部中断0@@@@@@@@@@@@@@*/
- void inter0() interrupt 0
- {
- Impluse++; //采集外部脉冲数据
- }
- /*@@@@@@@@@@定时器中断0@@@@@@@@@@@@@@*/
- void inter1() interrupt 1
- {
- static unsigned int time=0;
- TH0=THC0;
- TL0=TLC0;
- time++; //转速测量周期
- if(time>100)
- {
- time=0;
- num=Impluse*5;
- Impluse=0;
- PIDControl();
- }
- }
- void inter3() interrupt 3
- {
- cnt++;
- if(motoDirection == 1)
- {
- if(cnt<PWMTime)
- {
- CONT1=1;
- }
- else
- {
- CONT1=0;
- }
- }
- else
- {
- if(cnt<PWMTime)
- {
- CONT2=1;
- }
- else
- {
- CONT2=0;
- }
- }
- if(cnt>1000) cnt = 0;
- }
复制代码
全部资料51hei下载地址:
直流调速.zip
(94.76 KB, 下载次数: 149)
|