51小四轴制作之飞行姿态与PWM

四轴飞行器飞行的原理就是通过改变四个电机转速改变飞行器当前的飞行状态,而飞行器在空间中具有六个状态:垂直运动、俯仰运动、横滚运动、偏航运动。要实现这些飞行状态就需要对四轴飞行器每个电机的转速进行调整,这里的调整就用到了PWM(脉冲宽度调制)。

  • 飞行姿态

这里参考了这篇博客,讲的很详细
https://blog.csdn.net/qq_25005909/article/details/76512369

由于在飞行时如果螺旋桨同向转动,四轴飞行器会受到转动力矩的作用不利于我们控制飞行器,所以采用了两对相反的螺旋桨并且电机反向转动,这样可以平衡力矩,达到稳定飞行。
也就是图中1和3是正向螺旋桨逆时针运动,2和4是反向螺旋桨顺时针运动。
51小四轴制作之飞行姿态与PWM_第1张图片
1.垂直运动:所有电机同时提高相同的转速将飞行器上升。
2.俯仰运动:控制其中两个电机转速,也就是1的转速提高而3的转速减少,这样飞行器会向x轴方向仰起并且向x轴运动,如果要想后仰起移动只需要1的转速减少3的转速升高即可。
3.横滚运动:和俯仰运动类似,只是改变的是2和4电机,向侧方向翻转并且移动。
4.偏航运动:通过反扭力实现四轴飞行器的旋转,之前通过旋翼的转向的配置抵消了力矩,而现在要实现四轴飞行器方向的偏转需要通过力矩产生一个扭力,也就是需要其中两个同向电机转速减少,另外两个电机转速提高,比如1和3转速增加、2和4转速减少即可发生偏航运动。
5.前后运动
要想实现飞行器在水平面内前后、左右的运动,必须在水平面内对飞行器施加一定的力。在图e中,增加电机3转速,使拉力增大,相应减小电机1转速,使拉力减小,同时保持其它两个电机转速不变,反扭矩仍然要保持平衡。按图b的理论,飞行器首先发生一定程度的倾斜,从而使旋翼拉力产生水平分量,因此可以实现飞行器的前飞运动。向后飞行与向前飞行正好相反。当然在图b图c中,飞行器在产生俯仰、翻滚运动的同时也会产生沿x、y轴的水平运动。
6.侧向运动
在图f中,由于结构对称,所以侧向飞行的工作原理与前后运动完全一样。 总得来说就是控制四个电机的速度了。然后相应的提高速度和减慢速度就可以让四轴动起来了。

  • PWM

PWM波输出模块,首先下手PWM模块是因为这个模块直接控制电机的运转,再配合无线传输就可以简单地控制四轴飞行器,这样就可以在完成硬件后第一时间检测硬件功能是否正常,在最开始将可能故障排查就能使后续地工作更加顺畅。
PWM波是通过控制占空比,即高电平在一个周期内所占的比例,来控制电机的转速的。那我就要做一个函数,输入4个值控制4个电机的转速,而这4个值就是分别控制四个PWM输出口输出占空比的。而要控制占空比也就是要求在一个周期内高电平所占的比例,那就需要计算占空比。虽然理解了占空比,但是计算以及在程序中体现稍显麻烦。

  • PWM的概念及如何控制转速
    PWM即是宽度脉冲调制,是一种微处理器形成数字信号控制模拟电路的技术,具体就是产生一个方波,为什么要用这个PWM来控制转速呢。首先控制转速可以调节电流的大小,但这样不容易由单片机控制,但是可以用另一种方法来达到调速的作用,给电机工作一会停一会,就像我们骑自行车可以用比较小的力气一直地蹬,也可以每隔一会猛踩一会然后让自行车自己滑动,两种方法实际的平均速度都是一样的。所以这个PWM控制电机转速也就是后者,PWM信号传给电子调速器,而这个信号就是一种方波,就是一段高位低位交替的波形,当这个信号传给电调用于控制时,高位被称为高电平,低位被称为低电平,当处在高电平时电机会转动而低电平时电机不工作,由于间隙很短,这样就控制了电机的转速。所以这里引入了一个概念叫做“占空比”,就是指在一个脉冲循环内,通电时间相对于总时间所占的比例,通过调节这个占空比就能调节转速,这就是单片机控制电机转速的方式。
    51小四轴制作之飞行姿态与PWM_第2张图片

  • PWM占空比计算
    8位的PWM的话,每个周期里要分为256个小脉冲,占空比就是这256个脉冲里的高电平占这个整个256个电平的比例
    8位PWM的周期 = 计数脉冲周期×256
    8位PWM的频率 = 计数脉冲频率/256
    8位PWM的脉宽时间(高电平时间)= 计数脉冲周期×(256-CCAPnL)
    8位PWM的占空比 = 脉宽时间/PWM周期 = (1- CCAPnL/256) ×100%
    单片机中计数器和定时器采用的是脉冲计数,脉冲就是低电平转变为高电平的这个过程,也就是上升沿,而计时器是记录机器内部的脉冲个数再换算成时间,对于51单片机来说一个计数脉冲周期就是1us,也就是一个机器周期。8位PWM的周期就是计时器记录256次脉冲的时间,占空比就是在这个周期内记录的脉冲个数除以总的脉冲数256。

  • PWM在单片机程序中的体现
    在STC15W4K32S4中PWM输出模块自带两个内部15位计时器,T1、T2,这两个个计时器也就是定时器,可以通过编程设定时间实现定时。

    而在程序中PWM占空比的控制即是通过调整波形翻转的间隔达到的,这个时间间隔就由这两个定时器来控制,T1控制低电平翻转成高电平的时间节点,T2控制高电平翻转成低电平的时间节点。

    总的流程:系统内部时钟计时,然后两个定时器定时,当内部时钟的值与T1设定的值相等时,由低电平翻转成高电平,接下来持续输出高电平波形;当内部时钟的值达到T2设定的值时,由高电平翻转成低电平。当内部时钟计完一个周期后再将内部时钟重置继续输出这个波形。

    作用:通过设定翻转的时间节点调整波形处于高电平的时间,也就是控制了一个周期内的脉冲宽度,也就是控制了占空比。所以叫做脉冲宽度调制PWM。

  • 相应代码分析
    PWM模块主要分为两个函数,一个是PWM模块的初始化,基本上是搬过来的,所有的寄存器设置方式在数据手册上都有,这里比较关键的操作是设置每个PWM输出口内部时钟T1和T2的定时时间。在初始化时定义好T2的数值,这个T2定时的长度就相当于一个周期的长短。像是这里定义的是1001,一个周期就相当于1ms。
    另一个则是改变4个PWM输出口输出的PWM波形,改变T1的定时时间,就相应地改变了高电平的时间也就是脉冲的宽度。
    联系公式,不难看出,T2-T1的时间即是高电平的时间,而一个周期即为1ms,占空比就是(T2-T1)/T2。

void PWM_INIT()
{
	int i=1;
	//所有I/O口全设为准双向,弱上拉模式
	P0M0=0x00;
	P0M1=0x00;
	P1M0=0x00;
	P1M1=0x00;
	P2M0=0x00;
	P2M1=0x00;
	P3M0=0x00;
	P3M1=0x00;
	P4M0=0x00;
	P4M1=0x00;
	P5M0=0x00;
	P5M1=0x00;
	P6M0=0x00;
	P6M1=0x00;
	P7M0=0x00;
	P7M1=0x00;
	/*设置需要使用的PWM输出口为强推挽模式
	用到的PWM包含的端口都在为P2和P3所以
	只需要将这两个端口设置即可
	*/
	P2M0=0x0e;
	P2M1=0x00;
	P3M0=0x80;
	P3M1=0x00;
	
    //PWM控制寄存器
	P_SW2=0x80;    //最高位置1才能访问和PWM相关的特殊寄存器

	//PWM配置寄存器
  PWMCFG=0xb0;    //7位    6位                5位    4位    3位    2位    1位    0位
	                //置0  1-计数器归零触发ADC C7INI  C6INI  C5INI  C4INI  C3INI  C2INI
	                //     0-归零时不触发ADC       (值为1时上电高电平,为0低电平)
    //PWM时钟选择寄存器
	PWMCKS=0x10;    //7位6位5位    4位             3位    2位    1位    0位
	                //   置0    0-系统时钟分频          分频参数设定
	                //          1-定时器2溢出       时钟=系统时钟/([3:0]+1)
    //PWM中断标志寄存器
	PWMIF=0x00;     //7位    6位                5位    4位    3位    2位    1位    0位
                  //置0  计数器归零中断标志            相应PWM端口中断标志
    //PWM外部异常控制寄存器
	PWMFDCR=0x00;   //7位    6位       5位                4位
	                //置0    置0 外部异常检测开关  外部异常时0-无反应 1-高阻状态
	                //3位             2位                 1位                0位
                  //PWM异常中断  比较器与异常的关系   P2.4与异常的关系  PWM异常标志
    //PWM计数器
    PWMCH=0x03;     //15位寄存器,决定PWM周期,数值为1-32767,单位:脉冲时钟
    PWMCL=0xe9;

// 以下为每个PWM输出口单独设置
	PWM2CR=0x00;    //7位6位5位4位   3位      2位       1位        0位
	                //    置0      输出切换 中断开关 T2中断开关 T1中断开关
	PWM3CR=0x00;
	PWM4CR=0x00;
	PWM5CR=0x00;

	PWM2T1H=0x03;          //15位寄存器第一次翻转计数  第一次翻转是指从低电平翻转到高电平的计时
	PWM2T1L=0xe8;
	PWM2T2H=0x03;          //15位寄存器第二次翻转计数  第二次翻转是指从高电平翻转到低电平的计时
	PWM2T2L=0xe9;          //第二次翻转应比精度等级要高,否则会工作不正常,比如精度1000,第二次翻转就必须小于1000
/*
	PWM占空比的控制即是通过调整波形翻转的间隔达到的,这个时间间隔由两个定时器来控制,T1控制低电平翻转成高电平的时间
	节点,T2控制高电平翻转成低电平的时间节点。
	总的流程:系统内部时钟计时,然后两个定时器定时,当内部时钟的值与T1设定的值相等时,由低电平翻转成高电平,接下来持续
	输出高电平波形;当内部时钟的值达到T2设定的值时,由高电平翻转成低电平。当内部时钟计完一个周期后再将内部时钟重置继续
	输出这个波形。
	作用:通过设定翻转的时间节点调整波形处于高电平的时间,也就是控制了一个周期内的脉冲宽度,也就是控制了占空比。所以叫做
	脉冲宽度调制PWM。
*/
	PWM3T1H=0x03;
	PWM3T1L=0xe8;
	PWM3T2H=0x03;
	PWM3T2L=0xe9;

	PWM4T1H=0x03;
  PWM4T1L=0xe8;
	PWM4T2H=0x03;
	PWM4T2L=0xe9;

	PWM5T1H=0x03;
	PWM5T1L=0xe8;
	PWM5T2H=0x03;
	PWM5T2L=0xe9;
//以上为每个PWM输出口单独设置

  PWMCR=0x8f;     //7位          6位                5位 4位 3位 2位 1位 0位     10001111
	                //PWM开关 计数归零中断开关   相应I/O为GPIO模式(0)或PWM模式(1)

}


/*
这个函数是用来给T1定时器设定数值的,由每个定时器具有15位,
因为上面设定的T2值为1001(相当于在T2设定的时间结束),所
以我们的一个周期就是计时器计到1000。
设定了T1的数值,就是设定了开始转变为高电平的时间,T2-T1的
时间即是高电平的宽度。
本函数输入的4个值取值范围为0-1000 1000电机停,0转速最高,
*/
void PWM(int p1,int p2,int p3,int p4)
{
    PWM2T1H = p1 >> 8;
    PWM2T1L = p1;

    PWM3T1H = p2 >> 8;
    PWM3T1L = p2;

    PWM4T1H = p3 >> 8;
    PWM4T1L = p3;

    PWM5T1H = p4 >> 8;
    PWM5T1L = p4;
}```

你可能感兴趣的:(51小四轴制作之飞行姿态与PWM)