zhcool_521 发表于 2008-7-26 10:04:44

把Kalman移植到单片机上,编译错误-缺少浮点元算库(用的 试用版keil编译器)

C51FPS.LIBC51FPC.LIBC51FPL.LIB

谁有这几个库?借来用用,谢谢了!

xiaoqun 发表于 2008-7-26 11:17:08

点击此处下载 ourdev_358772.rar(文件大小:33K) (原文件名:LIB.rar)

zhcool_521 发表于 2008-7-26 14:05:33

谢谢了!

redrain 发表于 2008-7-26 14:49:23

Kalman的源码可以共享吗?谢谢。我的邮件:redrain@sjtu.edu.cn

zhcool_521 发表于 2008-7-26 16:12:09

试验中。。。

xiaoqun 发表于 2008-7-26 16:22:29

51算浮点吃力,可以借鉴DSP的Q格式做定点运算

zhcool_521 发表于 2008-7-28 14:08:30

*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?_INIT_MEMPOOL?INIT_MEM

请教 这个警告是什么原因?
导致 我的定式时中断里面a/d采样出现错误!

love12345 发表于 2008-7-28 18:15:24

是说有段没有被调用。

coolhe 发表于 2008-7-28 20:40:17

我现正将kalman应用于IMU,有类似应用的朋友可以一起讨论.
MCU:mega168.硬件资源是够用了.

xiaoqun 发表于 2008-7-28 23:48:27

这个警告没关系,一般不会出错,提示的函数没有被调用

zhcool_521 发表于 2008-7-29 08:03:59

【8楼】 coolhe
我用的51硬件资源不够用!
【9楼】 xiaoqun
我根本就没有定义这个函数?(_INIT_MEMPOOL)!现在定时中断里面a/d采样寄存器出现错误,而且会有死机现象!

xiaoqun 发表于 2008-7-29 08:22:02

init_mempool是stdlib里的函数,用来初始化堆的。extern void init_mempool (void _MALLOC_MEM_ *p, unsigned int size);这个是原形

zhcool_521 发表于 2008-7-29 08:34:06

【11楼】 xiaoqun谢谢 !

不知什么原因把a/d采样寄存器冲乱了!

zhcool_521 发表于 2008-7-29 08:34:28

【11楼】 xiaoqun谢谢 !

不知什么原因把a/d采样寄存器冲乱了!

xiaoqun 发表于 2008-7-29 08:47:07

不知道你程序里是否用malloc这个函数,这个函数如果要用必须先调用init_mempool这个函数初始化,并且必须是xdata就是扩展RAM,51里尽量少用这个函数,我估计你在做KALMAN的矩阵时可能初始化几个堆了,我觉得你可以定义全局的静态数组,虽然占更多资源,但是还是比较稳定。

zhcool_521 发表于 2008-7-29 08:59:00

用过 calloc 这个函数

//-------------------------------------------------------------------------------------------------
//矩阵倒置,A为倒置前矩阵,AInverse为结果矩阵;
//矩阵均为n行,n列
//-------------------------------------------------------------------------------------------------
static int matrix_inversion(float xdata * A, int n, float xdata * AInverse)
// Matrix Inversion Routine
{
    // A = input matrix (n x n)
    // n = dimension of A
    // AInverse = inverted matrix (n x n)
    // This function inverts a matrix based on the Gauss Jordan method.
    // The function returns 1 on success, 0 on failure.
    intxdata i, j, iPass, imx, icol, irow;
    floatxdata det, temp, pivot, factor;
    float   * ac = (float *)calloc(n*n, sizeof(float));

    det = 1;

    for (i = 0; i < n; i++)
    {
      for (j = 0; j < n; j++)
      {
            AInverse = 0;
            ac = A;
      }
      AInverse = 1;
    }

    // The current pivot row is iPass.
    // For each pass, first find the maximum element in the pivot column.
    for (iPass = 0; iPass < n; iPass++)
    {
      imx = iPass;
      for (irow = iPass; irow < n; irow++)
      {
            if (fabs(A) > fabs(A)) imx = irow;
      }

      // Interchange the elements of row iPass and row imx in both A and AInverse.
      if (imx != iPass)
      {
            for (icol = 0; icol < n; icol++)
            {
                temp = AInverse;
                AInverse = AInverse;
                AInverse = temp;
                if (icol >= iPass)
                {
                  temp = A;
                  A = A;
                  A = temp;
                }
            }
      }

      // The current pivot is now A.
      // The determinant is the product of the pivot elements.
      pivot = A;
      det = det * pivot;
      if (det == 0)
      {
            free(ac);
            return 0;
      }

      for (icol = 0; icol < n; icol++)
      {
            // Normalize the pivot row by dividing by the pivot element.
            AInverse = AInverse / pivot;
            if (icol >= iPass) A = A / pivot;
      }

      for (irow = 0; irow < n; irow++)
      {
            // Add a multiple of the pivot row to each row.The multiple factor
            // is chosen so that the element of A on the pivot column is 0.
            if (irow != iPass) factor = A;
            for (icol = 0; icol < n; icol++)
            {
                if (irow != iPass)
                {
                  AInverse -= factor * AInverse;
                  A -= factor * A;
                }
            }
      }
    }

    free(ac);
    return 1;
}

zhcool_521 发表于 2008-7-29 09:01:10

float   * ac = (float *)calloc(n*n, sizeof(float));
改成静态数组 试试吧,

xiaoqun高手! 谢谢指点!

zhcool_521 发表于 2008-7-29 09:09:14

改成静态数组不成!
调用init_mempool这个函数初始化试试!

zhcool_521 发表于 2008-7-29 09:38:27

警告消除,还是存在 a/d采样问题(把a/d采样 放在定时中断中采样错误,放在外面采样没有问题。)

看样子不是这个警告的问题。!

zhcool_521 发表于 2008-7-29 09:40:26

编译信息:

Build target 'Main_mcu'
compiling mainloop.c...
linking...
Program Size: data=73.0 xdata=502 code=6943
creating hex file from "Main_mcu"...
"Main_mcu" - 0 Error(s), 0 Warning(s).

xiaoqun 发表于 2008-7-29 10:44:14

你可能还有一个问题,就是用了递归调用,这样你需要定义为重入函数,要用到reentrant这个关键词比如说int f(int x) reentrant,必须注意这个问题,或者都用指针,这样函数就可以有可重入性了,C51给的库文件大部分有重入性

zhcool_521 发表于 2008-7-29 11:35:02

没有递归调用。

xiaoqun 发表于 2008-7-29 11:48:49

中断里调用的函数也需要注意。好多时候用到中断嵌套的,假如说同一个函数可能在同一时间调用的话,那么必须是再入的。往往数据发生错误大部分是在中断中发生的,因为没有做好保护现场,或者中断中更改了别的函数的数据,用仿真器可以跟踪到。还有一个问题,你的优化级别不要太高,我觉得6级就可以了,太高可能出现意想不到的错误。

zhcool_521 发表于 2008-7-29 12:01:29

谢谢老大指点! 可能找到问题所在了,下午再 确定一下!!

zhcool_521 发表于 2008-7-29 16:01:24

问题 定位在 上面的函数上!   
float   * ac = (float *)calloc(n*n, sizeof(float));

xiaoqun 发表于 2008-7-29 16:36:52

#include <stdlib.h>

unsigned char xdata malloc_mempool ;

void tst_init_mempool (void) {
int i;
xdata void *p;

init_mempool (&malloc_mempool, sizeof(malloc_mempool));

p = malloc (100);

for (i = 0; i < 100; i++)
    ((char *) p) = i;

free (p);
}

这个是keil的例子程序,你可以参考一下,可能是你的堆没有初始化好

zhcool_521 发表于 2008-7-30 08:21:54

问题原因定位在单片机ram资源不够用!
谢谢xiaoqun。

xiaoqun 发表于 2008-7-30 08:37:48

Program Size: data=73.0 xdata=502 code=6943 你用的是片上集成的XRAM,512byte?那你应该把一些变量定义在data或idata里,还有那么大的地方。

zhcool_521 发表于 2008-7-30 09:19:26

http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_362432.JPG
(原文件名:q.JPG)

xdata 是1024byte, 编译的时候显示“data=73.0 xdata=502 code=6943” 我怀疑编译信息有问题。

我做过这个一个试验: kalman子程序我不在主程序里面调用,ad采样后通过串口 上传到pc,数据无误!!然后再多 定义一个全局变量unsigned char xdata calloc_mempool ;编译后试验,结果上传到pc,数据是乱的!所以我推断是ram问题。

“data=73.0 xdata=502 code=6943”这只是一kalman处理程序,还没有加上角速度和加速度的角度计算还有pid,和后来的gps....这样算来最终还得换单片机。

不过为了试验 kalman 的正确与否,还会继续用51试下去。同时做换单片机的准备!

xiaoqun 发表于 2008-7-30 09:29:48

你可以试一下小模式编译。把数组之类的定义在XDATA,程序自己的临时变量自动会在data中生成。小模式相对速度也要快些。因为大模式编译的时候要注意startup的设置。因为默认keil不会初始化XDATA

zhcool_521 发表于 2008-7-30 09:55:30

小模式编译:

Build target 'Main_mcu'
compiling mainloop.c...
MAINLOOP.C(375): error C241: '_kalman_update': auto segment too large
MAINLOOP.C(553): error C193: '>>': bad operand type
MAINLOOP.C(555): error C193: '>>': bad operand type
MAINLOOP.C(557): error C193: '>>': bad operand type
MAINLOOP.C(559): error C193: '>>': bad operand type
Target not created

kaesi0 发表于 2010-8-3 11:16:35

zhcool_521 我最近也在学习单片机处理角速度 加速度的卡尔曼滤波 可是数学功底太差了能不能帮帮我 我的Mail 是kaesi0@qq.com

thisjoy 发表于 2011-9-16 14:46:02

mark

wonderfulzzd 发表于 2011-9-25 11:27:25

编程很痛苦   但为了我的飞行器那就不一样了
页: [1]
查看完整版本: 把Kalman移植到单片机上,编译错误-缺少浮点元算库(用的 试用版keil编译器)