51单片机直流电机调速

51单片机直流电机调速,第1张

第一:你这个不是电机调速的,用外部中断是测速的呀。

下面是我写的.PID部分的代码就不给了,想加的话,自己找可以了

#include <AT89X52.H>

#include "common.h"

#define _WHEEL_C_

#define Left_moto_pwm P1_5

#define Right_moto_pwm P1_4

#define Left_moto_go {IN1=0,IN2=1}

#define Left_moto_back{IN1=1,IN2=0}

#define Right_moto_go {IN3=1,IN4=0}

#define Right_moto_back {IN3=0,IN4=1}

sbit IN1=P1^0

sbit IN2=P1^1

sbit IN3=P1^2

sbit IN4=P1^3

unsigned char pwm_val_left=0

unsigned char push_val_left=0

unsigned char pwm_val_right=0

unsigned char push_val_right=0

float L_Count=0,R_Count=0

unsigned int TimerNum=0,SYS_TimeNum=0

float Save_L_Distance=0,Save_R_Distance=0,Left_Speed=0,Right_Speed=0

unsigned char Left_point=0,Right_point=0

unsigned char sys_1ms=0,sys_1s=0,TurnFlag=0

//初始化PWM调速函数

void Init_Wheel()

{

TMOD = 0x01

TH0 = 0x0FF

TL0 = 0x0A4

EA = 1

ET0 = 1

TR0 = 1

}

void Init_WheelSpeedInter()

{

IT0=1//INT0下降沿中断

EX0=1//允许INT1中断

IT1=1//INT1下降沿中断

EX1=1//允许INT1中断

EA=1

}

//得到上一次0.5秒的行驶距离

float GetLeftWheelMileage()

{

return Save_L_Distance

}

//得到上一次0.25秒的行驶距离

float GetRightWheelMileage()

{

return Save_R_Distance

}

void Inter_Left(void) interrupt 0

{

L_Count++

}

void Inter_Right(void) interrupt 2

{

R_Count++

}

//小车向前函数

void Wheel_Run(char left_val,char right_val)

{

push_val_left=left_val

push_val_right=right_val

Left_moto_go

Right_moto_go

}

//小车后退函数

void Wheel_Back(char left_val,char right_val)

{

push_val_left=left_val

push_val_right=right_val

Left_moto_back

Right_moto_back

}

//小车停止函数

void Wheel_Stop(void)

{

Wheel_Run(0,0)

}

//左轮PWM调速函数

void pwm_out_left_moto(void)

{

if(pwm_val_left>200)

{

pwm_val_left=0

}else

{

if(pwm_val_left<=push_val_left)

{

Left_moto_pwm=1

}

else

{

Left_moto_pwm=0

}

}

}

//右轮调速函数

void pwm_out_right_moto(void)

{

if(pwm_val_right>200)

{

pwm_val_right=0

}else

{

if(pwm_val_right<=push_val_right)

{

Right_moto_pwm=1

}

else

Right_moto_pwm=0

}

}

//PWM调速中断(TIMER0--工作方式1)

void Wheel_Interrupt(void) interrupt 1

{

TH0 = 0x0FF

TL0 = 0x0A4

TimerNum++

if(TimerNum>=2500)

{

//左右轮速度cm/s

Left_Speed=4*L_Count

Right_Speed=4*R_Count

//左右轮0.25秒行驶距离

Save_L_Distance+=L_Count

Save_R_Distance+=R_Count

//数据发送到串口图示

DataScope_Get_Channel_Data(L_Count, 1 ) //将数据 1.0 写入通道 1

DataScope_Get_Channel_Data(R_Count, 2 ) //将数据 2.0 写入通道 2

Send_Count = DataScope_Data_Generate(2)//生成10个通道的 格式化帧数据,返回帧数据长度

for( DateNum = 0 DateNum <Send_CountDateNum++) //循环发送,直到发送完毕

{

SendByte(DataScope_OutPut_Buffer[DateNum])

}

TimerNum=0

L_Count=0

R_Count=0

}

pwm_val_left++

pwm_val_right++

pwm_out_left_moto()

pwm_out_right_moto()

}

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

既然是技巧的话那就不提供详细的代码了,首先要看你这个小车是几轮几驱动的,首先假设你只用一个L298n驱动板的话,那么再假设只含左右两个轮,只对左右两个轮进行控制的话,那么就简单了,首先你要知道L298N驱动板怎么用,不同的驱动板功能都不一定相同,不过控制引脚一般来说都是4根,可以控制两个直流电机的正反转,同时还有两个PWM接口,可以控制两个电机的转速。

假设4个控制引脚分为A1、A2和B1、B2,A1、A2控制第一个直流电机,B1、B2控制第二个直流电机,当A1和A2接不同方向的电流后直流电机会正转或反转,同理B1和B2也是一样。PWM是通过控制占有率来控制电机速度的,即控制高电平和低电平的时间的,不同,这样在规定时间内,如果高电平的时间占有比例越高则电机转速越快,输出功率越高。

知道以上内容了那么之后的内容就更容易理解了

前进:两个直流电机朝正方向同时转动即可

后退:两个直流电机朝反方向同时转动即可

原地左转:类似原地打转,只需让两个电机一个正转一个反转即可,即左转为左边电机反转,右边电机正转

原地右转:与原地左转相反即可

固定轮转:固定左边令右侧轮前进即可实现固定轮转向的目的,例如左转的话令左边电机停止,右侧电机正向转动即可,向右转的话与左转相反。

至于keil程序,这个要根据具体的硬件来写,别人的无法通用,不过这些都不难,只要原理弄懂了,稍微花一点儿时间还是能很容易写出来的,先从控制电机的转向开始。别人的程序的话可能会越看越难理解,还是自己动手比较好,先不考虑调速的情况下完成了之后再去看看有关PWM调速的内容。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7738754.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-09
下一篇 2023-04-09

发表评论

登录后才能评论

评论列表(0条)

保存