下面是我写的.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调速的内容。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)