我想通过MPU6050角度传感器来实现改变不同的角度从而控制舵机不同角度的转动,但在实际操作中遇到了问题,请各位大神指点。
在不加MPU6050时单独通过按键控制舵机没有问题,单独测试MPU6050得到的角度也没有问题。
把他们写到一块就有问题了。我通过示波器发现是中断时舵机的周期有问题。
定时器每隔20ms进一次中断,经测试,程序中的中断时间没有问题。舵机的周期也确实是20ms,我单独给2ms高电平,18ms低电平,也完全没有问题。
但是在中断中我通过给一个for循环来控制舵机的高电平就开始出现问题了。for循环中a是我通过MPU6050得到的角度换算的一个值,通过改变a来实现高电平的不同时间。一但加入这个for循环后,舵机的周期立刻从原来的20ms变为220ms左右,我没搞懂为什么会这样变化,请各位大神给我点指点、建议,谢谢。
#include<STC12C5A60S2.h>
#include<math.h>
#include<stdio.h>
#include<INTRINS.H>
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
signed int a;
/********功能模块头文件**********/
#include"MPU6050.h"
#include"lcd1602.h"
//******角度参数************
float Accel_ax;
float Accel_ay;
float Accel_az; //X轴加速度值暂存
float Angle; //小车最终倾斜角度
//******产生PWM参数************
sbit pwm = P2^2;
//*********************************************************
//延时
//*********************************************************
void delay10us(unsigned char a)//每10微秒误差-0.234375us
{
unsigned char b,c;
for(b=a;b>0;b--)
for(c=2;c>0;c--);
}
void Delay100us() //@11.0592MHz
{
unsigned char i, j;
i = 2;
j = 15;
do
{
while (--j);
} while (--i);
}
void Delay2ms() //@11.0592MHz
{
unsigned char i, j;
i = 22;
j = 128;
do
{
while (--j);
} while (--i);
}
//*********************************************************
// 倾角计算
//*********************************************************
float Angle_Calcu(void)
{
// Accel_ax = GetData(ACCEL_XOUT_H); //读取X轴加速度
Accel_ay = GetData(ACCEL_YOUT_H); //读取Y轴加速度
Accel_az = GetData(ACCEL_ZOUT_H); //读取z轴加速度
// Angle = (int)(atan(Accel_ax/Accel_az)*180/3.14); //读取XZ平面角度
// Angle = (int)(atan(Accel_ax/Accel_ay)*180/3.14); //读取XY平面角度
Angle = (int)(atan(Accel_ay/Accel_az)*180/3.14); //读取YZ平面角度
Angle=(int)(Angle+90.0);
if(30<=(int)Angle<=90)
{
Angle=0.0029*Angle*Angle+1.1795*Angle-39.3514; //实际角度值
}
else if(90<(int)Angle<=180)
{
Angle=(-0.0029)*Angle*Angle+2.2359*Angle-87.741;
}
return Angle;
}
//*********************************************************
//定时器0初始化
//*********************************************************
void Timer0_Init(void) //100微秒11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0xB8; //设置定时初值
EA = 1; //开总中断
ET0 = 1; //开T0中断
TR0 = 1; //定时器0开始计时
}
//*********************************************************
//定时器0中断 //问题主要出在这一块,但我没想到什么好的方法,请各位大神给予指点,谢谢。
//*********************************************************
void Timer0(void)interrupt 1
{
TL0 = 0x00; //设置定时初值
TH0 = 0xB8; //设置定时初值
pwm = 1;
for(;a>0;a--)
{
Delay100us();
}
// Delay2ms();
pwm = 0;
}
//*********************************************************
//主函数
//*********************************************************
void main()
{
float jiaodu_1;
int sj_jiaodu_1;
delay(500); //上电延时
InitMPU6050(); //初始化MPU6050
InitLcd(); //液晶初始化
delay(150);
Timer0_Init();
pwm = 0;
while(1)
{
jiaodu_1=Angle_Calcu();
sj_jiaodu_1 = (int)(0.00001*jiaodu_1*jiaodu_1+0.2021*jiaodu_1+4.7779);
a = (int)(0.64*sj_jiaodu_1+29);
lcd_printf(dis,jiaodu_1); //转换数据显示
DisplayListChar(2,0,dis,4);
// DelayMS(100);DelayMS(100);DelayMS(100);DelayMS(100);DelayMS(100);DelayMS(100);
// DelayMS(10);
delay(1000);
}
}
|