本帖最后由 拿起书本 于 2012-4-15 21:30 编辑
直流电机具有良好的起运,制动性能,宜于在大范围内平滑调速,在许多需要调速或快速正反向的电力拖动系统中得到了广泛的应用。
单片机控制直流电机的基本方法是通过改变直流电机电枢电压的接通时间与通电周期的比值来控制电机速度,这种方法称为脉冲宽度调制,简称PWM
程序
******************************************************************************
程序功能为电机控制信号输出端P0.0初始输出低电平,根据测得的电机转速值与最高允许转速值进行比较,小于最高转速值时,增大P0.0脉冲的高电平宽度,提高电机转速;大于最高转速值时,减小P0.0脉冲的高电平宽度,直至电机转速等于最高转速200。
*******************************************************************************
#include <reg51.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
uchar bit100 数码管显示数值单元
uchar bit10
uchar bit1
uchar cout 1s定时控制参数
uchar cnt1,cnt2 延时参数单元
ucha rvalue 电机转速单元
ucha value 电机最高允许转速
定时器0中断服务程序,用于电机测速
void time0_int(void) interrupt 1
{
uchar temp
ET0=0 关闭T0中断
TR0=0;
cout=cout-1 1s定时控制参数
if(cout<=0) 1s定时到?
{
cout=0x14;
rvalue=TL1;
TH1=0x00; //重新设置电机测速时参数
TL1=0x00;
TH0=0x3c;
TL0=0xbb;
bit1=rvalue%0x0a; //转速数值换算
temp=rvalue/0x0a;
bit10=temp%0x0a;
bit100=temp/0x0a;
TR1=1; 打开T0定时、T1计数
ET0=1;
}
else
{
TH0=0x3c; 1s定时未到,T0 重装50ms定时参数
TL0=0xbb;
TR1=1;
ET0=1;
}
return;
}
//主程序开始,主要内容为初始化设置、
void main(void)
{
SP=0x70
cout=0x14;
cnt1=0x00;
cnt2=0x00;
value=0xc8; 转速设定值为100
TH1=0x00;
TL1=0x00;
TH0=0x3c; 50ms定时参数设定
TL0=0xbb;
TMOD=0x51
start(); MAX7219初始化
dig1=0x01;
dig2=0x02;
dig3=0x03;
dplay();
EA=1; 中断设置
ET0=1;
ET1=1;
TR0=1; 启动T0计时、T1计数
TR1=1;
while(1)
{
if(rvalue<value) 转速低于200
{
P0^0=1;
cnt1++; //驱动信号高电平维持时间增大,使转速增大
delay(cnt1);
cnt2=0xff-cnt1 //低电平维持时间减少
P0^0=0;
delay(cnt2);
return;
}
else if(rvalue>value) 转速高于200
{
P0^0=1;
cnt1--;
delay(cnt1); //驱动信号高电平维持时间较少,使转速减小
cnt2=0xff-cnt1 //低电平维持时间增加
P0^0=0;
delay(cnt2);
return
}
else 转速等于200
{
P0^0=1;
delay(cnt1); //驱动信号特性维持不变
P0^0=0;
delay(cnt2);
return;
}
}
}
转速显示程序
void dplay(void)
{
sendword(dig3,bit100); //发送数码管百位显示码到7219
sendword(dig2,bit10); //发送数码管十位显示码到7219
sendword(dig1,bit1); //发送数码管个位显示码到7219
}
数码管驱动MAX7219初始化程序
void start(void)
{
sendword (00b,0x02); // 设置扫描界限
sendword (0x09, 0x0ff); // 设置译码模式
sendword (0x0a, 0x0a); // 设置亮度
sendword (0x0c, 0x01); // 设置为正常工作模式
}
void sendword (uchar addr,uchar num)
{
LOAD=0; //7219准备接受16位数据
_nop_();
sendcode(addr); //7219接收8位寄存器地址
_nop_();
sendcode(num); //7219接收8位寄存器数据
_nop_();
LOAD=1; // 7219锁存进相应寄存器
}
发送一个字节数据到MAX7219
void sendcode (uchar code)
{
uchar i,temp;
_nop_();
for (i=0;i<8;i++)
{
temp=code&0x80;
code=code<<1;
if(code) //发送1
{
DIN=1;
CLK=0;
CLK=1;
}
else //发送0
{
DIN=0;
CLK=0;
CLK=1;
}
}
} |