1、多功能直流电机双向转动设计
2、多功能直流电机双向转动设计--程序编写
3、多功能直流电机双向转动设计--仿真
4、多功能直流电机双向转动设计--参考程序
#include<at89x52.h>
#define uchar unsigned char
#define uint unsigned int
#define T0_COUNT 100 //定时器0的计数值
#define KEY P1 //按键控制
#define PWM 100 //PWM计数值的上限值
#define INIT_VAL_PWM 20 //PWM占空比初始值
#define INCREMENT_PWM 10 //PWM控制时的增量大小
sbit DC_Moto_A = P2^0; //脉冲输入引脚
sbit DC_Moto_B = P2^1;
//sbit LED = P3^3; //LED指示灯接口
uchar count_PWM; //PWM计数值
uchar val_PWM; //PWM占空比的值(加速可调)
bit forward_flag; //电机正反转标志, 1:电机正转 0:电机反转
bit stop_flag; //电机停止/运行标志 1:停止 0;运行
bit suspend_flag; //电机暂停/继续标志 1:暂停 0:继续
/*-------------------------
函数名称:delay_ms
形 参:uint n:延时时间的长度
功 能:软件延时,延时的单位时间在1ms左右
返 回 值:无
-------------------------*/
void delay_ms(uint n)
{
uint i;
uchar j;
for(i=0;i<n;i++)
for(j=0;j<120;j++);
}
/*-------------------------
函数名称:key_scan
形 参:无
功 能:按键扫描
返 回 值:扫描的结果,"0"为无按键按下、非"0"为按键值
-------------------------*/
uchar key_scan() //按键检测
{
uchar temp = 0;
KEY = 0xff;
if(KEY!=0xff) //按键消抖
{
delay_ms(10);
KEY = 0xff;
if(KEY!=0xff)
{
temp = KEY;
while(KEY!=0xff) //等待按键释放
KEY = 0xff;
}
}
return temp;
}
/*-------------------------
函数名称:key_behav
形 参:uchar key_val:按键值
功 能:实现按键功能
返 回 值:无
-------------------------*/
void key_behav(uchar key_val)
{
switch(key_val)
{
case 0xfe: //电机加速
if((0==stop_flag)&&(0==suspend_flag))
{
val_PWM += INCREMENT_PWM; //增加占空比
if(val_PWM>PWM) //PWM表示占空比的上限值
val_PWM = PWM;
}
break;
case 0xfd: //电机减速
if((0==stop_flag)&&(0==suspend_flag)) //他是如何加速的事通过什么来实现的呢
{
if(val_PWM>=INCREMENT_PWM)
val_PWM -= INCREMENT_PWM; //减小占空比
}
break;
case 0xfb: //电机正或反转选择
if((0==stop_flag)&&(0==suspend_flag))
forward_flag = ~forward_flag; //切换电机旋转模式
break;
case 0xf7: //电机暂停/继续
if(stop_flag==0)
{
suspend_flag = ~suspend_flag;
if(suspend_flag)
{
TR0 = 0; //暂停
DC_Moto_A = 0;
DC_Moto_B = 0;
}
else
TR0 = 1; //继续
}
break;
case 0xef: //电机停止/运行
stop_flag =~ stop_flag;
if(stop_flag)
{ //停止
TR0 = 0; //停止PWM输出
val_PWM = INIT_VAL_PWM; //初始化变量和标志
LED = 1; //关闭指示灯
forward_flag = 1;
suspend_flag = 0; //停止运行的时候初始化一下
DC_Moto_A = 0;
DC_Moto_B = 0;
}
else
{
//LED = 0; //点亮指示灯
TR0 = 1; //允许输出PWM波形
}
break;
default:break;
}
}
/*-------------------------
函数名称:interrupt_init
形 参:无
功 能:中断寄存器初始化
返 回 值:无
-------------------------*/
void interrupt_init() //初始化
{
TMOD = 0x01; //选择定时器/计数器工作方式1
TH0 = (65536-T0_COUNT)/256;
TL0 = (65536-T0_COUNT)%256;
ET0 = 1; //开定时器/计数器中断
// TR0 = 1;
EA = 1; //开总中断
}
/*-------------------------
函数名称:variable_init
形 参:无
功 能:变量、标志初始化
返 回 值:无
-------------------------*/
void variable_init() //变量初始化
{
val_PWM = INIT_VAL_PWM;
forward_flag = 1; //电机正反转标志
suspend_flag = 0; //电机暂停/继续标志
stop_flag = 1; //电机停止/运行标志
// LED = 1; //关闭指示灯
DC_Moto_A = 0; //P2^0口输入
DC_Moto_B = 0; //P2^1口输入
}
/*-------------主函数----------*/
void main() //按键检测
{
uchar key_val;
variable_init(); //变量初始化
interrupt_init(); //中断函数初始化
while(1)
{
do
key_val = key_scan();
while(0==key_val);
key_behav(key_val);
}
}
/*-------------------------
函数名称:moto_run
形 参:无
功 能:中断函数;产生控制电机的PWM波形(定时器1中断)
返 回 值:无
--------------------------*/
void moto_run() interrupt 1 //选择正转还是反转跳入中断
{
TH0 = (65536-T0_COUNT)/256; //核心是在中断里面
TL0 = (65536-T0_COUNT)%256;
count_PWM++; //PWM计数值
if(forward_flag)
{ //电机正转
DC_Moto_B = 0;
if(count_PWM<val_PWM) //产生PWM
DC_Moto_A = 1;
else
DC_Moto_A = 0;
}
else
{ //电机反转
DC_Moto_A = 0;
if(count_PWM<val_PWM) //产生PWM
DC_Moto_B = 1;
else
DC_Moto_B = 0;
}
if(count_PWM>=PWM)
count_PWM = 0;
}
/********** 完毕 **********/

