单片机C语言模块化编程之双电机驱动篇.docx
《单片机C语言模块化编程之双电机驱动篇.docx》由会员分享,可在线阅读,更多相关《单片机C语言模块化编程之双电机驱动篇.docx(13页珍藏版)》请在冰豆网上搜索。
单片机C语言模块化编程之双电机驱动篇
单片机C语言模块化编程之双电机驱动篇
基于PROTEUS电路仿真;
电机通过L298电机驱动模块驱动;
通过双定时器完美生成PWM占空比控制电机速度,也可以单独使用一个定时器驱动双电机,方法一样;
通过按键扫描的方式控制电机的运动状态前进,后退,开始,停止,左拐,右拐等操作;
通过查看此文档,可以让初学者对程序模块化有一个初步认识,对电机驱动原理有一个初步了解。
注:
在真实遥控小车中能够正常运转,速度可以任意调节通过go(ucharsped1,ucharsped2)
Proteus仿真图如下:
C语言代码实现:
/*motor.h*/
#ifndef_MOTOR_H_
#define_MOTOR_H_
#include
#defineuintunsignedint
#defineucharunsignedchar
//电机控制位
sbitIN1=P0^0;//电机1的控制位IN1,IN2的值控制电机的正转,反转,停止,IN1=1,IN2=0电机正转,IN1=0,IN2=1电机反转,IN1=0,IN2=0电机停止转动;
sbitIN2=P0^1;
sbitINA=P0^4;//电机1的使能位INA=1,电机开始工作,INA=0,电机停止工作
sbitIN3=P0^2;//电机2的控制位IN3,IN4的值控制电机的正转,反转,停止,IN3=1,IN4=0电机正转,IN3=0,IN4=1电机反转,IN3=0,IN4=0电机停止转动;
sbitIN4=P0^3;
sbitINB=P0^5;//电机2的使能位INB=1,电机开始工作,INB=0,电机停止工作
//此处需要注意的地方,关于模块化编程时如果用到全局变量时,全局变量要在MOTOR.C中定义,MOTOR.H中需要extern声明(不可以再次赋值可以直接尝试下),否则将会报错。
externuintspeed1,speed2;//speed1电机速度值,t1电机一个周期的时间,PWM=speed/t;
externvoiddelay(uintxms);//一个简短的延时函数
externvoidgo(ucharspe1,ucharspe2);//电机加速函数,通过spe1,spe2控制电机速度
externvoidqianjin();//电机前进函数
externvoidback();//电机后退函数
externvoidturn_left();//电机左转
externvoidturn_right();//电机右转
externvoidstart();//电机启动函数
externvoidstop();//电机停止函数
externvoidISP_init();//定时器初始化函数
#endif
/*motor.c*/
#include"motor.h"
uintspeed1=0,speed2=0;
voiddelay(uintxms)//简单的延时
{
uinti;
ucharj;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
voidgo(ucharspe1,ucharspe2)//速度调节函数0~100之间
{
speed1=spe1;
speed2=spe2;
}
voidqianjin()//电机前进函数
{
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
voidback()//电机后退函数
{
IN1=0;
IN2=1;
IN3=0;
IN4=1;
}
voidturn_left()//电机左转
{
go(20,80);//此处速度可以任意调,0~100之间,左边的速度要小于右边速度值
}
voidturn_right()
{//电机右转
go(80,20);
}
voidstart()//开始
{
TR0=1;
TR1=1;
INA=1;
INB=1;
}
voidstop()//停止
{
TR0=0;
TR1=0;
INA=0;
INB=0;
}
voidISP_init()
{
TMOD=0X11;
TH0=-500/256;
TL0=-500%256;
TH1=-500/256;
TL1=-500%256;
ET0=1;
ET1=1;
EA=1;
}
voidTimer_0()interrupt1//通过2个定时器来实现左右2个电机占空比的输出
{
staticuchartemp1=0,t1=0;
TH0=-500/256;
TL0=-500%256;
if(t1==0)
{
temp1=speed1;//每个pwm输出完成后再接受新的速度值。
}
if(t1<=temp1)//通过定时器来实现左边电机PWM占空比的输出。
{
INA=1;
}
else
{
INA=0;
}
t1=(t1+1)%100;
}
voidTimer_1()interrupt3
{
staticuchartemp2=0,t2=0;
TH1=-500/256;
TL1=-500%256;
if(t2==0)//一个周期后才改变temp的值
{
temp2=speed2;
}
if(t2<=temp2)//通过定时器实现右边电机PWM占空比的输出。
{
INB=1;
}
else
{
INB=0;
}
t2=(t2+1)%100;
}
/*main.c*/
#include"motor.h"
sbitstart_k=P3^0;//开始按键
sbitstop_k=P3^1;
sbitqianjin_k=P3^2;
sbitback_k=P3^3;
sbitturn_left_k=P3^4;
sbitturn_right_k=P3^5;
bits_flag=0;//停止键按下标志位,按下停止键后再按其他的键都不起作用,直到开始键按下后恢复正常
voidkeyscan()
{
if(start_k==0)
{
delay(5);
if(start_k==0)
{
while(!
start_k);
start();
s_flag=0;
}
}
if(stop_k==0)
{
delay(5);
if(stop_k==0)
{
while(!
stop_k);
stop();
s_flag=1;
}
}
if(qianjin_k==0&&s_flag==0)
{
delay(5);
if(qianjin_k==0)
{
while(!
qianjin_k);
qianjin();
}
}
if(back_k==0&&s_flag==0)
{
delay(5);
if(back_k==0)
{
while(!
back_k);
back();
}
}
if(turn_left_k==0&&s_flag==0)
{
delay(5);
if(turn_left_k==0)
{
while(!
turn_left_k);
turn_left();
}
}
if(turn_right_k==0&&s_flag==0)
{
delay(5);
if(turn_right_k==0)
{
while(!
turn_right_k);
turn_right();
}
}
}
voidmain(void)
{
ISP_init();
while(start_k);//等待直到开始键按下后电机开始工作
delay(5);
while(!
start_k);
start();
qianjin();
go(80,80);//go(80,80),控制此时电机速度,PWM=80/100;占空比越大对应的电机速度越快
while
(1)
{
keyscan();//不断扫描按键按下情况
}
}
附录:
单个直流电机驱动原理
直流电机只有2个接口,正极,负极,给这两个接口通电电机就会转动,当然电压不要太高,否则会烧坏电机。
单片机控制直流电机运转,由于单片机驱动能力有限,所以需要增加外围驱动IC,我们这里使用的L298电机专用驱动模块,一个L298电机驱动模块可以同时驱动2个电机,在智能小车上面通常都使用L298刚好可以控制2个电机,L298需要12V电压才能够驱动,这点需要注意,当然低于12V也是可以驱动的,只是驱动能力不是太强,L298上有3个引脚需要注意(这里以一个电机驱动为例);
单个电机只需要控制IN1,IN2,INA这3个引脚即可,其中IN1,IN2是控制电机转动方向的控制引脚,IN1=1,IN2=0,对应的电机就好朝一个方向转动,IN1=0,IN2=1,电机会朝令一个方向转动,当IN1=0,IN2=0是电机就停止转动。
INA电机电机使能控制引脚,当INA=1时电机可以正常使用,当INA=0时,此时电机停止工作,无论怎么控制IN1,IN2的值电机始终停止工作。
驱动部分完成后就可以同过编程控制这3个引脚来控制电机的运动状态。
电机的速度控制需要占空比PWM来控制(不知道占空比的可以XX查下)下边就是产生占空比的方法:
1.通过延时的方法来实现占空比PWM
voidtimer_0()interrupt1
{
TH0=-50000/256;
TL0=-50000%256;
if(flag==0)
{
IN1=1;
IN2=0;
}
else
{
IN1=0;
IN2=1;
}
pwm1=1;
delay(num);
pwm1=0;
delay(100-num);
}
2.通过定时器的方法实现PWM
voidTimer_0()interrupt1//通过2个定时器来实现左右2个电机占空比的输出
{
staticuchartemp1=0,t1=0;
TH0=-500/256;
TL0=-500%256;
if(t1==0)
{
temp1=speed1;//每个pwm输出完成后再接受新的速度值。
}
if(t1<=temp1)//通过定时器来实现左边电机PWM占空比的输出。
{
INA=1;
}
else
{
INA=0;
}
t1=(t1+1)%100;
}