问关于四轴控制时间周期的问题。(已解决)
本帖最后由 fengyiyu1006 于 2012-10-16 11:43 编辑请问轴友们:
最近在做一个三轴6电机,控制周期上遇到了问题,请问四轴控制的周期一般多少合适啊?
我在学校做智能车时学校提供例程,里面是用5ms的定时中断精确循环,于是我受到启发,在写程序时主函数是一个中断级别较低的接收机解码程序,然后用systick的高级别定时中断实现其他控制,另有最高级别的中断用于加速度计自由落体中断等。
程序一块一块的写,刚开始没问题,但是当几块和在一起时,发现解码程序根本不执行了,用示波器看了一下,由于我的四个传感器全是iic接口,又用的是模拟iic,导致一个single_read()函数都需要执行283.33us,每个传感器数据读取平局耗时7.06ms,总共28.23ms。有点小担心啊,还计划用5ms中断,连一个传感器都读不完,跟别说后面的数据融合和控制了。
加速度计是BMA020,陀螺仪是MPU3050,电子罗盘HMC5883L,气压计BMP085 。
如果这样长的时间能保证控制精度的话,我就继续往下写,不然就要想办法精简算法了,后面的数据融合和控制算法都用的很庞大的东西。
{:2_31:} 等高手指点啊》》》。。。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
问题已经解决:
程序主要是iic读数据用的时间太长,后来检查时一句一句的读,其他的都注释掉,然后用示波器看时间,终于找到病因了。
在读取BMP085的气压和温度的两个小函数里有长达5ms的延时,以前是为了保证读数准确,写飞控就直接拷过来了,注释掉后发现无影响,现在肉眼观察iic几乎不占时间。
谢之前几位网友的提示指点。
"每个传感器数据读取平局耗时7.06ms"
感觉太久了
不知是使用什么MCU?
目前STM32 400Hz取样加算法还很OK john800422 发表于 2012-10-16 01:20 static/image/common/back.gif
"每个传感器数据读取平局耗时7.06ms"
感觉太久了
不知是使用什么MCU?
用的确实是stm32f103rbt6,主要是模拟iic中的delay函数太多,用硬件iic的话感觉太麻烦,之前潜水听大家说stm32的硬件iic比较难搞
400Hz的话周期是2毫秒多,看来程序有问题,我再改改
{:3_48:} 谢了 IIC延时可以适当减少甚至去掉 40342zz 发表于 2012-10-16 11:22 static/image/common/back.gif
IIC延时可以适当减少甚至去掉
我觉得可能是某些细节地方设置不对,现在函数是这样子的:
void I2C_delay(void)
{
__nop(); __nop();
}
已经很简单了,但是还是那个问题,我正在检查...
另外模拟iic程序是淘宝买东西附带的,百度也有:(能读数,就是太慢,我正在看时钟配置对不对)
bool I2C_Start(void)
{
SDA_H;
SCL_H;
I2C_delay();
if(!SDA_read)return FALSE; //SDA线为低电平则总线忙,退出
SDA_L;
I2C_delay();
if(SDA_read) return FALSE; //SDA线为高电平则总线出错,退出
SDA_L;
I2C_delay();
return TRUE;
}
void I2C_Ack(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
void I2C_NoAck(void)
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
bool I2C_WaitAck(void) //返回为:=1有ACK,=0无ACK
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
SCL_L;
I2C_delay();
return FALSE;
}
SCL_L;
I2C_delay();
return TRUE;
}
void I2C_SendByte(u8 SendByte) //数据从高位到低位
{
u8 i=8;
while(i--)
{
SCL_L;
I2C_delay();
if(SendByte&0x80)
SDA_H;
else
SDA_L;
SendByte<<=1;
I2C_delay();
SCL_H;
I2C_delay();
}
SCL_L;
}
unsigned char I2C_RadeByte(void) //数据从高位到低位
{
u8 i=8;
u8 ReceiveByte=0;
SDA_H;
while(i--)
{
ReceiveByte<<=1;
SCL_L;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
ReceiveByte|=0x01;
}
}
SCL_L;
return ReceiveByte;
}
bool Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data)
{
if(!I2C_Start())return FALSE;
I2C_SendByte(SlaveAddress); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
I2C_SendByte(REG_Address ); //设置低起始地址
I2C_WaitAck();
I2C_SendByte(REG_data);
I2C_WaitAck();
I2C_Stop();
delay5ms();
return TRUE;
}
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{ unsigned char REG_data;
if(!I2C_Start())return FALSE;
I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop();test=1; return FALSE;}
I2C_SendByte((u8) REG_Address); //设置低起始地址
I2C_WaitAck();
I2C_Start();
I2C_SendByte(SlaveAddress+1);
I2C_WaitAck();
REG_data= I2C_RadeByte();
I2C_NoAck();
I2C_Stop();
//return TRUE;
return REG_data;
} 告诉你个秘密你下的程序是用在51上的{:titter:}51两个空指令2usSTM32是多少?目测WaitAck等待时间也太短用硬件仿真或者示波器看看吧 40342zz 发表于 2012-10-16 11:38 static/image/common/back.gif
告诉你个秘密你下的程序是用在51上的51两个空指令2usSTM32是多少?目测WaitAck等待时间 ...
嗯,这个在stm32上也能用,这里的__nop();不追求准确,只是为了小延时一下,经测试传感器数据读取正常。另外的延时函数也是用的这个(systick中断用作控制周期定时了),那里我就是用示波器调的,还是挺准的。 用硬件吧,没什么问题,一直用。 enthier 发表于 2012-10-16 14:10 static/image/common/back.gif
用硬件吧,没什么问题,一直用。
开始时试了一下,一是不会,学一句,写一句;另外中断太多,配置的iic不运行。 fengyiyu1006 发表于 2012-10-16 22:40 static/image/common/back.gif
开始时试了一下,一是不会,学一句,写一句;另外中断太多,配置的iic不运行。 ...
可以是看我之前改写的
http://www.amobbs.com/thread-5492852-1-1.html
下面有完整测试程序
或许会有帮助 40342zz 发表于 2012-10-16 11:38 static/image/common/back.gif
告诉你个秘密你下的程序是用在51上的51两个空指令2usSTM32是多少?目测WaitAck等待时间 ...
等待时间确实不够,已经改成5次i--循环了 果断用硬件I2CDMA方式读取
直接无视采样时间,控制周期就看你自己随便了 __@ 发表于 2012-10-17 12:08 static/image/common/back.gif
果断用硬件I2CDMA方式读取
直接无视采样时间,控制周期就看你自己随便了
嗯,正在尝试
前面有“john800422 ”的代码范例,我正在学习
页:
[1]