搜索
bottom↓
回复: 12

问关于四轴控制时间周期的问题。(已解决)

[复制链接]

出0入0汤圆

发表于 2012-10-15 23:14:42 | 显示全部楼层 |阅读模式
本帖最后由 fengyiyu1006 于 2012-10-16 11:43 编辑

请问轴友们:
    最近在做一个三轴6电机,控制周期上遇到了问题,请问四轴控制的周期一般多少合适啊?
    我在学校做智能车时学校提供例程,里面是用5ms的定时中断精确循环,于是我受到启发,在写程序时主函数是一个中断级别较低的接收机解码程序,然后用systick的高级别定时中断实现其他控制,另有最高级别的中断用于加速度计自由落体中断等。
    程序一块一块的写,刚开始没问题,但是当几块和在一起时,发现解码程序根本不执行了,用示波器看了一下,由于我的四个传感器全是iic接口,又用的是模拟iic,导致一个single_read()函数都需要执行283.33us,每个传感器数据读取平局耗时7.06ms,总共28.23ms。有点小担心啊,还计划用5ms中断,连一个传感器都读不完,跟别说后面的数据融合和控制了。
    加速度计是BMA020,陀螺仪是MPU3050,电子罗盘HMC5883L,气压计BMP085 。

    如果这样长的时间能保证控制精度的话,我就继续往下写,不然就要想办法精简算法了,后面的数据融合和控制算法都用的很庞大的东西。

    等高手指点啊》》》。。。


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
问题已经解决:
    程序主要是iic读数据用的时间太长,后来检查时一句一句的读,其他的都注释掉,然后用示波器看时间,终于找到病因了。
    在读取BMP085的气压和温度的两个小函数里有长达5ms的延时,以前是为了保证读数准确,写飞控就直接拷过来了,注释掉后发现无影响,现在肉眼观察iic几乎不占时间。
    谢之前几位网友的提示指点。

   

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2012-10-16 01:20:33 | 显示全部楼层
"每个传感器数据读取平局耗时7.06ms"
感觉太久了
不知是使用什么MCU?
目前STM32 400Hz取样加算法还很OK

出0入0汤圆

 楼主| 发表于 2012-10-16 10:05:45 | 显示全部楼层
john800422 发表于 2012-10-16 01:20
"每个传感器数据读取平局耗时7.06ms"
感觉太久了
不知是使用什么MCU?

    用的确实是stm32f103rbt6,主要是模拟iic中的delay函数太多,用硬件iic的话感觉太麻烦,之前潜水听大家说stm32的硬件iic比较难搞
   400Hz的话周期是2毫秒多,看来程序有问题,我再改改
    谢了

出0入0汤圆

发表于 2012-10-16 11:22:33 | 显示全部楼层
IIC延时可以适当减少甚至去掉

出0入0汤圆

 楼主| 发表于 2012-10-16 11:29:51 | 显示全部楼层
40342zz 发表于 2012-10-16 11:22
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;

}

出0入0汤圆

发表于 2012-10-16 11:38:53 | 显示全部楼层
告诉你个秘密  你下的程序是用在51上的  51两个空指令2us  STM32是多少?  目测WaitAck等待时间也太短  用硬件仿真或者示波器看看吧

出0入0汤圆

 楼主| 发表于 2012-10-16 11:46:41 | 显示全部楼层
40342zz 发表于 2012-10-16 11:38
告诉你个秘密  你下的程序是用在51上的  51两个空指令2us  STM32是多少?  目测WaitAck等待时间 ...

    嗯,这个在stm32上也能用,这里的__nop();不追求准确,只是为了小延时一下,经测试传感器数据读取正常。另外的延时函数也是用的这个(systick中断用作控制周期定时了),那里我就是用示波器调的,还是挺准的。

出0入0汤圆

发表于 2012-10-16 14:10:38 | 显示全部楼层
用硬件吧,没什么问题,一直用。

出0入0汤圆

 楼主| 发表于 2012-10-16 22:40:25 | 显示全部楼层
enthier 发表于 2012-10-16 14:10
用硬件吧,没什么问题,一直用。

    开始时试了一下,一是不会,学一句,写一句;另外中断太多,配置的iic不运行。

出0入0汤圆

发表于 2012-10-17 00:37:37 | 显示全部楼层
fengyiyu1006 发表于 2012-10-16 22:40
开始时试了一下,一是不会,学一句,写一句;另外中断太多,配置的iic不运行。 ...

可以是看我之前改写的
http://www.amobbs.com/thread-5492852-1-1.html
下面有完整测试程序

或许会有帮助

出0入0汤圆

 楼主| 发表于 2012-10-17 12:01:56 | 显示全部楼层
40342zz 发表于 2012-10-16 11:38
告诉你个秘密  你下的程序是用在51上的  51两个空指令2us  STM32是多少?  目测WaitAck等待时间 ...

等待时间确实不够,已经改成5次i--循环了

出0入0汤圆

发表于 2012-10-17 12:08:52 | 显示全部楼层
果断用硬件I2C  DMA方式读取
直接无视采样时间,控制周期就看你自己随便了

出0入0汤圆

 楼主| 发表于 2012-10-17 12:33:23 | 显示全部楼层
__@ 发表于 2012-10-17 12:08
果断用硬件I2C  DMA方式读取
直接无视采样时间,控制周期就看你自己随便了

嗯,正在尝试
前面有“john800422 ”的代码范例,我正在学习
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 18:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表