51单片机驱动直流电机程序(用的是l298n芯片):
#include<reg51.h>
#include<math.h>
#defineuintunsignedint
#defineucharunsignedchar
#defineN100
sbit s1=P1^0//电机驱动口
sbits2=P1^1//电机驱动口
sbits3=P1^2//电机驱动口
sbits4=P1^3//电机驱动口
sbiten1=P1^4//电机使能端
sbiten2=P1^5//电机使能端
sbitLSEN=P2^0//光电对管最左
sbitLSEN1=P2^1//光电对管左1
sbitLSEN2=P2^2//光电对管左2
sbitRSEN1=P2^3//光电对管右1
sbitRSEN2=P2^4//光电对管右2
sbitRSEN=P2^5//光电对管最右
uintpwm1=0,pwm2=0,t=0
voiddelay(uintxms)
{
uinta
while(--xms)
{
for(a=123a>0a--)
}
}
voidmotor(ucharspeed1,ucharspeed2)
{
if(speed1>=-100&&speed1<=100)
{
pwm1=abs(speed1)
if(speed1>0)
{
s1=1
s2=0
}
if(speed1==0)
{
s1=1
s2=1
}
if(speed1<0)
{
s1=0
s2=1
}
}
if(speed2>=-100&&speed2<=100)
{
pwm2=abs(speed2)
if(speed2>0)
{
s3=1
s4=0
}
if(speed2==0)
{
s3=1
s4=1
}
if(speed2<0)
{
s3=0
s4=1
}
}
}
voidgo_forward(uintspeed)
{
s1=1
s2=0
s3=1
s4=0
pwm1=speed
pwm2=speed
}
voidgo_back(uintspeed)
{
s1=0
s2=1
s3=0
s4=1
pwm1=speed
pwm2=speed
}
voidstop()
{
s1=1
s2=1
s3=1
s4=1
pwm1=0
pwm2=0
}
voidturn_right(uintP1,uintP2)//右转函数
{
s1=1
s2=0
s3=0
s4=1
pwm1=P1
pwm2=P2
}
voidturn_left(uintP1,uintP2)//左转函数
{
s1=0
s2=1
s3=1
s4=0
pwm1=P1
pwm2=P2
}
voidtracking()
{
if((LSEN1==0)&&(LSEN2==0)&&(RSEN1==0)&&(RSEN2==0))//没有检测到
{
go_forward(100)
}
if((LSEN1==1)&&(LSEN2==0)&&(RSEN1==0)&&(RSEN2==0))//左一检测到
{
turn_left(40,80)//左转右轮》左轮
delay(N)
}
if((LSEN1==0)&&(LSEN2==1)&&(RSEN1==0)&&(RSEN2==0))//左二检测到
{
turn_left(40,60)//左转右轮》左轮
delay(N)
}
if((LSEN1==0)&&(LSEN2==0)&&(RSEN1==1)&&(RSEN2==0))//右一检测到
{
turn_right(60,4)//右转左轮》右轮
delay(N)
}
if((LSEN1==0)&&(LSEN2==0)&&(RSEN1==0)&&(RSEN2==1))//右二检测到
{
turn_right(80,40)//右转左轮》右轮
delay(N)
}
if((LSEN1==1)&&(LSEN2==1))
{
turn_left(0,100)
delay(1000)
}
if((RSEN1==1)&&(RSEN2==1))
{
turn_right(100,0)
delay(1000)
}
}
voidavoidance()
{
}
voidinit()
{
TMOD=0x02//timer0同时配置为模式2,8自动重装计数模式
TH0=156//定时器初值设置100us中断
TL0=156
ET0=1
EA=1
TR0=1//开启总中断
}
voidmain()
{
init()
while(1)
{
tracking()
}
}
voidtimer0()interrupt1//电机驱动提供PWM信号
{
if(t<pwm1)
en1=1
else
en1=0
if(t<pwm2)
en2=1
else
en2=0
t++
if(t>100)
t=0
}
扩展资料
L298N是一种双H桥电机驱动芯片,其中每个H桥可以提供2A的电流,功率部分的供电电压范围是2.5-48v,逻辑部分5v供电,接受5vTTL电平。一般情况下,功率部分的电压应大于6V否则芯片可能不能正常工作。
参考资料来源:百度百科-l298n
#include<reg51.h>#define uchar unsigned char
#define uint unsigned int
sbit PWM11 = P1^0 //motora
sbit PWM12 = P1^1
sbit PWM21 = P1^2 //motorb
sbit PWM22 = P1^3
sbit MC1 = P1^4 //motora enable
sbit MC2 = P1^5 //motorb enable
sbit LED = P1^6 //指示灯
sbit FMQ = P1^7 //蜂鸣器
sbit key_qt = P0^0 //motor2 引脚
sbit key_sph = P0^1 //升速键
sbit key_spl = P0^2 //降速键
sbit limita1 = P0^3 //电机正a限位
sbit limita2 = P0^4 //电机负a限位
sbit limitb1 = P0^5 //电机正b限位
sbit limitb2 = P0^6 //电机负b限位
uchar keyval,cnt=0,cnt1=0,pwm=50,num
uchar m_mode=0 //电机运行模式,1-电机正向;2-电机b正反向;3=电机b反向;4-电机a反向;
bit flag=0 //延时时间到标志
uchar runflag=0 //电机运行标志
void delaynms(uint z)
{
uint i,j
for(i = zi >0i--)
for(j = 110j >0j--)
}
void keychk(void)
{
keyval=0xff
if(key_qt==0)
{
delaynms(5)//消抖
if(key_qt==0) //确定按键按下
{
while(key_qt==0)
keyval=1
}
}
if(!key_sph)
{
delaynms(5)//消抖
if(!key_sph) //确定按键按下
{
while(!key_sph)
keyval=2
}
}
if(!key_spl)
{
delaynms(5)//消抖
if(!key_spl) //确定按键按下
{
while(!key_spl)
keyval=3
}
}
}
void t0isr() interrupt 1
{
TH0=(65536-50000)/256
TL0=(65536-50000)%256
if(runflag==1) //正常运行
{
cnt1++
if(cnt1>=10){cnt1=0LED=~LED}
}
if(runflag==2) //限位延时
{
LED=1
cnt++
if(cnt>=10)
{
flag=1
cnt=0
}
}
}
void t1isr() interrupt 3
{
num++
if(num<pwm)
{
switch(m_mode)
{
case 1:PWM11=1PWM12=0break //a电机正转
case 2:PWM21=1PWM22=0break //b电机正转
case 3:PWM21=0PWM22=1break //b电机反转
case 4:PWM11=0PWM12=1break //a电机反转
default:break
}
}
else if(num>=pwm)
{
PWM11=0PWM12=0PWM21=0PWM22=0
}
if(num>=100)num=0
}
void main(void)
{
bit qt=0
TMOD=0x21
TH0=(65536-50000)/256
TL0=(65536-50000)%256
TH1=236 //改变该值调整PWM频率
TL1=236
TR0=1
TR1=1
ET1=1
ET0=1
EA=1
P1|=0xc0
flag=0
while(1)
{
keychk()
switch(keyval)
{
case 1: qt=~qt
if(qt)
{
runflag=1
switch(m_mode)
{
case 0: m_mode=1 //刚开始启动,置模式1
MC1=1
FMQ=0 //蜂鸣器响一下
delaynms(100)
FMQ=1
break
case 1:MC1=1break //电机a正转
case 2:MC2=1break //电机b正转
case 3:MC2=1break //电机b反转
case 4:MC1=1break //电机a反转
default:m_mode=0break
}
}
if(!qt)
{
MC1=0
MC2=0
LED=1
runflag=0
break
}
break
case 2:pwm+=5if(pwm>100)pwm=100break //升速5个单位
case 3:pwm-=5if(pwm<10)pwm=10break //降速5个单位
default:break
}
if(limita1==0 &&m_mode==1) //电机a正向限位
{
delaynms(1)
if(limita1==0)
{
MC1=0
runflag=2
flag=0
while(flag==0) //等待延时0.5S结束
m_mode=2
runflag=1
MC2=1
}
}
if(limitb1==0 &&m_mode==2) //电机b正向限位
{
delaynms(1)
if(limitb1==0)
{
MC2=0
runflag=2
flag=0
while(flag==0)
qt=0
m_mode=3
}
}
if(limitb2==0 &&m_mode==3) //电机b反向限位
{
delaynms(1)
if(limitb2==0)
{
MC2=0
runflag=2
flag=0
while(flag==0)
m_mode=4
runflag=1
MC1=1
}
}
if(limita2==0 &&m_mode==4) //电机a反向限位
{
delaynms(1)
if(limita2==0)
{
MC1=0
runflag=2
flag=0
while(flag==0)
flag=0
m_mode=0
runflag=0
qt=0
LED=1
}
}
}
}
#include <reg52.h> // 引用标准库的头文件#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//=================电机驱动=====================
sbitdianji_r = P1^0 //右边电机控制口,低电平转?
sbitdianji_l = P1^3 //左边电机控制口,低电平转
//=============循迹感应接口======================
sbitxjmk_r=P3^2// 右边hall模块检测口 INT0
sbitxjmk_l =P3^3// 左边hall模块检测口 INT1
voidcheck_righet()//右边时候检测到stop测试程序
voidcheck_left()//左边时候检测到stop测试程序
void delay_50us(uint t)
void delayms(uint Ms)
uchar r_count//右边传感器检测到的次数计数单元
uchar l_count
uint time
//***********************主程序******************************
main()
{
time=50 dianji_r=0//上电时右侧电机运行
dianji_l=0//上电时左侧电机运行EA=1
EX1=1
EX0=1
IT1=0
IT0=0
xjmk_r=1//置IO为1,准备读取数据
xjmk_l=1
_nop_()
r_count=0
l_count=0
while(1)
{
_nop_()
// check_righet()//调用右边hall检测传感器
// check_left()//
if(r_count>=1)
{
delayms(time)
dianji_r=0
dianji_l=0
r_count=0
_nop_()
}
if(l_count>=1)
{
delayms(time)
dianji_r=0
dianji_l=0
l_count=0
_nop_()
}
}
}
void init0int() interrupt 2
{
l_count=5
dianji_l=1
dianji_r=0
if(r_count>0)
{ EX0=0
delayms(20)
if(time>=20)time-=19
EX0=0
}
return
}
void init1int() interrupt 0
{
r_count=5
dianji_r=1 dianji_l=0
if(l_count>0)
{ EX1=0
delayms(20)
if(time>=20)time-=19
EX1=1}
return } //*******************************************************************************
//函数名称:
//功能:左边边时候检测到stop测试程序
voidcheck_left()
{
if(xjmk_l==0)//检测右边的传感器是否感应到stop
{ delay_50us(1)//延时,去除机械振动
_nop_() if(xjmk_l==0)//再次检测
{ delay_50us(1)//延时,去除机械振动
if(xjmk_l==0) {
l_count++
xjmk_l=1 }
}
}
} //******************************************************************************* //函数名称:
//功能:右边时候检测到stop测试程序
voidcheck_righet()
{
if(xjmk_r==0)//检测右边的传感器是否感应到stop {
delay_50us(1)//延时,去除机械振动
if(xjmk_r==0)//再次检测
{
delay_50us(1)//延时,去除机械振动 if(xjmk_r==0)
{
r_count++
xjmk_r=1
}
}
}
//*******************************************************************************
//函数名称:void delay_50US(unsigned int t)
//功能:延时50*t(us)
void delay_50us(uint t)
{
uchar j
for(t>0t--)
{
for(j=19j>0j--)
}
}
/*====================================================================
设定延时时间:x*1ms ====================================================================*/
void delayms(uint Ms)
{
uint i,TempCyc
for(i=0i<Msi++)
{
TempCyc =70
while(TempCyc--)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)