logo资料库

DSP28335学习经验分享.doc

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
TMS320F28335 开发过程中常见问题总结 1.SPI 驱动 TLE7241E 出现返回值不对的问题。主要是由于时序的不对,导致 TLE7241E 输入采样时数据还没有 建立,所以 TLE7241E 收到的命令不正确,所以返回值不正确。 2.SPI 驱动 EEPROM 时,如果用金属物触到 clock pin 时,能正确运行,否则不能正确运行。出现次问题也是由 于时序的问题,金属物触到 clock 导致 clock 出现微小幅度的偏移,导致正好和 eeprom 的时序对上,而不用金属 物触碰时时序不正常,当使 dsp MOSIpin 数据发送提前半个周期后,eeprom 工作正常。 3.示波器有时会导致显示的波形被消尖,所以用示波器测量时周期不能太大。 TMS320F28335 笔记-I2C 1.响应和非响应的区别是什么? 关于 i2c 的响应问题:对于每一个接收设备(从设备,slaver),当它被寻址后,都要求在接收到每一个字节 后产生一个响应。因此,the master device 必须产生一个额外的时钟脉冲(第九个脉冲)用以和这个响应位相关 联。 在这个脉冲期间,发出响应的从设备必须将 SDA 拉低并在时钟脉冲的高电平期间保持住。这表示该设备给出了 一个 ACK。如果它不拉低 SDA 线,就表示不响应(NACK)。 另外,在从机(发送方)发送完最后一个字节后主设备(接收方)必须产生一个不响应位,用以通知从机(发送方) 不要再发送信息了,这样从机就知道该将 SDA 释放了,而后,主机发出一个停止位给 slaver。 总结下,i2c 通讯中,SDA 和 SCL 都是有主机控制的,从设备只是能够将 SDA 线拉低而已。对于 SCL 线,从机 是没有任何能力去控制的。从机只能被动跟随 SCL 再说的清楚些:主机发送数据到从机的状态下:主机控制 SCL 信号线和 SDA 信号线,从机只是在 SCL 线为高的 时候去被动读取 SDA 线。 主机读取从机的数据:主机来发出时钟信号,从机只是保证在时钟信号为高电平的时候的 SDA 的状态而已。 SDA 和 SCL 已经通过上拉电阻被上拉,master 可以控制(拉低或者释放)这两条线,而 slaver 只能控制 SDA 线。当 master 发送数据时,master 会适时地将 SDA 和 SCL 拉低或释放(拉高)。确切的时序应该是这样的:当 mater 要发送一个 start 时,mater 会将 SDA 拉低,这就可以了,因为此时的 SCL 一定是 High。好了,一个 start 就这样 发出去了。而 slaver 也会发现这个 start 信号的发生,slaver 便会准备好接收接下来的数据了。紧接着,master 要发送一个 Byte 的数据了,一位一位的发出这 8 个 bits。这时 master 会先将 SCL 拉低,然后在 SCL 为低的状态下 将一个 bit 准备好放到 SDA 上(比如要发送一个 0,master 就会通过拉低 SDA 来放好这个 0),然后 master 会把 SCL 拉高(释放),此时 slaver 会立刻检测到 SCL 的变化,由此聪明的 slaver 便知道 master 已经将要发送的那个 bit 准备好了,slaver 便会在这个 SCL 的高电平期间尽快(maser 不会等你很久的哦)去读取一下 SDA,嗯读到了 一个 0,slaver 就把这个 0 放到自己的移位寄存器中待后续处理。master 会在一个设定好的时间后把 SCL 再次拉低, 然后在 SCL 为低电平期间把下一个 bit 放到 SDA 上,然后再把 SCL 拉高,然后 slaver 在 SCL 的高电平期间再去读 SDA。。。。。如此反复 8 次,一个 Byte 的传输便告结束。当这 8 个 bit 发完后,SCL 是处于低电平的(被 master 拉低的),SDA 是出于高电平的(master 已经释放了 SDA)。 当一个字节发送完毕后,master 会释放 SDA(拉高)并拉低 SCL,此时 slaver 如果打算发出一个 ACK 的话,它 必须在这个 SCL 被 master 拉低的短暂时间内去主动将 SDA 拉低并保持住 (此前我们说过,SDA 此时已经被 master 释放,所以 slaver 才有机会去拉低这个 SDA)。master 会在一个确定的时间后再次将 SCL 拉高,并在拉高的期间去 读取 SDA 线的状态,如果读到低电平,则认为收到了来自 slaver 的响应(ACK),否则认为 slaver 没有响应(NACK)
刚才发送的那一个 Byte。这个过程就是我们说的 i2c 通讯中的第 9 个时钟周期。当 master 读完这个 ACK / NACK 后, 会再次将 SCL 拉低,用以通知 slaver:第 9 个时钟周期已经结束,你现在可以释放 SDA 了。而此时 master 也可以 向 SDA 上准备下一个 Byte 的第一个 bit。继而重复上述过程。。。。。或者,master 也许想在接下来发送一个 stop 过去,那么 master 会在这个 SCL 为低的时间内将 SDA 拉低,而后再将 SCL 拉高,在 SCL 为高的期间再将 SDA 释放 (拉 高) 。这样,一个 STOP 位就产生了。你会发现此后的 SDA 和 SCL 都是高,这就是是所谓的总线空闲了! 一句话:SCL 是单向的,由 master 控制。而 SDA 是双向的,master 可以控制,slaver 也可以控制。 2.示波器探头会对波形产生影响,导致波形延时,使用是请注意。 TMS320F28335学习笔记-ADC控制器 1.ADC 的工作模式有哪些? 同时采样模式和顺序采样模式。 2.ADCINT 与 SEQ1INT、SEQ2INT 中断有什么区别 SEQ1INT 和 SEQ2INT 对应序列器 SEQ1 和 SEQ2 的中断,ADCINT 是为了向前兼容 F281x 系列的 ADC 中断,可以由 SEQ1 或 SEQ2 触发产生。在 ADCINT 中断服务程序里,需要软件干预去根据对应标志位确定到底是哪个序列产生了中 断,而 SEQINT1&2 是不需要的。 TMS320F28335笔记-启动过程 1.DSP reset 后运行的起始地址是多少? 0x3FFFC0 2.仿真器烧写程序的步骤是? 根据 cmd 文件把程序烧到指定位置,然后执行。 3.DSP 的 Flash 启动过程是什么?
首先硬件配置 GPIO84~87 上拉为 1,即处于 Flash 启动过程。当 DSP 复位后,会从复位向量 0x3FFFC0 处取得复 位向量,并跳转到 InitBoot 处开始执行,InitBoot 会读 GPIO84~87 的值发现全为 1 判断为 Flash 启动方式。然后 会跳到 0x33FFF6 处执行。在 CCS5.2 工程的 cmd 文件中有如下代码: MEMORY { PAGE 0 : BEGIN : origin = 0x33FFF6, length = 0x000002 /* Boot to M0 will go */ here ... } SECTIONS {... codestart : > BEGIN PAGE = 0 ...} 即表示把 codestart 段放到 0x33FFF6 位置处,文件“DSP2833x_CodeStartBranch.asm”中有 codestart 段的定义, 实际上 codestart 段只是包含了一个跳转指令,是程序跳转到_c_int00 处,_c_int00 在 boot.asm in RTS library 中有定义,_c_int00 的代码最终会调用 c 的 main 函数,之后就是 main 函数的执行。 4.F28335 如何烧写代码到 flash 中并运行? 首先使用添加 C:\ti\controlSUITE\device_support\f2833x\v133\DSP2833x_common\cmd\F28335.cmd。此文件即为 配置代码到 flash 中的 TI 官方配置文件。 然后参考 C:\ti\controlSUITE\device_support\f2833x\v133\DSP2833x_examples_ccsv4\flash_f28335。添加以下 代码: MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);将一些在内存中运行的代码从 flash 复 制到内存中,然后程序才能正常运行。 5.写好的代码再 ram 中能正常运行但是烧写到 flash 中后,函数 DSP28x_usDelay()不能正常运行为什么? 因为在 DSP2833x_usDelay.asm 中有.sect "ramfuncs",即把该函数定义在段"ramfuncs"中, 而此段需要在内 存中运行,故需要使用函数 MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);将 ramfuncs 段复制到内存中然后运行。 只算以这样设计是因为函数 DSP28x_usDelay()精准运行对运行速度有要求故必须放在段"ramfuncs"中。参考: http://blog.sina.com.cn/s/blog_9388c4140100vs0r.html
6.cmd 中以下代码如何解释? ramfuncs : LOAD = FLASHD, RUN = RAML0, LOAD_START(_RamfuncsLoadStart), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), PAGE = 0 第 1 行表示该段的装载在 PAGA0 的 FLASHD 中 第 2 行表示该段的运行地址在 PAGE0 的 RAML0 中 LOAD_ START(_RamfuncsLoadStart)令编译器创建了一个变量 RamfuncsLoadStart,该变量指向段 ramfuncs 的装载 地址的首地址(LOAD_ START 为编译伪指令,请见 CCS 的帮助文档); LOAD_ START(_RamfuncsLoadEnd)令编译器创建了一个变量 RamfuncsLoadEnd,该变量指向段 ramfuncs 的装载地址 的末地址(LOAD_ END 为编译伪指令,请见 CCS 的帮助文档); LOAD_ START(_RamfuncsRunStart)令编译器创建了一个变量 RamfuncsRunStart,该变量指向段 ramfuncs 的运行地 址的首地址(LOAD_ START 为编译伪指令,请见 CCS 的帮助文档); 从第 1 和 2 行可以看出,段 ramfuncs 中的函数 DSP28x_usDelay()的装载地址和运行地址是不同的,本程序中 装载在 Flash 的块 FLASHD 中,而在 SARAM L0 中运行,这只是目标,实际运行时 DSP 并不会自动将 Flash 中的代码 拷贝到 SARAM 中,因此需要手动添加代码来完成。 在 C 函数中,为了使用变量 RamfuncsLoadStart、RamfuncsLoadEnd 和 RamfuncsRunStart,必须先声明,本工程在 文件 DSP2833x_GlobalPrototypes.h 中做了如下声明: extern Uint16 RamfuncsLoadStart; extern Uint16 RamfuncsLoadEnd; extern Uint16 RamfuncsRunStart; 然后就可以使用了。在 Main.c 中,使用 MemCopy()函数将段 ramfuncs 中的函数 DSP28x_usDelay()的代码从装载地 址 RamfuncsLoadStart—RamfuncsLoadEnd 拷贝到 RamfuncsRunStart 开始的 SARAM 空间中。之后在程序运行时,只 要调用 DSP28x_usDelay()函数,都会自动地指向 SARAM 中相应的函数入口地址,这一点是自动完成的。MemCopy() 函数原型在 MemCopy.c 中,DSP2833x_GlobalPrototypes.h 声明。 7.如何将一个函数放到 ram 中运行? 参考 TI 公司头文件中自带 InitFlash 函数,这些函数会以 CODE_SECTION 申明。如:#pragma CODE_SECTION(InitFlash, "ramfuncs"); TMS320F28335笔记-中断
1.如何开启某个中断? 设置中断向量。例如:PieVectTable.WAKEINT = &wakeint_isr; 打开 PIE 控制器。PieCtrlRegs.PIECTRL.bit.ENPIE = 1; 使能 PIE 中对应外设的中断(相应 group 的相应 pin)。例如:PieCtrlRegs.PIEIER1.bit.INTx8 = 1; 使能 CPU 的相应中断(INT1~INT12)IER |= M_INT1; 使能 CPU 响应中断 EINT; 参考网址:http://www.61ic.com/Article/C2000/Delfino/201112/40118.html 2.中断标志有几级?作用是什么? 中断标志主要有三级 CPU(有 16 个标志位)、PIE(有 12 组每组有 12 个标志位)和外设(有的外设没有)。 标志位在中断发生后锁存中断状态,即表示中断发生。在 CPU 响应中断后,会自动清除 cpu 级别的标志位 IFR bit, 同时将 INTM bit 置位,以防止其它中断的发生;CPU 在从 PIE 中取中断向量时 PIE 会自动清除 PIE 级别的标志位 PIEIFRx.y。所以在进入中断处理程序后除了外设所有中断位都已经清除。而中断处理程序中需要清除 PIEACKx 和 外设的中断标志位(如果有的话)。 参考网址:http://www.deyisupport.com/question_answer/f/56/t/13047.aspx http://www.61ic.com/Article/C2000/Delfino/201204/41777.html TMS320F28335笔记-SPI模块 什么是 SPI 接口? SPI 接口是高速同步串行输入输出接口。 TMS320F28335 有几个 SPI 接口模块? 有一个专门的 SPI 模块, 另外两个 McBSP 也可以配置为 SPI 接口。 TMS320F28335SPI 接口由几组寄存器控制? 12 组,位于控制寄存器帧 0x7040h 开始的位置。所有的寄存器都为 16bit 寄存器 FIFO 有几级? 16 级
SPI FIFO 模式下如何对传输和接收 FIFO 进行操作? 直接对 SPITXBUF 进行赋值以传输数据例如:SpiaRegs.SPITXBUF=sdata[i]。此操作可理解为:首先使 TXFIFO 头指针加 1,然后把值写入 TXFIFO 头指针指向的位置。 如果当前没有一个激活的传输过程时,对 SPITXBUF 的写入会激活一个传输过程。 直接读取 SPIRXBUF 的值以接收数据例如:rdata[i]=SpiaRegs.SPIRXBUF,此操作可理解为:首先从 RXFIFO 头 指针处读取 1 个 word, 然后使 RXFIFO 头指针减 1。 SPI FIFO 模式下传输和接收中断何时产生? 是在数据传输或接收结束后,再判断传输和接收 FIFO 队列中有多少数据(SPIFFTX.TXFFST4-0 和 SPIFFRX.RXFFST4-0 的值)。对于传输 FIFO 如果 FIFO 中数据小于等于 TXFFIL4-0(此寄存器指定临界值)指定的 值时会触发中断,在中断处理例程中继续传输数据。对于接收 FIFO 如果 FIFO 中的值大于等于 RXFFIL4-0 中指定的 值时触发中断,在中断处理例程中接收数据。故 FIFO 模式下中断触发条件除了标准 SPI 模式下的数据传输接收完 毕的条件外还要满足 FIFO 中的数据小于等于 TXFFIL 或大于等于 RXFFIL 设定值的条件,在两个条件都满足的情况 下才会触发中断。另外一般情况下,FIFO 模式 SPI 初始化完后会立即产生以个传输中断,因为此时 TXFIFO 没有数 据满足产生中断的条件。 如果只接收数据不发送数据如何激活接收过程? SPI 的的接收过程必须依赖传输过程,故即使值接收数据也必须对 SPITXBUF 写入以激活一个传输过程来接收数 据。 TMS320F28335笔记-McBSP模块 1.McBSP 接口总共有几个?每个 McBSP 接口有几根 pin? TMS320F28335 总共有两个 McBSP 接口。每个接口有六根 pin, 分别是:MFSX, MFSR, MCLKX, MCLKR, MDX, MDR。 2.McBSP 用于 SPI 模式时使用那些 pin?他们和标准 SPI pin 的对应关系是什么? SPICLK->MCLKX SPISIMO->MDX SPISOMI->MDR
SPISTE->MFSX SPITXINT-> SPIRXINT-> 3.McBSP 如何开启 clock stop mode 以兼容 SPI 接口? 通过 CLKSTP、CLKXP 和 CLKRP 来配置时钟的极性和延时的 SPI 兼容模式。 DSP28335研发笔记 1.如何查看 CCS5.2 中包含的源文件有哪些?以及他们的位置? CCS5.2 工程中 C 语言源文件有两部分组成,一部分是在 project 路径下的.c 文件,另外一部分是通过连接添 加到工程里的(.project 文件中的字段)。因此 CCS5.2 中的源文件一部分 在工程目录下,另外一部分在.project 文件中的字段包含的路径下。 2.CCS 中 GEL 文件的作用是什么? ccs 的 gel 语言是一种交互式的命令,它是解释执行的,即不能被编译成可执行文件。它的作用在于扩展了 ccsstudio 的功能,可以用 gel 来调用一些菜单命令,对 DSP 的存储器进行配置等等。但是作者建议对于使用仿真 器和 DSP 功能板的仿真环境用户来说,这种 GEL 语言文件是没必要加入到配置中的。gel 语言的重要性在于针对计 算机模拟环境的用户,使用 gel 可以为其准备一个虚拟的 DSP 仿真环境,但也不是非用不可的。 3.引用例子中的源文件时要注意什么? 使用 CCS5.2 导入例子中的源文件时,最好不要选择连接方式,而使用复制的方式,这样必要时可以更改这些 源文件,而不会影响其他的程序的使用。 4.CCS5.2 如果没有包含函数的声名头文件时也能运行但是结果会不正常,故当函数调用出现莫名其妙的问题 时,要检查声名函数的头文件是否包含。 5.CCS5.2 开发 DSP28335 程序时如何设置程序堆栈的大小? CCS5.2 默认情况下堆栈的大小都为 0x400,在 Project->Properties->Build->C200 Linker->Basic Options 下设置。设置完堆栈的大小后,还要在 cmd 文件中分配堆栈存储空间的
段的位置和大小,栈空间的段名为.stack 用于函数中的临时变量,堆空间的段名为.sysmem 用于 c 语言 malloc 函数分配内存,malloc 最大可分配内存为 Project->Properties->Build ->C200 Linker->Basic Options 下设置的大小减 2。cmd 文件中的堆栈段的大小不能小于 Project->Properties->Build->C200 Linker->Basic Options 下设置的大小。一般来讲不用 变动栈空间的大小和位置,如果函数中需要大的空间就申请堆空间。堆空间可以指定为外部内存,但要注意在第一 次 malloc 函数调用之前一定要初始化外部内存。否则 malloc 能执行成功但是空间指向未定。 heap 大小限制为 32k word 即 0x10000。 6.相关参考网站 http://processors.wiki.ti.com/index.php 7.如何添加头文件的相对路径? 首先在 Project->Properties->Build 选项下,点击 Variables 添加一个变量,然后就可以在 Project->Properties->Build->C2000 Compiler->Include Options 下用${}引用变 量。表示工程路径的系统变量是 PROJECT_ROOT,可以在 Project->Properties->Build->C2000 Compiler->Include Options 下直接引用。注意 Project->Properties->Resource- >Linked Resources 下的变量在 Project->Properties->Build->C2000 Compiler->Include Options 下无效,只有 Project->Properties->Build 下 Variables 选项卡中的变量才能 用。 http://processors.wiki.ti.com/index.php/Include_paths_and_options 8.当程序烧写到 flash 中运行时,设置断点为什么总是出错? 当程序烧写到 flash 中时设置的断点为硬件断点,此断点对 C28x 系列 DSP 只能设置两个多的话就会报错,另 外有些函数有可能会占用硬件断点,故设置断点失败时可查一下如何清理 c 函数的硬件断点。 9.CCS5 Debug 模式下 Tool->Graphs 的用法的要点? 进入 CCS Debug 模式,点击 debug 按钮右边的小箭头打开下拉列表,选中 Debug Configurations,在 target 选项卡下选择 Realtime Options->Halt the target before any debugger access。如果不选此项当 target running 时,graph 波形会是一条为 0 的直线。 在代码中打断点,运行到断点处,因为只有运行在断点处 Graphs 才能识别变量地址,才能在设定 Start Address 时使用数组名和&变量名的形式。
分享到:
收藏