[讨论] C2000 RMS计算求指点

a828378   2014-11-14 14:39 楼主
简单来说这段代码是用来做FIR+RMS计算的。FIR的部分是直接用TI的例程的。RMS算法部分是自己写了。
AD采集得到数据由CLA读取中断和采样结果,并且进行数字滤波。
RMS算法的部分就是每次滤波完的数据都求一次平方,并且累加。同时设定某一个阀值Vth,当电压超过Vth时认为是采样满了一个周期,得到将所得平方和开放求平均开方得到有效值。再输出到CLA的通讯RAM中。代码如下,内含错误若干。已经改了几个通宵了,第一次写汇编被这么简单的程序纠结了。。望各位大哥帮小弟个忙。没看懂的程序部分请留言。@dontium ~
  1. MMOV32     MR0,@_X4                      ;1 Load MR0 with X4
  2.     MMOV32     MR1,@_A4                      ;2 Load MR1 with A4
  3.     MNOP                                     ;3 Wait till I8 to read result
  4.     MNOP                                     ;4 Wait till I8 to read result
  5.     MNOP                                     ;5 Wait till I8 to read result
  6.     MNOP                                     ;6 Wait till I8 to read result
  7.     MNOP                                     ;7 Wait till I8 to read result
  8.     MUI16TOF32 MR2,  @_AdcResult.ADCRESULT1  ;8 Read ADCRESULT1 and convert to float

  9.     MMPYF32    MR2, MR1, MR0                 ; MR2 (Y) = MR1 (A4) * MR0 (X4)
  10. || MMOV32     @_X0, MR2

  11.     MMOVD32    MR0,@_X3                      ; Load MR0 with X3, Load X4 with X3
  12.     MMOV32     MR1,@_A3                      ; Load MR1 with A3
  13.                                           
  14.     MMPYF32    MR3, MR1, MR0                 ; MR3 (Y) = MR1 (A3) * MR0 (X3)
  15. || MMOV32     MR1,@_A2                      ; Load MR1 with A2
  16.     MMOVD32    MR0,@_X2                      ; Load MR0 with X2, Load X3 with X2

  17.     MMACF32    MR3, MR2, MR2, MR1, MR0       ; MR3 = A3*X3 + A4*X4
  18. || MMOV32     MR1,@_A1                      ; MR2 = MR1 (A2) * MR0 (X2)
  19.     MMOVD32    MR0,@_X1                      ; Load MR0 with X1, Load X2 with X1

  20.     MMACF32    MR3, MR2, MR2, MR1, MR0       ; MR3 = A2*X2 + (A3*X3 + A4*X4)
  21. || MMOV32     MR1,@_A0                      ; MR2 = MR1 (A1) * MR0 (X1)
  22.     MMOVD32    MR0,@_X0                      ; Load MR0 with X0, Load X1 with X0

  23.     MMACF32    MR3, MR2, MR2, MR1, MR0       ; MR3 = A1*X1 + (A2*X2 +A3*X3 + A4*X4)
  24. || MMOV32     MR1,@_A0                      ; MR2 = MR1 (A0) * MR0 (X0)

  25.     MADDF32    MR3, MR3, MR2                 ; MR3 = A0*X0 + (A1*X1 + A2*X2 +A3*X3 + A4*X4)

  26.         MF32TOUI16 MR2, MR3                      ; Get back to Uint16 value
  27.     MMOV16     @_VoltFilt, MR2               ; Output

  28.     .if CLA_DEBUG == 1
  29.     MDEBUGSTOP
  30.     .endif


  31.     MMOV32     MR1, @_Vavr
  32.     MSUBF32    MR3, MR3, MR1                 ; use the current average votage for blocking

  33.     MMOV32     MR1, @_Vavrc                  ; calculate the total votage for the average calc
  34.     MADDF32    MR1, MR1, MR3
  35.     MMOV32     @_Vavrc, MR1

  36.     MMPYF32    MR2, MR3, MR3                 ; calculate the total power for the rms calc
  37.   || MMOV32    MR1, @_Vrmsc
  38.     MADDF32    MR1, MR1, MR2
  39.     MMOV32     @_Vrmsc, MR1

  40.     MMOVZ16    MR1, @_calcnum                ; N+1
  41.     MMOVZ16    MR0, @_TRUE_Value
  42.     MADD32     MR1, MR0, MR1
  43.     MMOV16     @_calcnum, MR1

  44.     MUI16TOF32 MR2, @_Vth                    ; load MR2 with the votage threshold
  45.     MCMPF32    MR3,MR2                       ; compare the votage and its threshold

  46.     MNOP
  47.     MNOP
  48.     MNOP
  49.     MBCNDD     aboveVth,GT                   ; if votage is larger than its threshold,then jump to the aboveVth and do the calcalation
  50.     MNOP
  51.     MNOP
  52.     MNOP

  53.     ;MMOVIZ     MR0, #0.0                    ; clear the check flag
  54.     ;MF32TOUI16 MR0, MR0
  55.     ;MMOV16     @_Frag, MR0
  56.     MMOV16     MAR0, @_FALSE_Value
  57.     MMOV16     @_Frag, MAR0

  58.     MNOP
  59.     MNOP
  60.     MNOP
  61.     MBCNDD     Tsk7STOP, UNC                 ; jump to the end of the task
  62.     MNOP
  63.     MNOP
  64.     MNOP

  65. aboveVth:    MUI16TOF32 MR2, @_Frag          ; load MR2 with the Flag

  66.     .if CLA_DEBUG == 1
  67.     MDEBUGSTOP
  68.     .endif
  69.     MMOVF32    MR0, #0.0
  70.     ;MF32TOI32  MR0, MR0
  71.     MCMPF32    MR2, MR0                      ; compare Frag with 0

  72.     MNOP
  73.     MNOP
  74.     MNOP
  75.     MBCNDD     Tsk7STOP,GT                   ; if Frag is biger than 0,which means it has been set to 1 and has been calclated ,Jump to the end
  76.     MNOP
  77.     MNOP
  78.     MNOP

  79.     MMOV16     MAR0,@_TRUE_Value             ; set the Frag
  80.     MMOV16     @_Frag,MAR0

  81. MNOP
  82.     MNOP
  83.     MNOP
  84.     MNOP
  85.     MMOV32     MR1, @_calcnum                 ;calc the average of the RMS

  86.     MMOV16     MAR1, @_calcnum
  87.     MNOP
  88.     MNOP
  89.     MNOP
  90.     MNOP
  91.     MMOV16     @_calcPRD, MAR1
  92.     MNOP
  93.     MNOP
  94.     MNOP
  95.     MNOP

  96.     MEINVF32   MR0, MR1
  97.     MMOV32     MR1, @_Vrmsc
  98.     MMPYF32    MR2, MR0, MR1
  99.     MMOV32     @_Vrms, MR2                   ;load the Vrms with MR2
  100. MDEBUGSTOP
  101.     ;MMOV32    MR0, @_invn                  ;calc the average of the RMS
  102.     MMOV32     MR1, @_Vavrc
  103.     MMPYF32    MR2, MR0, MR1
  104.     MMOV32     @_Vavr, MR2                   ;load the Vrms with MR2

  105.     MMOVIZ     MR0, #0.0
  106.     MUI16TOF32 MR0, MR0
  107.     MMOV32     @_Vavrc, MR0
  108.     MMOV32     @_Vrmsc, MR0
  109.     MMOVI16    MAR0, #0
  110.     MMOV16     @_calcnum,MAR0
  111.     MNOP
  112.     MNOP
  113.     MNOP
  114.     MNOP

  115. Tsk7STOP:        MSTOP     ; End task



回复评论 (10)

看了好久,也没看出什么名堂。给你提点建议吧:

1、第8行前可以不用NOP,------只要不是提前产生EOC。
2、第10行以后的运算,最好一步一步地调试。在语句中很难发现错误所在。
       即,执行每一步后,寄存器的值是多少,然后验算一下是不是这个值。我调试时就采用这种办法,不然很难发现寄存器应用错误。
3、第36行,可以不用这样处理。因为CLA只有在调试时连接它时MDEBUGSTOP语句才使程序暂停,其它情况,即使在调试时,只要未连接它或非DEBUG模式,它只作为NOP指令。
4、从存储器中取连续数据并运算时,可以考虑使用象MMOV32 MR0, *MAR0[2]++形式。
5、取数,也可以考虑使用MMOVD32 MRa, mem32

; sum = X0*B0 + X1*B1 + X2*B2 + Y1*A1 + Y2*B2
;
; X2 = X1
; X1 = X0
; Y2 = Y1
; Y1 = sum
;
_Cla1Task2:
MMOV32 MR0, @_B2 ; MR0 = B2
MMOV32 MR1, @_X2 ; MR1 = X2
MMPYF32 MR2, MR1, MR0 ; MR2 = X2*B2
|| MMOV32 MR0, @_B1 ; MR0 = B1
MMOVD32 MR1, @_X1 ; MR1 = X1, X2 = X1
MMPYF32 MR3, MR1, MR0 ; MR3 = X1*B1
|| MMOV32 MR0, @_B0 ; MR0 = B0
MMOVD32 MR1, @_X0 ; MR1 = X0, X1 = X0
; MR3 = X1*B1 + X2*B2, MR2 = X0*B0
; MR0 = A2
MMACF32 MR3, MR2, MR2, MR1, MR0
|| MMOV32 MR0, @_A2
MMOV32 MR1, @_Y2 ; MR1 = Y2
; MR3 = X0*B0 + X1*B1 + X2*B2, MR2 = Y2*A2
; MR0 = A1
MMACF32 MR3, MR2, MR2, MR1, MR0
|| MMOV32 MR0, @_A1
MMOVD32 MR1,@_Y1 ; MR1 = Y1, Y2 = Y1
MADDF32 MR3, MR3, MR2 ; MR3 = Y2*A2 + X0*B0 + X1*B1 + X2*B2
|| MMPYF32 MR2, MR1, MR0 ; MR2 = Y1*A1
MADDF32 MR3, MR3, MR2 ; MR3 = Y1*A1 + Y2*A2 + X0*B0 + X1*B1 + X2*B2
MMOV32 @_Y1, MR3 ; Y1 = MR3


40行以后的也没有见你写算式,更难看懂。
点赞  2014-11-14 16:02
引用: dontium 发表于 2014-11-14 16:02
看了好久,也没看出什么名堂。给你提点建议吧:

1、第8行前可以不用NOP,------只要不是提前产生EOC。

十分感谢十分感谢。
我再继续改改调试下。加点注释。希望能好来。
先问两个小问题:
1我在task结束的地方有一句MSTOP,但每次一旦执行到那儿以后。就会卡在那儿,CLA就不能在仿真了。显示的是CLA_0: Can't Single Step Target Program:只能重新仿真才能继续。
2另外如何查看变量。?直接在expressions框内添加对应的变量,及时切换到CLA的仿真也不能查看对应变量。导致我单步仿真一直不好弄。
点赞  2014-11-14 16:22
1、一般地,执行MSTOP后,CLA的任务已经结束,如果再次运行,需要再次触发。
    但是个别时候,调试时运行到MSTOP时并不能清除RUN状态,导致无法再次运行,可以在结束前,即运行MSTOP时点DEBUG窗口的“运行”图标。

2、有CLA寄存器窗口,直接看具体的寄存器好了。如果没有CLA寄存器窗口,可以设置一下。
点赞  2014-11-14 16:34
过来看看~~~~~~~~~~~
点赞  2014-11-14 17:32
引用: dontium 发表于 2014-11-14 16:34
1、一般地,执行MSTOP后,CLA的任务已经结束,如果再次运行,需要再次触发。
    但是个别时候,调试时运 ...

那看来是不能单步到MSTOP语句上。我用的是ccs6.0的。改了下程序。单步仿真了好像这两个语句还有点问题。
  1.     MMOV32     MR1, @_calcnum                ; calc the average of the RMS
  2.     MEINVF32   MR0, MR1                      ; 计算点数1/n用于求平均 将起暂时放在MR0中
calcnum是uint16的。需要求算程float32型的1/n用来求平均好像算出来不大正常但不知道怎么改。先不说精度的问题。

没看到什么大错误。但是直接跑起来还是不大正常。我加了一些注释。希望有时间的朋友能帮忙注意下。万分感谢了。
  1. MMOV32     MR0,@_X4                      ;1 Load MR0 with X4
  2.     MMOV32     MR1,@_A4                      ;2 Load MR1 with A4
  3.     MNOP                                     ;3 Wait till I8 to read result
  4.     MNOP                                     ;4 Wait till I8 to read result
  5.     MNOP                                     ;5 Wait till I8 to read result
  6.     MNOP                                     ;6 Wait till I8 to read result
  7.     MNOP                                     ;7 Wait till I8 to read result
  8.     MUI16TOF32 MR2,  @_AdcResult.ADCRESULT1  ;8 Read ADCRESULT1 and convert to float

  9.     MMPYF32    MR2, MR1, MR0                 ; MR2 (Y) = MR1 (A4) * MR0 (X4)
  10. || MMOV32     @_X0, MR2

  11.     MMOVD32    MR0,@_X3                      ; Load MR0 with X3, Load X4 with X3
  12.     MMOV32     MR1,@_A3                      ; Load MR1 with A3
  13.                                           
  14.     MMPYF32    MR3, MR1, MR0                 ; MR3 (Y) = MR1 (A3) * MR0 (X3)
  15. || MMOV32     MR1,@_A2                      ; Load MR1 with A2
  16.     MMOVD32    MR0,@_X2                      ; Load MR0 with X2, Load X3 with X2

  17.     MMACF32    MR3, MR2, MR2, MR1, MR0       ; MR3 = A3*X3 + A4*X4
  18. || MMOV32     MR1,@_A1                      ; MR2 = MR1 (A2) * MR0 (X2)
  19.     MMOVD32    MR0,@_X1                      ; Load MR0 with X1, Load X2 with X1

  20.     MMACF32    MR3, MR2, MR2, MR1, MR0       ; MR3 = A2*X2 + (A3*X3 + A4*X4)
  21. || MMOV32     MR1,@_A0                      ; MR2 = MR1 (A1) * MR0 (X1)
  22.     MMOVD32    MR0,@_X0                      ; Load MR0 with X0, Load X1 with X0

  23.     MMACF32    MR3, MR2, MR2, MR1, MR0       ; MR3 = A1*X1 + (A2*X2 +A3*X3 + A4*X4)
  24. || MMOV32     MR1,@_A0                      ; MR2 = MR1 (A0) * MR0 (X0)

  25.     MADDF32    MR3, MR3, MR2                 ; MR3 = A0*X0 + (A1*X1 + A2*X2 +A3*X3 + A4*X4)

  26.         MF32TOUI16 MR2, MR3                      ; Get back to Uint16 value MR3一直保存着当前采样值
  27.     MMOV16     @_VoltFilt, MR2               ; Output

  28.     MDEBUGSTOP

  29.     MMOV32     MR1, @_Vavr                   ; 用以前计算的平均值来做电压隔值。MR3=MR3-Vavr
  30.     MSUBF32    MR3, MR3, MR1                 ; use the current average votage for blocking

  31.     MMOV32     MR1, @_Vavrc                  ; calculate the total votage for the average calc
  32.     MADDF32    MR1, MR1, MR3                 ; Vavr=Vavr+MR3
  33.     MMOV32     @_Vavrc, MR1

  34.     MMPYF32    MR2, MR3, MR3                 ; calculate the total power for the rms calc
  35.   || MMOV32    MR1, @_Vrmsc
  36.     MADDF32    MR1, MR1, MR2                 ; Vrmsc=Vrmsc+MR3*MR3
  37.     MMOV32     @_Vrmsc, MR1

  38.     MMOVZ16    MR1, @_calcnum                ; N+1
  39.     MMOVZ16    MR0, @_TRUE_Value             ; calcnum=calcnum+1 表示一个周期内计算了多少个点
  40.     MADD32     MR1, MR0, MR1
  41.     MMOV16     @_calcnum, MR1

  42.     MUI16TOF32 MR2, @_Vth                    ; load MR2 with the votage threshold
  43.     MCMPF32    MR3,MR2                       ; compare the votage and its threshold
  44.     ;比较当前电压和门限值,高了转去aboveVth

  45.     MNOP
  46.     MNOP
  47.     MNOP
  48.     MBCNDD     aboveVth,GT                   ; if votage is larger than its threshold,then jump to the aboveVth and do the calcalation
  49.     MNOP
  50.     MNOP
  51.     MNOP

  52.     ;MMOVIZ     MR0, #0.0                    ; clear the check flag
  53.     ;MF32TOUI16 MR0, MR0
  54.     ;MMOV16     @_Frag, MR0
  55.     MMOV16     MAR0, @_FALSE_Value           ; 将Frag标志位清零
  56.     MMOV16     @_Frag, MAR0

  57.     MNOP
  58.     MNOP
  59.     MNOP
  60.     MBCNDD     Tsk7STOP, UNC                 ; jump to the end of the task
  61.     MNOP
  62.     MNOP
  63.     MNOP

  64. aboveVth:    MUI16TOF32 MR2, @_Frag          ; load MR2 with the Flag
  65.     MMOVF32    MR0, #0.0
  66.     ;MF32TOI32  MR0, MR0
  67.     MCMPF32    MR2, MR0                      ; compare Frag with 0
  68.                                              ; 比较标志位是否为零;

  69.     MDEBUGSTOP

  70.     MNOP
  71.     MNOP
  72.     MNOP
  73.     MBCNDD     Tsk7STOP,GT                   ; if Frag is biger than 0,which means it has been set to 1 and has been calclated ,Jump to the end
  74.     MNOP                                     ; 如果标志位为1 则跳转至结束。
  75.     MNOP
  76.     MNOP

  77.     MMOV16     MAR0,@_TRUE_Value             ; set the Frag
  78.     MMOV16     @_Frag,MAR0                   ; 将标志位置位。

  79.     MMOV16     MAR1, @_calcnum               ; 将计算点数输出至calcPRD变量
  80.     MMOV16     @_calcPRD, MAR1

  81.     MMOV32     MR1, @_calcnum                ; calc the average of the RMS
  82.     MEINVF32   MR0, MR1                      ; 计算点数1/n用于求平均 将起暂时放在MR0中
  83.    
  84.     MMOV32     MR1, @_Vrmsc                  ; VRMS=VRMSC * 1/n
  85.     MMPYF32    MR2, MR0, MR1                 ; 结果保存在VRMS中
  86.     MMOV32     @_Vrms, MR2                   ; load the Vrms with MR2

  87.     MMOV32     MR1, @_Vavrc                  ; calc the average of the RMS
  88.     MMPYF32    MR2, MR0, MR1                 ; Vavr=Vavrc * 1/n 结果保存在Vavr中
  89.     MMOV32     @_Vavr, MR2                   ; load the Vrms with MR2

  90.     MMOVIZ     MR0, #0.0                     ; 将Varvc、Vrmsc和calcnum清零
  91.     MUI16TOF32 MR0, MR0
  92.     MMOV32     @_Vavrc, MR0
  93.     MMOV32     @_Vrmsc, MR0
  94.     MMOVI16    MAR0, #0
  95.     MMOV16     @_calcnum,MAR0
  96.     MNOP
  97.     MNOP
  98.     MNOP
  99.     MNOP

  100. Tsk7STOP:        MSTOP     ; End task




点赞  2014-11-14 19:47
引用: a828378 发表于 2014-11-14 19:47
那看来是不能单步到MSTOP语句上。我用的是ccs6.0的。改了下程序。单步仿真了好像这两个语句还有点问题。
calcnum是uint16的。需要求算程float32型的1/n用来求平均好像算出来不大正常但不知道怎么改。先不说精度的问题。

没看到什么大错误。但是直接跑起来还是不大正常。我加了一些注释。希望有时间的朋友能帮忙注意下。万分感谢了。

MEINVF32   是约等运算,你可以看看手册中的说明,可以更逼近1/n。

不正常的话,可能是运算中出了问题,看嘛是很难看出来的,有时候寄存器搞错了就会得到错误的结果。  --- 所以我建议你单步运行后,将每一步的结果与手工计算作一比较,这样才能发现问题所在。我在调试时就是这样做的,如果你有更好的办法不仿告诉我。
点赞  2015-1-19 21:37
引用: a828378 发表于 2014-11-14 19:47
那看来是不能单步到MSTOP语句上。我用的是ccs6.0的。改了下程序。单步仿真了好像这两个语句还有点问题。
calcnum是uint16的。需要求算程float32型的1/n用来求平均好像算出来不大正常但不知道怎么改。先不说精度的问题。

没看到什么大错误。但是直接跑起来还是不大正常。我加了一些注释。希望有时间的朋友能帮忙注意下。万分感谢了。




点赞  2015-1-19 21:37
引用: dontium 发表于 2015-1-19 21:37
MEINVF32   是约等运算,你可以看看手册中的说明,可以更逼近1/n。

不正常的话,可能是运算中出了问题,看嘛是很难看出来的,有时候寄存器搞错了就会得到错误的结果。  --- 所以我建议你单步运行后,将每一步的结果与手工计算作一比较,这样才能发现问题所在。我在调试时就是这样做的,如果你有更好的办法不仿告诉我。


非常感谢!后来调试出来了。就是在算倒数和开方后面的用牛顿法毕竟的时候寄存器倒来倒去倒错了。现在已经改正。但我现在遇到另一个问题希望能求指点。有些变量我是存放在flash。开机的时候在startup里面把他们全部复制到RAM里。然后再运行程序的。我在运行的时候会更改这些数据。但我希望能掉电保存他们。我可能就需要获得他们在flash里面存放的地址。然后去修改?》请问如何做到?

点赞  2015-1-20 11:07
复制到RAM需要重新存放FLASH吗
点赞  2015-1-20 16:32
引用: accboy 发表于 2015-1-20 16:32
复制到RAM需要重新存放FLASH吗



是的。这个参数我要求掉电保存。
点赞  2015-1-20 17:34
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复