程序是这个样子的:
/*
程序目的:让带编码器的直流电机在10秒时间内通过PWM控制按照设定速度运转,10秒钟以后反转
电机转一圈,编码器分辨率为64,通过外部中断反馈被识别了多少次,然后通过计算算
出电机的速度,再将速度与设定值相比较,然后通过PWM调速。
*/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define PI 3.1415926
uchar a;
uint PWM_T;
uint t=0,t1;//t1为编码器识别的次数
float v,b;//v表示速度,b用来定时
sbit D11=P1^0; //D11表示电机一极,D12表示另外一极
sbit D12=P1^1;
void delay(unsigned int c)//延时函数
{
unsigned int m,n;
for(m=c;m>0;m--)
for(n=114;n>0;n--);
}
void main()
{
a=0;
TR0 =1; //启动定时器0
TR1 =1; // 启动定时器1
TMOD =0x12;//设置定时器模式,0001 0010,此时为定时器1 工作模式1(16位定时器),定时器0工作模式2(八位自动填装)
TH1 =0x4B; // 定时50毫秒,填充初值
TL1 =0xFC;
TH0=200;
TL0=200;//写入预置初值(取值1-255,数越大PWM频率越高)
EA=1; //打开总中断
ET0=1; //打开定时器中断0
EX0=1; //打开外部中断0
IT0=1; //外部中断为跳变沿触发方式
D11=1;
D12=0; //电机两极有电位差,实现转动
PWM_T=30; //PWM_T初值
while(1)
{
if(TF1==1)//查询T1是否溢出
{
TH1=0x4b;//T1溢出,重新填装初值
TL1=0xfc;
TF1=0; //重新将T1置零,开始第二次计时
a++; //一次a代表50毫秒
}
if(a==2)//查询a是否达到2次,若达到,表示计时达到0.1秒
{
a=0;
b++; //b代表0.1秒
}
while(b==50)//查询b是否达到50次,若达到,表示已计时达到5秒,达到5秒后电机持续反转
{
D11=0;
D12=1;
}
if(b<50)//在5秒以内PWM调速,5秒之后自动反转,且不再进入PWM调速程序
{
v=(0.2*PI*t1)/64/(10*b);//电机是来带动轮子转动,轮子直径是0.1米,V代表此时的速度(我觉得是这样)
if(v<0.1)//括号里面的数就代表设定的速度,速度比设定的低了,就加大占空比,高了就减小
{
if(PWM_T<250)
{
PWM_T++;
}
delay(10);
}
if(v>0.1)
{
if(PWM_T>0)
{
PWM_T--;
}
delay(10);
}
}
}
}
void ex0() interrupt 0//编码器识别的次数
{
t1++;
}
void timer0() interrupt 1//定时器0中断,
{
t++; //每次定时器溢出
if(t>=250) //PWM周期 100个单位
{
t=0; /*使t=0,开始新的PWM周期(但是我的实际情况t好像并没有清零,
因为在5秒中之内电机会停下来,而我程序中其他地方并没有可以让它停下来的指令)*/
D11=0; //这个就是在周期内输出让电机停转的信号
D12=0;
}
if(PWM_T==t) //周期内电机转动的信号
{
D11=1;
D12=0;
}
} /*哪位大神帮我解决一下,感激不尽,这个程序我改了两天了还是没有解决,
我感觉自己的想法没错,但是就是实现不了,我也很无奈*/
搜索
复制