SECTIONS
{    D_LINE: align(256) { }  > RAM  PAGE 1. . .
}

上面是cmd文件的配置,D_LINE用于保存FIR要处理的数据。由于使用了循环间接寻址(Circular Indirect Addressing Modes (XAR6, XAR1)),用XAR6来做数据指针,它指向的初始地址必须是256对齐的,即XAR6开始赋给它的指针低8位必须为0,(XAR6 points to the current address in the buffer. The top of the buffer must be at an address where the 8 LSBs are all 0s.),用XAR1的AR1[7:0]来指示一个循环要处理多少数据,处理AR1个数据即循环一次。由于只用了AR1的8位来表示循环范围,所以一个循环最大只能是(0~255)个字(TI 16位dsp中一个字16bit)。

参考:spru430d,TMS320C28x DSP CPU and Instruction Set Reference Guide,p145~146

TAPS    .set    4       ; FIR – Order +1
xn    .usect “D_LINE”,TAPS       ; sample array in I1Q15 .data           ; FIR – Coeffs in I1Q15
tbl    .word    32768*707/1000       ; 0.707    .word    32768*123/1000       ; 0.123.word   32768*(-175)/1000       ; -0.175.word    32768*345/1000       ; 0.345
    .text
FIR:    SETC  SXM       ; 2’s complement mathCLRC  OVM       ; no clipping modeSPM    1       ; fractional mathMOVL    XAR7,#tbl       ; coefficient pointerMOVL  XAR6,#xn       ; circular buffer pointerMOV   AR1,#TAPS-1       ; buffer offsetMOV    *XAR6%++,*(0:adc)       ; get new sample ( x(n) )ZAPA           ; clear ACC,P,OVC    RPT     #(TAPS/2)-1       ; RPT next instr.(#+1)times
||    DMAC    ACC:P,*XAR6%++,*XAR7++ ; multiply & accumulate 2pairsADDL    ACC:P       ; add even & odd pair-sumsMOV    *(0:dac),AH       ; update output ( y(n) )RET

.word    32768*707/1000       ; 0.707 上面这个表示FIR的系数,乘以32768表示使用IQ15, .word表示这个用16bit存储, 707/1000是为了精度考虑
SPM    1 表示DMAC乘了之后结果左移1位。具体说明见后面。
MOV    *XAR6%++,*(0:adc)       ; get new sample ( x(n) )上面这个原型为 MOV loc16,*(0:16bit) ; [loc16] = [0:16bit],由于是loc16(指向16bit的地址),所以XAR6++表示跳到下一个字(16bit),XAR6后面的%表示循环间接寻址
 loc16
Selects Direct/Stack/Indirect/Register addressing mode for 16-bit data access.loc32
Selects Direct/Stack/Indirect/Register addressing mode for 32-bit data access.

from:spru430d,p126

*XARn++if(loc16), XARn = XARn + 1if(loc32), XARn = XARn + 2

from:spru430d,p134

RPT     #(TAPS/2)-1       ; RPT next instr.(#+1)times这个重复指令作用于它的下一条指令,指示循环多少次
DMAC    ACC:P,*XAR6%++,*XAR7++ ; multiply & accumulate 2pairs原型:DMAC ACC:P,loc32,*XAR7++  由于是loc32,所以一次++表示加了两个字(共32bit)。DMAC表示Dual 16-bit x 16-bit signed multiply and accumulate.具体如下图:

一个32bit的数据拆成2个字,分别相乘,各自结果都移位PM,上半个字乘、移位后累加到ACC,下半个字乘、移位后的结果累加到P,等效的过程如下:
XT = [loc32];
Temp = Prog[*XAR7 or *XAR7++];
ACC = ACC + (XT.MSW * Temp.MSW) << PM;
P = P + (XT.LSW * Temp.LSW) << PM;

参考:spru430d,p243
ADDL    ACC:P循环之后,把ACC和P的结果累加。为什么要累加,见FIR的算法:

MOV    *(0:dac),AH       ; update output ( y(n) )

只取了累加器的高字给16bit的DAC结果缓冲器,由于是取高半字(高16bit),所以相当于右移16bit,前面化为IQ15是左移15位,差了1位,所以让PM等于1,就刚刚好了。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>分隔>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    但是上面的代码好像有些问题,因为MOV    *XAR6%++,*(0:adc)仅仅移动了一个字,而DMAC    ACC:P,*XAR6%++,*XAR7++ 这里一“++”就是两个字,所以到边界的时候有可能就对不齐了。    目前还不清楚,DMAC指令当在用循环间接寻址,取32位数的时候,XAR6刚好是一个奇数,刚好距离循环寻址的边界仅剩一个字的时候,这个32位的数值的高字节究竟是循环寻址区的第一个字节还是越循环寻址区,取与寻址区相邻的一个字节呢?根据TI的文档,应该是后一种比较有可能,因为文档中提到If one of the instructions accessing the circular buffer performs a 32-bit operation,make sure XAR6 and AR1 are both even (都是偶数)before the buffer is accessed.所以上面代码是有问题的,但是作为参考,还是有益的。    开始TI的Filter库是放在sprc082,后来出了controlsuite,sprc082就没更新了,对比sprc082的0.9c(不是上面这个,比较完善了)与controlsuite的代码,还是有点区别的,这部分代码还没仔细看,以后应当用controlSUITE的代码。刚刚下的一个controlSUITE是v3.1.1 - October 8, 2012

controlSUITE:http://www.ti.com/tool/controlsuitecontrolSUITE里面的代码分析,暂缓吧

原创:  TrueElement转载请注来源>>

转载于:https://www.cnblogs.com/TrueElement/archive/2012/11/22/2782283.html

C28x FIR - Filter 示例汇编代码解读相关推荐

  1. 【嵌入式开发】ARM 关闭中断 ( CPRS 中断控制位 | 中断使能寄存器 | 中断屏蔽寄存器 | 关闭中断 | 汇编代码编写 )

    一. 中断控制 ( 基于 S3C6410 开发板 ) 1. 关闭中断的两个步骤 (1) 关闭中断步骤 2. CPRS 寄存器中的中断控制位 (1) CPRS 寄存器简介 (2) CPRS 寄存器 中断 ...

  2. mips汇编代码示例解释_通过示例解释cosmosdb

    mips汇编代码示例解释 Since I'm going to be giving a spiel (or two) about Data and AI at Microsoft Ignite lat ...

  3. 【嵌入式开发】ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 )

    文章目录 一. 内存 简介 1. 两大内存分类 ( 1 ) DRAM 简介 ( 定期刷新 | 速度慢 | 成本低 ) ( 2 ) SRAM 简介 ( 不需刷新 | 存取速度快 | 功耗大 | 成本高 ...

  4. directshow 虚拟摄像头 实例 代码解读

    本文只介绍这个源码的大致构成以及怎么修改,因为其他的我也不会啊哈哈哈,我就是用QQ调用虚拟摄像头读取我自己的视频或者图片播放给别人让别人以为这就是实时的而已. 1,示例代码:QQ可用 Directsh ...

  5. 装逼一步到位!GauGAN代码解读来了

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:游璐颖,福州大学,Datawhale成员 AI神笔马良 如何装逼一 ...

  6. Unet论文解读代码解读

    论文地址:http://www.arxiv.org/pdf/1505.04597.pdf 论文解读 网络 架构: a.U-net建立在FCN的网络架构上,作者修改并扩大了这个网络框架,使其能够使用很少 ...

  7. 【嵌入式开发】ARM 异常向量表 ( 异常概念 | 异常处理流程 | 异常向量 | 汇编代码 )

    一. 异常向量表 1. 异常相关概念 (1) 异常 (2) 异常类型简介 2. 异常处理 (1) 异常处理 二. 异常向量表代码编写 1. 初始化异常向量表模块代码 2. 链接器脚本 3. Makef ...

  8. Jsoup代码解读之四-parser(上)

    转载自  Jsoup代码解读之四-parser(上) 作为Java世界最好的HTML 解析库,Jsoup的parser实现非常具有代表性.这部分也是Jsoup最复杂的部分,需要一些数据结构.状态机乃至 ...

  9. 程序编码(机器级代码+汇编代码+C代码+反汇编)

    [-1]相关声明 本文总结于csapp: 了解详情,或有兴趣,建议看原版书籍: [0]程序编码 GCC调用了一系列程序,将源代码转化成可执行代码的流程如下: (1)C预处理器扩展源代码,插入所有用#i ...

  10. 如何在Visual Studio项目中正确添加汇编代码 .

    引用注明>> [作者:张佩][镜像:www.yiiyee.cn/blog] 1.      问题描述 在以往的编程经历中,本人最常使用的汇编代码是__asm {int 3}.它可以在我的代 ...

最新文章

  1. 使用dwz框架搭建网站后台
  2. SVG animation 回顾
  3. 专家揭示模块化数据中心的真谛
  4. Leaflet中使用MovingMarker插件实现标记移动(轨迹回放效果)
  5. How to Pronounce BEAUTIFUL
  6. 数据段描述符和代码段描述符(一)——《x86汇编语言:从实模式到保护模式》读书笔记10
  7. python函数手册_python学习手册——内置函数(上)
  8. 因为sudoers权限而引起的sudo失效
  9. JPA EntityManager详解
  10. ir指令、立即数的作用_ARM指令中使用立即数详解
  11. java long类型6_Java学习6——基本数据类型及其转换
  12. 信息系统的风险评估过程与评估方法
  13. [Python数据分析]NBA的球星们喜欢在哪个位置出手
  14. 辞旧迎新,继往开来:2021→2022
  15. 卡在装备配置计算机,win10开机卡logo的小伙伴有福了,赶紧看过来!
  16. 华师大 OJ 2850
  17. vue数字递增的动画效果
  18. Java程序中如何输入数据
  19. 年末放大招,Java进阶大数据3W全套视频免费领!
  20. 三种EXCEL去重统计方法

热门文章

  1. 微信小程序自定义屏幕调试
  2. 【读书】2022年阅读记录
  3. 2019春季高考计算机试题,山东省2019春季高考模拟考试信息技术试试卷+答案(10页)-原创力文档...
  4. c语言中isupper用法,C 库函数 – isupper() - C 教程 - 自强学堂
  5. 七、项目沟通管理(输入/工具与技术/输出)
  6. 大数据和数据挖掘是什么关系?
  7. 深入理解 ceph mgr
  8. 记录一下matlab画雷达图
  9. 比特大陆发布终端 AI 芯片 端云联手聚焦安防
  10. 支付宝VS微信,谁在抄袭谁?