如题, 我们实训选了直流电机可调转速的项目,但是我想领导程序完美一点,电机达到那个要求的转速后,只能在要求速度上下徘徊,不能达到那个指定速度后匀速转动。
程序如下:
//文件名:main.c
//文件功能:包含液晶显示子文件
#include<reg52.h>//包含52单片机头文件
#include<lcd1602.h>
sbit S1=P1^5;
sbit S2=P1^6;
sbit S3=P1^7;
sbit PWM=P2^7;
bit flag=0;
unsigned int sec;
unsigned char fun_num=0;
unsigned int T0_num=0;
unsigned int num1=0; //本秒圈数
unsigned int num2=0; //上一秒圈数
unsigned int fre0=20; //设定
unsigned int fre =0; //差:fre=num1-num2;
unsigned int PWM_H=25; //高电平 所谓的“PWM”就是脉冲宽度调制
/*-------------------------------------------------------------------
//0123456789012345
[T:00001 Fre:9999]
[N:12345 fre:9999]
------------------------------------------------------------------*/
void display()
{
unsigned int i,j;
j=0;
i=0;LCD_dis(j,i,'t');
i++;LCD_dis(j,i,':');
i++;LCD_dis(j,i,0x30+sec/10000);
i++;LCD_dis(j,i,0x30+sec%10000/1000);
i++;LCD_dis(j,i,0x30+sec%1000/100);
i++;LCD_dis(j,i,0x30+sec%100/10);
i++;LCD_dis(j,i,0x30+sec%10);
i++;LCD_dis(j,i,' ');
i++;LCD_dis(j,i,'F');
i++;LCD_dis(j,i,'R');
i++;LCD_dis(j,i,'E');
i++;LCD_dis(j,i,':');
i++;LCD_dis(j,i,0x30+fre0%10000/1000);
i++;LCD_dis(j,i,0x30+fre0%1000/100);
i++;LCD_dis(j,i,0x30+fre0%100/10);
i++;LCD_dis(j,i,0x30+fre0%10);
//--------------------------------------------
j=1;
i=0;LCD_dis(j,i,'N');
i++;LCD_dis(j,i,':');
i++;LCD_dis(j,i,0x30+num1/10000);
i++;LCD_dis(j,i,0x30+num1%10000/1000);
i++;LCD_dis(j,i,0x30+num1%1000/100);
i++;LCD_dis(j,i,0x30+num1%100/10);
i++;LCD_dis(j,i,0x30+num1%10);
i++;LCD_dis(j,i,' ');
i++;LCD_dis(j,i,'F');
i++;LCD_dis(j,i,'R');
i++;LCD_dis(j,i,'E');
i++;LCD_dis(j,i,':');
i++;LCD_dis(j,i,0x30+fre%10000/1000);
i++;LCD_dis(j,i,0x30+fre%1000/100);
i++;LCD_dis(j,i,0x30+fre%100/10);
i++;LCD_dis(j,i,0x30+fre%10);
}
//-----------------延时函数------------------------
void delay_20ms()
{
unsigned int i=200;
while(i--);
}
//----------------按键扫描函数----------------------
void scan_key()//按键扫描
{
//-------------------------------------
if(S1==0)
{
delay_20ms();
if(S1==0)
{
//------------------------
fun_num++;
if(fun_num>=5) fun_num=0;
//------------------------
while(S1==0);
delay_20ms();
//------------------------
}
}
//-------------------------------------
if(S2==0)
{
delay_20ms();
if(S2==0)
{
//------------------------
if(fun_num==1) {fre0+=1000;}
else if(fun_num==2) {fre0+=100; }
else if(fun_num==3) {fre0+=10; }
else if(fun_num==4) {fre0+=1; }
//--------------------------------
while(S2==0);
delay_20ms();
//------------------------
}
}
//-------------------------------------
if(S3==0)
{
delay_20ms();
if(S3==0)
{
if(fun_num==1) {fre0-=1000;}
else if(fun_num==2) {fre0-=100; }
else if(fun_num==3) {fre0-=10; }
else if(fun_num==4) {fre0-=1; }
while(S3==0);
delay_20ms();
}
}
//-------------------------------------
}
//------------------------------------------
void ex0_server() interrupt 0 //外部中断0
{
num1++;
}
//-----------------------------------------------
void t0_server() interrupt 1 //定时器0中断
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
T0_num++;
if(T0_num<PWM_H) //10ms*25=250ms
{
PWM=1;
}
else if(T0_num<100) //10ms*100=1000ms=1s
{
PWM=0;
}
if (T0_num>=200) //200*5ms=1s
{
T0_num=0;
PWM=1;
flag=1;
fre=num1-num2;
num2=num1;
sec++;
if(fre>fre0) { if(PWM_H>0) PWM_H--;}
if(fre<fre0) { if(PWM_H<100) PWM_H++;}
SBUF=0x30+fre%1000/100;while(TI==0);TI=0;
SBUF=0x30+fre%100/10; while(TI==0);TI=0;
SBUF=0x30+fre%10; while(TI==0);TI=0;
SBUF=0x0d; while(TI==0);TI=0;
SBUF=0x0a; while(TI==0);TI=0;
}
}
//***************串口中断函数**********************//
void serial_sever() interrupt 4
{
if(RI==1) { RI = 0; }
}
//--------------外部中断0的初始化函数----------------------------
void EX0_Init()
{
IT0=1; EX0=1; EA=1; PX0=1;
}
//---------------定时中断0的初始化函数----------------------------
void ET0_Init()
{
TMOD=0X01;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
ET0=1;
EA =1;
PT0=1;
TR0=1;
}
//************串口中断的初始化函数*****************//
void s_Init()
{
SCON = 0x50; // 串口工作在方式1, 允许接收
PCON |= 0x80; // SMOD=1;波特率倍增
TMOD |= 0x20; // 定时器1工作在方式2,重载
TH1 = 0xf3; // 波特率4800,fosc=12MHz
TL1 = 0xf3; // 波特率4800,fosc=12MHz
EA = 1;
ES = 1; // 允许串行中断,interrupt enable
TR1 = 1; // 启动定时器1,timer1 run
TI = 0; //发送中断溢出标志
RI = 0; //接收中断溢出标志
}
//-------------------主函数----------------------------------
void main()//
{
Init_LCD();//液晶初始化
EX0_Init();//调用外部中断0的初始化函数
ET0_Init();//调用定时中断0的初始化函数
s_Init();//调用串口中断的初始化函数
//-----------------------------------------------
while(1)
{
if(flag==1)
{
flag=0;
display();
}
scan_key();//按键扫描
}
}
希望有高手帮忙改改!! 拜托了。
此帖出自
小平头技术问答
有点波动是正常的吧,就算加入了闭环控制,使用pid等控制算法,也是会有点波动的,能满足精度需求就可以了吧。
一周热门 更多>