从零开始做基于51的循迹小车-Day2-利用PWM调速!

文章目录

概要

昨天我们让小车的四个电机转了起来,今天来利用pwm对电机进行调速。

对PWM的理解

让蓝线递增,比红线高的部分直接转化为高电平,低的则为低电平。基本原理就是一个周期内,通电的时间越多,最终呈现出来的效果就是电机就转的越快,这可以抽象为一个重要参数--占空比,占空比越大,也就是说一个周期内通电越多,电机转的越快。

这里还要用到L298N的ENA和ENB口,基本原理如图:

也就是说给ENA口赋值1,就相当于打开了OUT口,电机就会根据相应的指令转动,赋值0,OUT口则关闭,不管IN口是什么指令电机都会停止转动;

代码细节

#include <REGX52.H>
#include "motor.h"
void Timer0Init(void);
sbit EN1A=P0^2;//前轮
sbit EN1B=P0^7;//前轮
sbit EN2A=P3^2;//后轮
sbit EN2B=P3^7;//后轮

unsigned int counter1,speed;

void Timer0Init(void)		//100微秒@11.0592MHz
{
	
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |=0x01; 		//设置定时器模式
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	ET0=1;   //定时器0中断允许开关 
	EA=1;     //定时器总开关
	PT0=0;    //定时器0中断优先级
}
void Timer0_Routine()  interrupt 1
{
		TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	
	counter1++;
	counter1%=100;
	if(counter1<speed)
	{
	EN1A=1;
	EN1B=1;
	EN2A=1;
	EN2B=1;
	}
	else
	{
	EN1A=0;
	EN1B=0;
	EN2A=0;
	EN2B=0;
	}
	
}

代码中有两个重要参数,一个是counter1,另一个是speed,让counter1递增,也就是上面图中递增的蓝线,红线就是speed,这里的周期就是100um×100。占空比在这就为speed/100,也就是说speed越大,电机转速则越快,调速的效果就达到啦!

每日小结

今天主要是代码,调试中也出现了一些问题,有个别轮子会不动,可能是接马达的电线接口接触不良,于是重新换了一根线,重新焊上去了。明天继续加油!!!

51单片机控制的循迹小车调速通常涉及到PID(比例积分微分)控制器的使用,因为这可以帮助车辆精确地跟随轨迹。以下是一个简单的示例,假设我们有两路电机分别通过PWM信号控制速度: ```c #include "reg52.h" #include "pwm.h" #define MAX_SPEED 255 // 最大电机速度 void track_follow(int target_pos) { int error = target_pos - current_position; // 计算误差 float proportional = error * kP; // 比例部分 float integral = integral_term + error * kI; // 积分部分 float derivative = (error - last_error) / dt; // 微分部分 float total_speed = proportional + integral + derivative; if(total_speed > MAX_SPEED) { motor1_speed = MAX_SPEED; motor2_speed = MAX_SPEED; } else if(total_speed < -MAX_SPEED) { motor1_speed = -MAX_SPEED; motor2_speed = -MAX_SPEED; } else { motor1_speed = MAX_SPEED * (total_speed + MAX_SPEED); motor2_speed = MAX_SPEED * (-total_speed + MAX_SPEED); // PWM值反向控制另一路电机 } // 更新PID参数和上一帧的误差 integral_term += error * kI; last_error = error; } // 初始化函数 void init_track_follow() { // 初始化PID常数kP、kI等 // 开启PWM模块 pwm_init(); } int main(void) { init_track_follow(); while(1) { track_follow(some_sensor_data); // 根据传感器数据更新目标位置 delay_ms(10); // 等待一段时间再处理下一个位置 } return 0; } ``` 注意:这个例子假设你已经有一个PID库或者自定义了PID计算的部分,并且你需要替换`some_sensor_data`为实际的传感器测量值(如红外循迹传感器读取的结果)。同时,具体的硬件连接也需要相应设置。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值