搜索
bottom↓
回复: 313

TMS320F28XX问题讨论贴,我会尽量回答大家提出的问题

[复制链接]

出0入0汤圆

发表于 2009-4-10 09:11:09 | 显示全部楼层 |阅读模式
我对28XX系列比较熟悉,大家有问题可以跟帖讨论,我每天晚上抽空回复
当然,我不是万能的,尽我所能帮助大家,互相提高

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

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2009-4-13 10:46:21 | 显示全部楼层
楼上:
  你好
   F2808M0,M1 SARAMS;L0,L1,H0 SARAMS;BootRom;Flash,OTP,这些存储器都怎么用?
映射的物理地址是固定的么?如果是固定的,那么它们各自映射空间是什么?

如果程序中开辟了一块数据表,和一段连续的全局变量应该放到哪个存储器空间?

如果想把部分程序代码在运行时由flash加载到RAM,该怎么做?

谢谢大侠不吝赐教

出0入0汤圆

发表于 2009-4-13 14:30:51 | 显示全部楼层
怎么没人顶啊   难得有楼主这样的好人呢。

出0入0汤圆

 楼主| 发表于 2009-4-14 09:15:48 | 显示全部楼层
关于qionggui84的问题
F2808M0,M1 SARAMS;L0,L1,H0 SARAMS;BootRom;Flash,OTP,这些存储器都怎么用?
M1 SARAMS;L0,L1,H0 SARAMS;这些是RAM可以用来放程序和数据
BootRom;Flash,OTP这些只能放程序代码

映射的物理地址是固定的,各自映射空间请查看2808的datasheet

如果程序中开辟了一块数据表,和一段连续的全局变量应该放到哪个存储器空间?
一般变量放到RAM空间,常量数据表可以放到程序空间

如果想把部分程序代码在运行时由flash加载到RAM,该怎么做?
这个建议看一下2808例程里的FLASH示例
简单来说需要在两个地方进行设置
1:CMD文件中需要配置
   ramfuncs            : LOAD = FLASHD,
                         RUN = RAML0,
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         PAGE = 0
2:main函数里要调用MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);并初始化FLASH


我说的可能不太清楚,不明白可以再讨论

出0入0汤圆

发表于 2009-4-14 19:43:27 | 显示全部楼层
请教一下只要使能中断的话PIEVECTORTABLE和PIECORTROL这两个和PIE中断相关的内容是不是必须要初始化呢?因为我看很多的例程仅仅初始化vectortable这个中断向量表,而没有运行初始化piecontrol.

出0入0汤圆

 楼主| 发表于 2009-4-15 09:20:24 | 显示全部楼层
PIEVECTORTABLE和PIECORTROL都要初始化
如果把PIEVECTORTABLE比做酒店的房间,那么PIECORTROL就是每个房间的钥匙,如果一个人想住酒店,那么他必须知道房间号(初始化vectortable),还要有房间钥匙(初始化piecontrol)

出0入0汤圆

发表于 2009-4-15 10:52:41 | 显示全部楼层
请问F2812的SCI模块,使用他的增强功能FIFO模块发送的时候,假如打开了FIFO发送级别匹配,怎么会总是进入中断呢,中断函数里面我已经写了清除FIFO发送级别中断标志了呀,可是观察寄存器,发现根本没有清除掉。
相应代码如下:
初始化SCIA模块部分
    // Config SCIA module
        SCIFFTXA  = 0x0000;                // reset transmit chanel
        SCIFFRXA  = 0x0000;                // reset transmit chanel
        SCICCRA   = 0x07;                /* 1 stop bit, No loopback, No parity, 8 char bits, async mode, idle-line protocol */
        SCICTL1A  = 0x03;                /* enable TX, RX, internal SCICLK, Disable RX ERR, SLEEP, TXWAKE */
        SCICTL2A  = 0x00;
   
    SCIHBAUDA = SCIABAUDH;
    SCILBAUDA = SCIABAUDL;        // 波特率115200
   
        SCICTL1A  = 0x23;           // Restar sci, enable Recieve and Transmit
        SCIFFTXA  = 0xC02F;         // Enable TX interrupt,enable TX FIFO, Triger level set to 16
        SCIFFRXA  = 0x0026;         // Enable RX interrupt,enable RX FIFO, Triger Level set to 5
        SCIFFCTA  = 0x0002;                // disable Auto Baud rate check, Delay 2 baudclock period
    SCIPRIA   = 0x08;      

        SCIFFTXA |= BIT13;
        SCIFFRXA |= BIT13;

SCI发送中断处理函数部分
interrupt void SciaTxIsr(void)
{
    PerformSciaTx();//这里只是处理数据部分,不涉及寄存器。

        SCIFFTXA |= BIT6;        // Clear interrupt flag(就是这里,进入发送中断后执行完这一句,观察SCIFFTXA 寄存器,发现根本没有清除掉bit7的TXFIFO中断标志,导致重复进入发送中断,困惑。)
        PIEACK |= PIEACK_GROUP9;        // Acknowledge PIE group 9 int
        EINT;
        return;
}

假如我想用TXFIFO的话,例如一次发16个字节,应该怎么配置SCIFFTXA寄存器呢?
用TXFIFO的话,可以不用一个字节一个字节等待发送完毕,一次性写入16个字节就可以啦,这样理解对吧?

期待楼主的解惑,先行谢过啦!
谢谢

出0入0汤圆

发表于 2009-4-15 11:35:47 | 显示全部楼层
LZ辛苦了,无私的人,

出0入0汤圆

 楼主| 发表于 2009-4-15 14:03:38 | 显示全部楼层
我贴一个2808的TX FIFO例子你看一下,其实TI提供了很全的例子,所以你先看一下TI的代码,然后修改一下就OK

interrupt void sciaTxFifoIsr(void)
{
    Uint16 i;
    for(i=0; i< 8; i++)
    {
           SciaRegs.SCITXBUF=sdataA;     // Send data
        }

    for(i=0; i< 8; i++)                 //Increment send data for next cycle
    {
           sdataA = (sdataA+1) & 0x00FF;
        }

        SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;        // Clear SCI Interrupt flag
        PieCtrlRegs.PIEACK.all|=0x100;      // Issue PIE ACK
}

interrupt void sciaRxFifoIsr(void)
{
    Uint16 i;
        for(i=0;i<8;i++)
        {
           rdataA=SciaRegs.SCIRXBUF.all;         // Read data
        }
        for(i=0;i<8;i++)                     // Check received data
        {
           if(rdataA != ( (rdata_pointA+i) & 0x00FF) ) error();
        }
        rdata_pointA = (rdata_pointA+1) & 0x00FF;

        SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear Overflow flag
        SciaRegs.SCIFFRX.bit.RXFFINTCLR=1;   // Clear Interrupt flag

        PieCtrlRegs.PIEACK.all|=0x100;       // Issue PIE ack
}

void scia_fifo_init()
{
   SciaRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
                                  // No parity,8 char bits,
                                  // async mode, idle-line protocol
   SciaRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,
                                  // Disable RX ERR, SLEEP, TXWAKE
   SciaRegs.SCICTL2.bit.TXINTENA =1;
   SciaRegs.SCICTL2.bit.RXBKINTENA =1;
   SciaRegs.SCIHBAUD = 0x0000;
   SciaRegs.SCILBAUD = SCI_PRD;
   SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
   SciaRegs.SCIFFTX.all=0xC028;
   SciaRegs.SCIFFRX.all=0x0028;
   SciaRegs.SCIFFCT.all=0x00;

   SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset
   SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;
   SciaRegs.SCIFFRX.bit.RXFIFORESET=1;


}


假如我想用TXFIFO的话,例如一次发16个字节,应该怎么配置SCIFFTXA寄存器呢?
怎么配置,这个看书,看datasheet都可以得到答案,我就不帮你查书了

用TXFIFO的话,可以不用一个字节一个字节等待发送完毕,一次性写入16个字节就可以啦,这样理解对吧?
你理解的对,这样可以减少中断次数,提高效率

出0入0汤圆

发表于 2009-4-15 14:11:51 | 显示全部楼层
首先万分感谢楼主的热心解答!!!
可是我的问题还是没有解决。SCIA模块其他的寄存器都没有什么问题,我也会配置。
就是这个SCIFFTXA寄存器,工作状态和TI的手册描述的不一样呀!
现在问题的核心在于使能TXFIFO后,执行SCIFFTXA |= BIT6;
调试程序,下断点观察SCIFFTXA 寄存器执行这句后,发现根本没有清除掉bit7的TXFIFO中断标志,导致重复进入发送中断。
可数据手册里面写的很清楚,想要清除TXFIFO发送级别匹配中断的FLAG(BIT7),就是通过向BIT6写1实现清零。
可我试过很多次了,向BIT6写1之后,BIT7的TXFIFO发送中断标志位根本没有清除,仍然保持为1.
无奈了

出0入0汤圆

 楼主| 发表于 2009-4-15 14:19:46 | 显示全部楼层
楼上用TI的scia_loopback_interrupts例子试一下可好?如果TI的原版例子也有问题,那么我晚上可以实际测试一下。

出0入0汤圆

 楼主| 发表于 2009-4-15 14:31:15 | 显示全部楼层
TI的2812外设例程ourdev_436636.zip(文件大小:812K) (原文件名:sprc097.zip)

出0入0汤圆

发表于 2009-4-15 16:33:45 | 显示全部楼层
先感谢楼主,在说明调试过程。谢谢楼主!!!

TI的例程也有问题,我把开发板的串口A连接到了电脑,用串口调试助手观察收到的数据,也发现了一些不理解的现象。
源代码修改了下面一句,重新定义串口通讯的波特率,以便于和上位机通讯
#define SCI_FREQ          115200(源代码为#define SCI_FREQ 100E3,但这个波特率无法和上位机通讯,所以修改了)

例程一开始运行,就不停的发送数据,在发送数据的sciaTxFifoIsr()中下断点,断点处语句为

SciaRegs.SCIFFTX.bit.TXINTCLR=1;        // Clear SCI Interrupt flag
(以下简称的执行前,执行后,都是说的执行这条语句前和执行这条语句后。)

查看执行这条语句前后SCIFFTX寄存器的内容变化如下。
1.第一次进入中断,执行前0xE7A8,执行后0xE7A8,寄存器内容无变化(注意,BIT7没有被清零)。上位机的串口调试助手收到0个数据。
2.第二次进入中断,执行前0xEFA8,执行后0xEF28,寄存器内容有变化(注意,BIT7被清零了)。上位机的串口调试助手收到0个数据
3.第三次进入中断,执行前0xF0A8,执行后0xF028,寄存器内容有变化(注意,BIT7被清零了)。上位机的串口调试助手收到7个数据,分别为00 01 02 03 04 05 06。
4.第四次进入中断,执行前0xF0A8,执行后0xF028,寄存器内容有变化(注意,BIT7被清零了)。上位机的串口调试助手收到8个数据,分别为07 01 02 03 04 05 06 07。
以后循环3,4步的过程。

疑问来了,这样的FIFO发送,怎么用呢?
第一次进入中断,向SciaRegs.SCITXBUF中写入了8个数据,一个也没发出去。
第二次进入中断,再向SciaRegs.SCITXBUF中写入了8个数据,发出去了7个,发送的数据是上一次中断中写入的前7个数据00~06,少发了最后一个07。
第三次进入中断,终于正常了,SciaRegs.SCITXBUF中写入了8个数据,发出去了8个,但是发送的数据,是上一次8个数据的最后一个07,和这一次循环的01~07),BIT7的中断标志也可以正常清零了。

可是和我理解的向SciaRegs.SCITXBUF中写入了8个数据,就发8个数据,完全不一样呀。

出0入0汤圆

发表于 2009-4-15 23:02:08 | 显示全部楼层
12楼iceyfire
  你好;
  我也发现类似的问题;
  调试RXFIFO时,产生问题可以解释:当ScibRegs.SCIFFRX.bit.RXFFIL = 0x06;PC机发送字节数为6时,正常接收到全部,发送字节数4 ,不产生中断,然后PC机再发送2个字节,这时产生中断,如果PC机发送8个字节,产生中断,不过只接受前六个字节;
  但是在调试TXFIFO时,产生问题就无法解释了,和12楼发现问题类似,期待高手解释;

出0入0汤圆

 楼主| 发表于 2009-4-15 23:08:34 | 显示全部楼层
第一次进入中断,向SciaRegs.SCITXBUF中写入了8个数据,一个也没发出去。
这个正常,写进FIFO并不意味着发出去了

第二次进入中断
此时第一次写的8个数据已经从FIFO里移出了,FIFO此时空,实际计算机收到7个数据,我理解为发送寄存器中还有一个

第三次及以后均正常了

**********************************
我做了个测试,就是第一次进中断后写8个数据到FIFO,以后中断就不写了,实际是可以收到0-7数据的,也就是说第二次进中断你就可以认为第一次写的8个数据已经成功发送出去了,实际也是这样的

因为DSP中断后,会将CPU挂起,所以第8个字节有可能在发送寄存器里,计算机暂时接收不到
如果是ARM就不会有这个问题了

注意点:使用FIFO时,发送中断是FIFO空中断;

出0入0汤圆

发表于 2009-4-15 23:19:08 | 显示全部楼层
楼主:
  你好:
  在看苏奎峰等编著《TMS320F2812原理与开发》这本书时,第114页介绍SCI FIFO发送(SCIFFTX)寄存器功能描述,当TXFFIL4~0大于或等于状态TXFFST4~0时,发送FIFO将产生中断;
  是不是可以这样理解,如果我把TXFFIL设置为6时,只要一发送1个字节(符合TXFFIL4~0大于或等于状态TXFFST4~0条件)就产生中断,那是不是就起不到用FIFO的初衷(减少中断次数)?

出0入0汤圆

 楼主| 发表于 2009-4-16 09:32:38 | 显示全部楼层
15楼,你好

如果我把TXFFIL设置为6时,发送FIFO中数据个数小于或者等于6就会产生中断了,但是FIFO有16个那么多哦,所以相对于产生16次中断,产生6次中断还是减少了中断次数的,TXFFIL在复位后默认值为0,也就是FIFO为空时才中断

实际使用中,你根据需要设置TXFFIL值就可以了

出0入0汤圆

 楼主| 发表于 2009-4-16 09:40:08 | 显示全部楼层
28X的SCI FIFO和我最近使用的ARM的FIFO不太一样,ARM中可以设置FIFO的长度,也就是说可以只使用4个字节、8个字节或者其他长度的FIFO,FIFO空了就会中断。
但28X中,我理解是16个FIFO一直都可以使用,但是可以设置发送FIFO在还剩下多少个数据时产生中断,TI的文档对这个部分说明不是太详细,大家多实践吧

出0入0汤圆

发表于 2009-4-16 10:58:56 | 显示全部楼层
但是楼主你贴的TI的例程里面讲TXFFIL设置成8,那么如果我一次向FIFO里面写入8个数据的话,是不是每次都会产生中断呢?

出0入0汤圆

发表于 2009-4-16 11:02:46 | 显示全部楼层
还有想请教一下,是不是这8个字符会连续发送出去?在这8字符没有发送完成的过程中,还会产生发送中断吗?

出0入0汤圆

 楼主| 发表于 2009-4-16 11:49:37 | 显示全部楼层
天才杨威利
你有仿真器的哦,自己实践一下吧

出0入0汤圆

发表于 2009-4-16 20:11:49 | 显示全部楼层
谢谢楼主了,出去调试啦,现在手头没有仿真器。明天按楼主的思路调试一下,在看看结果。
楼主真是热心人,呵呵,谢谢

出0入0汤圆

发表于 2009-4-16 20:15:40 | 显示全部楼层
楼主:
   谢谢楼主不吝赐教;
   我在网上看了一些关于Modbus485协议的评论,说是先要制订一份Mosbus登记表,记录各个寄存器对应的地址,因为标准Modbus协议面向寄存器地址,可以把不同变量映射到Mosbus登记表记录的地址。想打听一下楼主有没有按照标准Modbus协议来编制通讯程序模块,或者框架。给初学者我指点一下。

出0入0汤圆

 楼主| 发表于 2009-4-16 22:55:17 | 显示全部楼层
MODBUS还是比较简单的,有个freemodbus的开源软件,可以找来看看
还有一个叫 modbus poll的软件,也很不错哦,我做的时候就是用这个软件测试

基础就是UART发送接受,就象你会开车,现在要你按照指定路线开,并不复杂的

出0入0汤圆

发表于 2009-4-17 10:00:53 | 显示全部楼层
谢谢楼主指点
  我去看看

出0入0汤圆

发表于 2009-4-17 15:20:54 | 显示全部楼层
请教一下AD中的CONVnn中的nn代表什么意思呢?我知道他是选择要采样的引脚。CONV11=0X07表示转换在ADCINA7和ADCINB7(同步采样)。
因此我想请教一下CONV11中的11代表什么意思?

出0入0汤圆

发表于 2009-4-19 17:01:58 | 显示全部楼层
我在文件1.C中定义了一个位定义结构体
struct
{
   unsigned   acc:1;
   unsigned   dec:1;
   unsigned   stopmod:2;
   unsigned   dirsel:1;
   unsigned   dirfor:1;
   unsigned   save:1;

}runcon4_flag;

想在2.C操作这个变量,就在2.C顶头 extern struct runcon4_flag;
但是编译不通过;
提示:
"2.c", line 226: error: identifier "runcon4_flag" is undefined

然后 我保留 extern struct runcon4_flag;
删除在2.C引用runcon4_flag,再编译,就编译通过,不过警告“"Modbus.c", line 23: warning: a storage class may not be specified here”,我双击它,就跳转到 “extern struct runcon4_flag;”

请问大侠这是怎么回事啊,

出0入0汤圆

 楼主| 发表于 2009-4-19 18:32:21 | 显示全部楼层
26楼,这个你参考一下DSP28xx_Gpio.h中结构体的用法

出0入0汤圆

 楼主| 发表于 2009-4-19 18:36:08 | 显示全部楼层
25楼,请参考
TMS320x280x DSP
模数转换器(ADC)
参考指南

SPRU716.pdf

出0入0汤圆

发表于 2009-4-19 21:58:05 | 显示全部楼层
请教楼主DX下
我用2808,但现在可以调试,运行OK
但我下载到FLASH中,就不运行了`
只是个普通的LED程序,我参考模板写的

出0入0汤圆

 楼主| 发表于 2009-4-20 08:59:30 | 显示全部楼层
29楼
要将程序在FLASH中运行,需要注意
1.编译模式选release
2.必须初始化FLASH

        //设置FLASH寄存器程序调入RAM中运行
        MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
       
        InitFlash();

关于FLASH中运行,可以参考TI例程中的FLASH示例

出0入0汤圆

发表于 2009-4-20 09:43:37 | 显示全部楼层
谢谢LZ回答
我是在release 中编译的,也
运行了 MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
         
        InitFlash(); 两个函数
这两个函数直接用的原来模板的,是没有问题的
`奇怪哈~
对了,我用的板子应该是在楼主这买的,
就是那个 TMS320F2808开发板(买DSP开发板送仿真器)
我现在使用它的程序模板,自己建立了一个项目,把模板中的文件都加了进去
同样的main.c在模板环境下可以,可以烧到FLASH中运行
在我的项目中就只可以调试,
我基本上能修改都改了,应该和模板没什么区别了~
现在只是个简单的LED闪烁程序
麻烦DX给看一下~不胜感谢!
点击此处下载 ourdev_438034.rar(文件大小:385K) (原文件名:BLDC.rar)

出0入0汤圆

 楼主| 发表于 2009-4-20 11:54:49 | 显示全部楼层
那你用光盘里综合实验的工程做模板,在其基础上添加自己的代码吧

出0入0汤圆

发表于 2009-4-20 13:58:30 | 显示全部楼层
谢谢楼主回答~
我知道问题出那了
我少加了个 DSP280x_CodeStartBranch.asm 文件,没有这个文件,编译也不回出错~
奇怪哈,不知道这文件是做什么的?

楼主的板子不错,程序写的满好的~我现在就用的楼主的模板程序~呵呵~DSP不简单哈~

出0入0汤圆

 楼主| 发表于 2009-4-20 20:54:17 | 显示全部楼层
感谢楼上的肯定
不过我个人认为,DSP并不难,难的是基于DSP的应用,不管是ARM、DSP、51或者其他CPU,从使用CPU的角度来说都差不多,道理也是相通的。就象从南京到上海,可以采用步行、自行车、汽车等等交通方式,但前提是你必须知道路线(对你的目标应用要熟悉),用何种交通方式,只是效率问题。

另,最近新增了12864图形LCD的程序,需要可以best2002@vip.sina.com索取,效果如下,控制器为SED1565兼容

(原文件名:12864s.jpg)

出0入0汤圆

发表于 2009-4-22 13:51:19 | 显示全部楼层
各位老师,问下MODBUS通讯,(DSP做从机),上位机在给下位机发指令要求数据的时候,modbus协议中的寄存器地址是怎么定义的,下位机中开关量的地址是一个虚拟的吗,就是定义一个表示开关量的位变量,这个变量就是那个地址,不过是由编译器临时分配的吧,那是不是我们上位机的协议中这个寄存器地址是怎么回事呢,他和下位机的这个是怎么连接的呢 。
请教一下,谢谢!

出0入0汤圆

发表于 2009-4-22 21:07:49 | 显示全部楼层
在请教楼主下
CMD文件中的 .cinit              : > FLASHA      PAGE = 0
   .pinit              : > FLASHA,     PAGE = 0
   .text               : > FLASHA      PAGE = 0
   codestart           : > BEGIN       PAGE = 0
  .cinit              : > FLASHA      PAGE = 0
   .pinit              : > FLASHA,     PAGE = 0
   .text               : > FLASHA      PAGE = 0
   codestart           : > BEGIN       PAGE = 0
   ramfuncs            : LOAD = FLASHD,
                         RUN = RAML0,
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         PAGE = 0                         RUN = RAML0,
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         PAGE = 0
是把FLASH的程序烤到RAML0中运行
但我看RAML0只有4K,如果程序大过4K怎么办?

怎么让程序都在FLASH中运行?
这样修改可以不?
ramfuncs            : > FLASHD, PAGE = 0
谢谢了`

出0入0汤圆

 楼主| 发表于 2009-4-22 22:59:20 | 显示全部楼层
先出差,回来再说^-^

出0入0汤圆

 楼主| 发表于 2009-4-23 10:33:22 | 显示全部楼层
RAM不够的话,可以换大块的RAM区
你定义了ramfuncs才需要执行COPY到RAM的操作,没定义的话,默认就是在FLASH里执行的。

以下是一个例子,其他论坛找来的,可以参考一下
1cmd定义:



ramfuncs            : LOAD = FLASHJ,  PAGE = 0

                         RUN = RAMH0,  PAGE = 0

                         LOAD_START(_RamfuncsLoadStart),

                         LOAD_END(_RamfuncsLoadEnd),

                         RUN_START(_RamfuncsRunStart)



secureRamFuncs    :   LOAD = FLASHP,   PAGE = 0          /* Used by InitFlash() in SysCtrl.c */

                         RUN =  RAMH0 ,   PAGE = 0

                         LOAD_START(_secureRamFuncs_loadstart),

                         LOAD_END(_secureRamFuncs_loadend),

                         RUN_START(_secureRamFuncs_runstart)



2定义变量(装载或运行的起始地址)

extern Uint16 RamfuncsLoadStart;

extern Uint16 RamfuncsLoadEnd;

extern Uint16 RamfuncsRunStart;





extern Uint16 secureRamFuncs_runstart;

extern Uint16 secureRamFuncs_loadstart;

extern Uint16 secureRamFuncs_loadend;



3把要拷贝到RAM里的函数(eva_timer1_isr,eva_timer2_isr...)定义到段ramfuncs



  #pragma CODE_SECTION(eva_timer1_isr, "ramfuncs");

  #pragma CODE_SECTION(eva_timer2_isr, "ramfuncs");

  #pragma CODE_SECTION(evb_timer3_isr, "ramfuncs");

4把要初始化的flash控制寄存器函数定义到段secureRamFuncs

#pragma CODE_SECTION(InitFlash, "secureRamFuncs")

void InitFlash(void);

// 声明中断函数

  interrupt void eva_timer1_isr(void);

  interrupt void eva_timer2_isr(void);

  interrupt void evb_timer3_isr(void);

  interrupt void evb_timer4_isr(void);

//初始化flash 控制寄存器函数为

void InitFlash(void)

{

        asm(" EALLOW");                                                                       // Enable EALLOW protected register access

        FlashRegs.FPWR.bit.PWR = 3;                                                // Pump and bank set to active mode

        FlashRegs.FSTATUS.bit.V3STAT = 1;                                // Clear the 3VSTAT bit

        FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF;        // Sleep to standby transition cycles

        FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF;        // Standby to active transition cycles

        FlashRegs.FBANKWAIT.bit.RANDWAIT = 5;                        // Random access waitstates

        FlashRegs.FBANKWAIT.bit.PAGEWAIT = 5;                        // Paged access waitstates

        FlashRegs.FOTPWAIT.bit.OPTWAIT = 5;                                // Random access waitstates

        FlashRegs.FOPT.bit.ENPIPE = 1;                                        // Enable the flash pipeline

        asm(" EDIS");                                                                        // Disable EALLOW protected register access



/*** Force a complete pipeline flush to ensure that the write to the last register

     configured occurs before returning.  Safest thing is to wait 8 full cycles. ***/



    asm(" RPT #7 || NOP");

}

//复制中断向量到ram的函数为

void InitPieVectTable(void)

{

        int16        i;

        Uint32 *Source = (void *) &ieVectTableInit;

        Uint32 *Dest = (void *) &ieVectTable;

               

        EALLOW;        

        for(i=0; i < 128; i++)

                *Dest++ = *Source++;         



        EDIS;



        // Enable the PIE Vector Table

        PieCtrl.PIECRTL.bit.ENPIE = 1;        

                        

}

4.在主函数中执行调用以下函数



        /*初始化PIE矢量表*/

        InitPieVectTable();        



     memcpy(  &secureRamFuncs_runstart,

               &secureRamFuncs_loadstart,

                 &secureRamFuncs_loadend - &secureRamFuncs_loadstart);

   

      InitFlash();

memcpy(  &RamfuncsRunStart,

                 &RamfuncsLoadStart,

                 &RamfuncsLoadEnd - &RamfuncsLoadStart);

出0入0汤圆

 楼主| 发表于 2009-4-23 11:03:17 | 显示全部楼层
35楼的问题
MODBUS中地址表是你自己定义的,只要每个地址可以对应一个数据就可以了

出0入0汤圆

发表于 2009-4-23 12:27:46 | 显示全部楼层
谢谢楼主了哈~

出0入0汤圆

发表于 2009-4-23 16:30:37 | 显示全部楼层
郁闷死了,老板让我编写Modbus通讯程序,编译通过,就是调试不通,程序是从网上下的;然后改了一些地址映射;麻烦大侠指点一下
/********Modbus.h ********/


#ifndef MODBUS_H
#define MODBUS_H


#ifdef __cplusplus
extern "C" {
#endif

typedef unsigned char boolean; /* Boolean value type. */
typedef unsigned long int uint32; /* Unsigned 32 bit value */
typedef unsigned short uint16; /* Unsigned 16 bit value */
typedef unsigned char uint8; /* Unsigned 8 bit value */
//typedef signed long int int32; /* Signed 32 bit value */
//typedef signed short int16; /* Signed 16 bit value */
typedef signed char int8; /* Signed 8 bit value */


//------------MODBUS CMD-----------------------
//#define READ_N_COIL      01
//#define READ_N_DI        02
#define READ_HLD_REG     03
//#define READ_AI          04
//#define SET_1_COIL       05
//#define SET_1_HLD_REG    06
//#define SET_N_COIL       15
#define SET_N_HLD_REG    16

//------------UART_MODULE.Status---------------
#define IDLE_WAIT        0x00        // 空闲态,等待起始位
#define RECE_START       0x01        // 收到起始位,等待结束位
#define RECE_END         0x02        // 收到结束位,等待发送
#define SEND_START       0x03        // 发送起始位
#define SEND_END         0x04        // 发送完毕

//------------MODBUS REGS-----------------------
/*ModBus 寄存器缓冲区起始绝对地址,位于L1SARAM
ModBus 寄存器缓冲区0x009F00~0x009FFF,总长度256个字长度,512个字节 */

#define MBRRegAdd   0x009F00
/*只读寄存器
起始地址:0x009F00;
长度    :0x20
*/
#define MBDriveVerB6   *(int *)(MBRRegAdd)/* 传动型号寄存器组 */
#define MBSoftVerBt6   *(int *)(MBRRegAdd+0x03)/* 软件版本寄存器组 */
#define MBSoftVerBt8   *(int *)(MBRRegAdd+0x06)/* 出厂编号寄存器组 */
#define MBStatusReg1_2 *(int *)(MBRRegAdd+0x0A)/* 状态寄存器1 */
#define MBStatusReg2_2 *(int *)(MBRRegAdd+0x0B)/* 状态寄存器2 */
#define MBStatusReg3_2 *(int *)(MBRRegAdd+0x0C)/* 状态寄存器3 */
#define MBStatusReg4_2 *(int *)(MBRRegAdd+0x0D)/* 状态寄存器4 */
#define MBStatusReg5_2 *(int *)(MBRRegAdd+0x0E)/* 状态寄存器5 */
#define MBStatusReg6_2 *(int *)(MBRRegAdd+0x0F)/* 状态寄存器6 */
#define MBFreqOut_4    *(int *)(MBRRegAdd+0x10)/* 实际频率输出寄存器 */


/*可读写寄存器*/
#define  MBRWRegAdd 0x009F20
/*读写寄存器
起始地址:0x009F20;
长度    :0x10;
*/


/*EEPROM寄存器*/
/*可读写
起始地址:0x009F30;
长度    :0xCF;
*/
#define  MBEEPROMRegAdd 0x009F30





// ------------功能指令----------------------------
#define WORD_LO(xxx) ((char)((int)(xxx) & 255))/* 得到一个字的低位*/
#define WORD_HI(xxx) ((char)((int)(xxx) >> 8)) /* 得到一个字的高位*/
//#define B_PTR(var) ((char *)(void *) &(var))  /*得到一个变量的地址(word宽度)*/
#define W_PTR(var) ((int *)(void *) &(var)) /*得到一个变量的地址(word宽度)*/
//#define MEM_B(x) (*( (char *)(x))) /*得到指定地址上的一个字节*/
#define MEM_W(x) (*( (int *)(x))) /*得到指定地址上的一个字*/





// 定义MODBUS数据结构
struct MODBUSDATA
{
  unsigned int ID;
  unsigned int FunCode;
  unsigned int RegAdd;
  unsigned int RegNum;
  unsigned int Buf[128];
  unsigned int Status;
  unsigned int TxLen;
  unsigned int RxLen;
  unsigned int Point;
  unsigned int TimeoutReg;
  unsigned int TimeoutCounter;
};

//--------------------供外部调用函数-------------------------------

extern struct MODBUSDATA ModbusModule;
extern void ConfigureModbus(Uint16 brat,Uint16 SwitchRate);
extern void ModbusRTUSlaveRun(void);
#ifdef __cplusplus
}
#endif /* extern "C" */

#endif  // end of DSP280x_SCI_H definition

//===========================================================================
// End of file.
//===========================================================================


// SC File $Revision:
// Checkin $Date:
//###########################################################################
//
// FILE:  Modbus.c
//
// TITLE:  
//
//###########################################################################
// $TI Release:
// $Release Date:


#include "DSP280x_Device.h"     // DSP280x Headerfile Include File
#include "DSP280x_Examples.h"   // DSP280x Examples Include File

#include "Modbus.h"

const unsigned char  auchCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
} ;
/* CRC低位字节值表*/
const unsigned char  auchCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
} ;

struct MODBUSDATA ModbusModule;

// -------Modbus初始化----------0
void ConfigureModbus (void)
{
Uint16 i;
Uint16  *dest_p;
dest_p=((Uint16*)MBRRegAdd);
for(i=0;i<256;i++)
    {
    *(dest_p+i)=0x0000;
    }
ModbusModule.TxLen  = 0;
ModbusModule.RxLen  = 0;
ModbusModule.Point  = 0;
//ModbusModule.ReTryTime =0;
ModbusModule.ID  = 2;
ModbusModule.Status = SEND_END;
}//

/*
interrupt void ScibTxInt (void)      // SCI-B
{
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
if( ModbusModule.TxLen > 0 ){
            ScibRegs.SCITXBUF= ModbusModule.Buf[ModbusModule.Point++];
            ModbusModule.TxLen--;
//            ModbusModule.Point++;
//            ModbusModule.Point %= 128; //
}else{  //发送完毕
            ModbusModule.Status = SEND_END;   //状态切换
   ModbusModule.Point=0;
   ModbusModule.TimeoutReg=0;
    }
}
*/
/*
//---------------------------------------------
// ScibRxInt MODBUS RTU
// 以两字符时间停顿为3.5个字符时间
// 程序用5ms时间判断 对应9600--5个字符时间
// 程序帧结束数据在主程序里面处理
//3.5字符数计数器公式:
//设波特率为 int BtRate(4800;9600;19200;)
//设开关频率volatile int SwitchRate(1K~20K,单位为KHZ)
//设3.5字符时间为delay3.5 =(int)(3.5*10*1000/BtRate);
//计数器Timeout3.5=delay3.5*SwitchRate;
//---------------------------------------------
interrupt void ScibRxInt (void)      // SCI-B
{
Uint16  temp;
PieCtrlRegs.PIEACK.bit.ACK9 = 1; //ACK复位
temp=ScibRegs.SCIRXBUF.all;

switch( ModbusModule.Status ){
  case SEND_END:      //4
   ModbusModule.Status = RECE_START;
   ModbusModule.Point=0;
  case RECE_START:     //1
   ModbusModule.Buf[ModbusModule.Point] = temp;
   ModbusModule.Point++;
   ModbusModule.RxLen = ModbusModule.Point;
   break;
}
ModbusModule.TimeoutReg=0;
}
*/
//---------------------------------------------
//  程序第二部分:MODBUS 协议解析与构造
// CRC16
// 协议帧构造
// 协议帧解析
//---------------------------------------------
//---------------------------------------------
// CRC16 calculate
// <-Modbus Protocol English pdf
// ptr calculate start point
// len calculate data length
//---------------------------------------------

Uint16 GetCRC16 (Uint16 volatile * puchMsg,Uint16 usDataLen)
{
        unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化 */
        unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */
        Uint32 uIndex ; /* CRC循环中的索引 */
        while (usDataLen--) /* 传输消息缓冲区 */
        {
                uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */
                uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
                uchCRCLo = auchCRCLo[uIndex] ;
        }
        return (uchCRCHi << 8 | uchCRCLo) ;
}//uint16 crc16(uint8 *puchMsg, uint16 usDataLen)

//---------------------------------------------
// RTU Set N Hold Register
// CMD=16 SET_N_HLD_REG
// Constructe Answer Frame
//---------------------------------------------
void  ModbusSlaveSetNHldRegAnswer ( Uint16 board_adr,Uint16 start_address,Uint16 lenth)
{
Uint16 i=0,j=0;

ModbusModule.Buf[i++] = board_adr;
ModbusModule.Buf[i++] = SET_N_HLD_REG;
ModbusModule.Buf[i++] = WORD_HI(start_address);
ModbusModule.Buf[i++] = WORD_LO(start_address);
ModbusModule.Buf[i++] = WORD_HI(lenth);
ModbusModule.Buf[i++] = WORD_LO(lenth);
j=GetCRC16(ModbusModule.Buf,i);
ModbusModule.Buf[i++] = WORD_LO(j);
ModbusModule.Buf[i++] = WORD_HI(j);
ModbusModule.TxLen    = i;
ModbusModule.Point   = 0;
}

//---------------------------------------------
// RTU Read Hold Register
// CMD=03 READ_HLD_REG
// Constructe Answer Frame
//---------------------------------------------
void  ModbusSlaveReadHldRegAnswer ( Uint16 board_adr,Uint16 *com_buf,Uint16 lenth)
{
Uint16 i=0,j=0;

ModbusModule.Buf[i++] = board_adr;
ModbusModule.Buf[i++] = READ_HLD_REG;
ModbusModule.Buf[i++] = lenth<<1;
for(j=0;j<lenth;j++){
  ModbusModule.Buf[i++] = WORD_HI( * (com_buf+j) );
  ModbusModule.Buf[i++] = WORD_LO( * (com_buf+j) );
}
j=GetCRC16(ModbusModule.Buf,i);
ModbusModule.Buf[i++] = WORD_LO(j);
ModbusModule.Buf[i++] = WORD_HI(j);
ModbusModule.TxLen    = i;
ModbusModule.Point   = 0;
}

//---------------------------------------------
// RTU  从站接收分析
// 3 READ_HLD_REG
// 16 SET_N_HLD_REG
// 返回值: 0  OK
//    1 CRC校验错误
//    2 站号不匹配
//    3 读地址无效
//    4 16写地址不匹配
//    5 16写数据字数不匹配
//---------------------------------------------
Uint16 RTUSlaveFrameAnalyse (void)
{
Uint16 i;
Uint16  *dest_p;
Uint16 crc_result, crc_tmp;
Uint16 RegNum;
int16  RegAddr;
crc_tmp  = ModbusModule.Buf[ModbusModule.RxLen-1]<<8;
crc_tmp += ModbusModule.Buf[ModbusModule.RxLen-2];
crc_result=GetCRC16(ModbusModule.Buf,ModbusModule.RxLen-2);
if ( crc_tmp != crc_result )       // CRC 校验正确
    {
        return 1;
    }
if ( ModbusModule.ID != ModbusModule.Buf[0] )
    {
        return 2;
    }
ModbusModule.FunCode=ModbusModule.Buf[1];
RegAddr= (ModbusModule.Buf[2]<<8) + ModbusModule.Buf[3]-0x4000;
RegNum = (ModbusModule.Buf[4]<<8) + ModbusModule.Buf[5];
switch (ModbusModule.FunCode)
   {      
    case READ_HLD_REG: //3
             if(RegAddr>0xFF||RegAddr<0) return 3;
                 if((RegAddr+RegNum-1)>0xff) return 3;
                 dest_p=((Uint16*)(MBRRegAdd+RegAddr+RegNum-1));
         ModbusSlaveReadHldRegAnswer(ModbusModule.ID,dest_p,RegNum);
         break;
    //case SET_1_HLD_REG: //6
             
    case SET_N_HLD_REG: //16
         if(RegAddr>0x2F||RegAddr<0x20) return 4;
         if((RegAddr+RegNum-1)>0x2f)    return 4;
         if((RegNum<<1) != ModbusModule.Buf[6])return 4;
         dest_p=((Uint16*)(MBRRegAdd+RegAddr+RegNum-1));
         for (i=0; i<ModbusModule.Buf[6]; i+=2)
            {
             *(dest_p + i/2) = ( ModbusModule.Buf[i+7]<<8 ) + ModbusModule.Buf[i+8];
            }
         ModbusSlaveSetNHldRegAnswer(ModbusModule.ID,RegAddr,RegNum);   
         break;
    }//end switch
return 0;
}
//---------------------------------------------
// ModbusRTUSlaveRun
// 通讯由主站发起,从站初始化为接收,并相应的做出回应。
// 站号在初始化中有设置,以后不再更改。
//---------------------------------------------
void ModbusRTUSlaveRun (void)
{

switch (ModbusModule.Status){
  case IDLE_WAIT ://0
   ScibRegs.SCITXBUF = ModbusModule.Buf[ModbusModule.Point++];
   ModbusModule.TxLen--;
   ModbusModule.Status = SEND_START;
   break;
  case SEND_START ://3
   asm("nop");
   break;
  case SEND_END ://4
   if (ModbusModule.TimeoutReg>=10)
   {  //超时10ms
    //ModbusModule.ReTryTime++;
    ModbusModule.TimeoutReg=0;
    //InitSci_B(); //***********
   }
   break;
  case RECE_START ://1
   if (ModbusModule.TimeoutReg>=5)
   {  //接收帧结束
    ModbusModule.Status = RECE_END;
   }
   break;
  case RECE_END ://2
   if(RTUSlaveFrameAnalyse()==0 )
    {//帧解析正确
     ModbusModule.Status =IDLE_WAIT;
    }
   else
    {          //帧解析不正确
     ModbusModule.Status =SEND_END;
    }
   break;
  }
}

出0入0汤圆

发表于 2009-4-23 16:38:11 | 显示全部楼层
void ModbusRTUSlaveRun (void) ;函数我放在一个定时器中断里不断查询状态;ModbusModule.TimeoutReg计数器放在一个EPWM定时器中断里(优先级最高,保证计数准确性);使能串口接受中断,发送中断,调试时只在主循环循环,不进入串口中断,急啊

出0入0汤圆

发表于 2009-4-23 16:53:30 | 显示全部楼层
这么久了,才又有机会调试F2812的SCI模块。
虽然还是不能完全理解它的TX FIFO模块的工作原理,但是现在基本可以用了。
SCI-B的配置如下:
        // Initialize SCI-B:
        ScibRegs.SCICCR.all = 0x0007;    // 1 stop bit,  No loopback
                                   // No parity,8 char bits,
                                   // async mode, idle-line protocol
        ScibRegs.SCICTL1.all = 0x0003;   // enable TX, RX, internal SCICLK,
                                   // Disable RX ERR, SLEEP, TXWAKE
        ScibRegs.SCICTL2.bit.TXINTENA = 1;
        ScibRegs.SCICTL2.bit.RXBKINTENA = 1;
        ScibRegs.SCIHBAUD = SCIBBAUDH;
        ScibRegs.SCILBAUD = SCIBBAUDL;//波特率是9600的,和电脑的串口调试助手联机调试方便
        //ScibRegs.SCICCR.bit.LOOPBKENA = 1; // 不开自测试模式,因为是和电脑实际的联机调试的
        ScibRegs.SCIFFTX.all = 0xC020;
        ScibRegs.SCIFFRX.all = 0x0025;
        ScibRegs.SCIFFCT.all = 0x00;
        SciaRegs.SCIPRI.all = 0x10;

        ScibRegs.SCICTL1.all = 0x0023;     // Relinquish SCI from Reset
        ScibRegs.SCIFFTX.bit.TXFIFOXRESET = 1;//打开这个,SCIB就会进入发送中断,貌似复位时就会产生一个TXRDY中断
        ScibRegs.SCIFFRX.bit.RXFIFORESET = 1;
发送中断程序如下:
interrupt void SCITXINTB_ISR(void)     // SCI-B
{
        // Insert ISR Code here
        PerformScibTx();
         
        // ClearSCIB TxFiFo Interrupt flag
        ScibRegs.SCIFFTX.bit.TXINTCLR=1;   
        // To receive more interrupts from this PIE group, acknowledge this interrupt
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;

        // Next two lines for debug only to halt the processor here
        // Remove after inserting ISR Code
        //asm ("      ESTOP0");
        //for(;;);

}
发送数据函数如下:
定义了一个全局变量bool ScibTxFlag = true用来进行单次发送测试
void PerformScibTx(void)
{
      
    Uint16 i;
   
    if (ScibTxFlag == true)
    {
            for(i = 0; i < 8; ++i)
            {
                           ScibRegs.SCITXBUF = i;     // Send data
                }
                ScibTxFlag = false;
        }
        else ScibRegs.SCIFFTX.bit.TXFIFOXRESET = 0;
}
发送FIFO的级别为0,就是说发送FIFO为空时进入发送中断。
中断里面只写一次数据。
实际联机调试发现,程序运行后,会进入两次发送中断,第一次进入时,向TXFIFO写入了8个数据,程序完成第一次中断后,上位机收到7个数据,然后程序进入第二次发送中断,这次并不想TXFIFO中写入数据,程序完成第二次中断后,上位机收到了1个数据。两次发送中断,把自己想要发送的8位数据发送完成了。但是如果不TXFIFOXRESET = 0的话,程序会不停的进入发送中断,这个就无法理解了。
一句话,TI DSP的TXFIFO模块,用起来真是不同寻常,和别人的不一样。
谢谢楼主和各位兄弟的帮助啦。

出0入0汤圆

 楼主| 发表于 2009-4-23 20:58:32 | 显示全部楼层
关于MODBUS的问题,请另开一贴讨论,这个和CPU关系不大呢
建议到ARM或者AVR版块发贴,我虽然也做过,但实在没精力帮兄弟看程序了,见谅

出0入0汤圆

发表于 2009-4-24 10:39:56 | 显示全部楼层
楼主您好:
首先感谢您回复了这么多问题,看了十分有收获,现在我说下我的疑问 呵呵
我看书上说2812在启动时需要一个跳转向量跳转到_c_int00,这样才能跳转到c代码
我在烧写时验证了一下 确实是这样
但是当我load时我写的程序里根本没有跳转指令也能正常执行,也能正常进入main
这是怎么回事呢,是不是load和烧写时不一样呢?load时不需要跳转指令也会自动进入main函数吗?

出0入0汤圆

发表于 2009-4-24 12:14:18 | 显示全部楼层
非常有收获啊

出0入0汤圆

发表于 2009-4-24 12:43:19 | 显示全部楼层
看你的cmd里面,cint00在这里定义的

出0入0汤圆

发表于 2009-4-24 20:40:43 | 显示全部楼层
有关OSHT和CBC的疑问

请教一下2808的TZ模块中,有两个模式CBC和OSHT,但是对于他们的区别,TI的datasheet上并没有介绍得很清楚。因此有些不明吧。
第一CBC我知道好像是每个PWM周期都会检测一下引脚相关输入引脚的状态,如果状态为高电平,就恢复相应输入引脚的功能,但是这是相应的标志位:CBC和INT不会被清除,必须要手工清除,那么是不是着来年改革标志位不会再次出发中断了呢?
第二对于OSHT我不太明白是不是他一旦检测到输入引脚为地电平,就不会在周期性的检测相应输入引脚的状态了呢?
第三,CBC状态时不管我什么时候清除标志位,他都会只在CTR=0的时刻回复相应输出的功能,OSHT状态,什么时候能够解除呢?是不是只要我将相应的OST和INT标志位清零,他就会解除?
以上是我的是那个疑问,希望工程师能帮助解释就。

出0入0汤圆

 楼主| 发表于 2009-4-26 22:57:33 | 显示全部楼层
楼上的问题,十分抱歉,最近比较忙,没时间帮你查找资料了,自己先想想办法吧
5.1后我再来看这个问题。

出0入0汤圆

发表于 2009-4-27 15:03:05 | 显示全部楼层
已经解决了,虽然提问了,但是自己也在努力研究尝试,已经解决了。但还是感觉楼主。

出0入0汤圆

 楼主| 发表于 2009-4-27 22:37:53 | 显示全部楼层
楼上将你解决问题的方法发上来呀,大家共同进步,互相帮助

出0入0汤圆

发表于 2009-4-27 22:50:49 | 显示全部楼层
楼主帮我解决下我的问题阿,都把我跳过了..... 在发一下问题吧
楼主您好:
首先感谢您回复了这么多问题,看了十分有收获,现在我说下我的疑问 呵呵
我看书上说2812在启动时需要一个跳转向量跳转到_c_int00,这样才能跳转到c代码
我在烧写时验证了一下 确实是这样
但是当我load时我写的程序里根本没有跳转指令也能正常执行,也能正常进入main
这是怎么回事呢,是不是load和烧写时不一样呢?load时不需要跳转指令也会自动进入main函数吗?

出0入0汤圆

 楼主| 发表于 2009-4-28 20:35:18 | 显示全部楼层
呵呵,楼上不好意思啊
load和烧写时不一样
***********************************************************************
* Function: codestart section
*
* Description: Branch to code starting point
***********************************************************************

    .sect "codestart"

code_start:
    .if WD_DISABLE == 1
        LB wd_disable       ;Branch to watchdog disable code//load时执行这里
    .else
        LB _c_int00         ;Branch to start of boot.asm in RTS library//FLASH中执行这里
    .endif

出0入0汤圆

发表于 2009-4-29 08:03:07 | 显示全部楼层
请教楼主:
我做毕业设计,就用到F2812的SCI和打印机相连,能用DSP控制打印机。大概就是打印出银行的排队小票。可以说说思路,现在还是不太理解从哪改起。我有PC机与SCI通信的实验例子,就是PC机向2812传一个字符。

出0入0汤圆

 楼主| 发表于 2009-4-29 08:41:02 | 显示全部楼层
54楼
1、你需要了解打印机的控制协议,发送什么数据给它,会打印一个字符?发什么数据会换行?等等都要搞清楚
2、实现2812的SCI发送,这个TI有例子程序,楼上也有相关讨论的贴子可以参考
3、用2812实现协议,控制打印机

这个毕业设计难度并不大,只是用到了SCI而已

出0入0汤圆

发表于 2009-4-30 20:21:40 | 显示全部楼层
楼主:
我是54楼的,还是想再问一下,我现在不太清楚怎么将打印机的控制命令字通过SCI发给打印机,是用汇编和C语言混编的形式,用asm()的那个吗,问题有点弱,您说仔细一些,我之前没接触过这些,谢谢了。

出0入0汤圆

 楼主| 发表于 2009-4-30 21:18:10 | 显示全部楼层
楼上,你要先学会用SCI发送数据,就象你要和人交流,必须先学会说话一样。
至于怎么用SCI发送数据,TI有例程的哦,自己看一下,然后实际运行一下会有比较直观的了解

出0入0汤圆

发表于 2009-4-30 22:37:11 | 显示全部楼层
做板凳听听课!呵呵

出0入0汤圆

发表于 2009-5-1 17:41:41 | 显示全部楼层
CBC就是周期性的检测相应引脚的状态,每个周期结束的时候,如果相应的输入引脚为高电平,就会自动退出tz状态,相应的输出引脚回复pwm功能。这个我感觉很适合做限流。而OSHT就是一次触发模式,他是只要进入tz模式,除非手动清除标志位,否则不会退出tz模式。因此需要手动结束tz模式。以上是我试验以及和其他人讨论的结论,不知道对不对,发上来和大家一起分享。
另外之前我提过的SCI的fifo模式,也做了个实验,fifo如果设定成16个字节的话,每次发送的时候,可以使用for循环一次向TXBUF中写入16个数据。直到全部发送完成才会产生TX中断。同样接收的时候,只有到达了你设定的数量,才会产生中断,这是你可以通过for循环一次性的将全部数据读出。

但是有一点不太清楚,如果初始化的时候设定了fifo的发送中断时当发送缓冲器中的数据小于2(或者直接就是默认值0)就会产生中断,那在初始化完成后,实际上发送缓冲器中并没有数据,但是却没有出发中断,知道我第一次向其中写入数据才会出发中断,看到有一些例程里面可以通过清楚发送中断标志位来使能发送,而他仅仅在发送中断中才会将数据传输到发送缓冲器中。因此不太明白是不是在初始化完成后,通过清楚发送中断的标志位和将fifo功能使能位置一,就可以出发发送中断,然后直接通过中断将数据发送出去?
而在中断外部不需要先向发送缓冲器中写入一次数据?
以上就是我这几天的实验所得,希望大家能够一起讨论。

出0入0汤圆

 楼主| 发表于 2009-5-7 09:17:16 | 显示全部楼层
大家继续讨论,盖高楼

出0入0汤圆

发表于 2009-5-12 17:03:37 | 显示全部楼层
非常感谢楼主耐心指导,我也是在做SCI通信程序,碰到点问题,请楼主指导:
我看过很多例程,现在想编一个利用中断方式接收道不同指令后,由DSP回复相应内容的程序.于是我先制定了协议.我发现如果用FIFO发送接收的话,因为接收情况太多,所以我在接收中断里采用选择结构.但是发送的内容也不一样,在发送中断里也要相应的发出相对应的内容,这样一来,我有点束手无策了,请文楼主又没什么好方法呢?还有,就是FIFO只能传16个字节,而我要发20多个字节,我试了,如果就平常那样发的话,中间的数据会丢失,这也不好解决了...请楼主帮下,谢谢.

出0入0汤圆

发表于 2009-5-12 20:05:16 | 显示全部楼层
那你必须将这些命令变成16个字节,当然你可以使用一个变量来统计发送的个数,这样就可以接着上次的发送。

出0入0汤圆

 楼主| 发表于 2009-5-13 08:42:34 | 显示全部楼层
61楼,你将接收/发送数据都发到缓冲区,缓冲区可以开大一些,比如512字节。然后中断里只是把缓冲区数据发送出去,将接收数据放到接收缓冲区,这样中断里就比较简单了。
然后可以在其他地方判断缓冲区里的数据;一般是贞结束后再处理接受缓冲区里的数据

出0入0汤圆

发表于 2009-5-13 10:41:57 | 显示全部楼层
62楼,我这些要发的数据已经定好了,而且发的内容不会一样,长度定了,不能改了。。。
63楼,如果采纳楼主的意见,那意味着我不能用FIFO了吧,就只能用普通的中断吗?

出0入0汤圆

 楼主| 发表于 2009-5-13 10:52:43 | 显示全部楼层
一样可以用FIFO,并不冲突
比如你要运送货物到一个地方,如果把缓冲区比做火车(容量大),FIFO比做卡车
你可以直接用卡车送。
现在有火车了,你可以将所有东西先装到火车上,到达目的火车站后,再由卡车分别送到最终客户手里
这样对发送来说,就只要将货物送到火车站了,接收时只要从火车站取货然后使用

对于是否用FIFO,就是使用卡车还是人扛运送火车站的货物的问题,随便你了

出0入0汤圆

发表于 2009-5-13 19:39:56 | 显示全部楼层
楼上的意思还是分别发送(需要多个中断),但是你要判断如果接到了指定数量的指令,在一起冲数组或者缓冲区里读取。

出0入0汤圆

发表于 2009-5-13 23:03:33 | 显示全部楼层
哦~我现在已经实现接收到某一命令就发送相应数据的功能了。我的做法是在发送中断内加入选择结构,将发送与接收的内容对应。
其实我把要发送的数据都放在对应的数组里了,每次收到不同命令时就发送对应数组的内容,这是不是跟楼主说的分配一个缓冲区给数据一样,而接受的数据我也放在数组里了。
而且,据我的理解,用FIFO的话,拿发送来说,数据是先发到FIFO里,再到scitxbuf,这样一来,字节还是限制为16字节,一旦超过了时,我用串口调试时就发生中间部分缺失问题,不知道我的理解是不是正确,望大家指正和指导,谢谢。

出0入0汤圆

发表于 2009-5-14 15:18:40 | 显示全部楼层
每次最多发送16字节,如果超过这个大小就要分多次发送,要预先按照16字节规划一下。分多个发送中断发送。接受一样,可以使用结束标志,当接到结束标志的时候就意味着全部接受完成,然后就可以处理了

出0入0汤圆

发表于 2009-5-15 12:41:23 | 显示全部楼层
您好,我有2个问题:
1) F2812 里声明一个数组,有大小限制吗?
例如: A[400*80]   可以编译通过
       A[400*100]   编译出错
提示: error: the size of an array must be greater than zero
------------------------------------------------------------
2)  如果需要大数组的话,该什么处理呢?
------------------------------------------------------------
谢谢!~~

出0入0汤圆

发表于 2009-5-15 22:04:22 | 显示全部楼层
68楼:分多次发的话,是要将内容要分放在几个数组中吗,还是都放在一个数组里,发送先发16字节,发送完时未检测到结束标志再继续发。。这样又牵扯到另一个问题,每个数组都要有个结束标志了。请问结束标志可以定为那些字符?还有,我想在发送数据时在数据前加一位命令字,一位数据长度的话,直接加在数据所在的数组里的话,由于命令字和长度都是16进制的数字,而数据是字母的话,在定义这个数组时怎么定义,这是C的问题了,我试了几种方法都出现错误了,特请求教。

出0入0汤圆

发表于 2009-5-16 10:24:48 | 显示全部楼层
我的意思是,比如你有20个字节需要发送,那么你就在这20个字节后面加一个停止标志字节(自己设定的)。然后使用一个变量来技术,只要没有接到这个停止标志字节,就认为发送的是同一条指令,然后放在同一个数组里面,这样不需要管经过几次中断,最终都可以得到完整的命令组。但是你在发送的时候最多一次只能发送16个字节,因此需要在发送的时候人为地将这20个字节+一个结束字节分成两组发送。

出0入0汤圆

发表于 2009-5-18 20:09:31 | 显示全部楼层
我今天试了下~我设定数据末尾都有个换行符,在发送中断中先发送前十六个字节给SCITXBUF,然后判断第16个字节是否为换行符(在这我想问下,怎么选中SCITXBUF中的数据啊,或许是到FIFO中选?我当时是直接检测我放数据的数组中第16个字节)。如果不是的话,我通过循环赋值语句把数组接下来未发的数据再发给SCITXBUF。这样的话,我发现还是会少数据。

于是,我在判断语句中加了检测发送缓冲是否为空和FIFO中是否为空两条语句跟前面的判断语句相与,以此来作为判断是否发未发完的数据。但是,问题是在中断里面加这条语句,我在串口里只看到前16格字节,后面部分丢失了。。。

我的结论是可能中断未结束,那两个作为判断的标志位不符合条件,就没继续发送了后面数据了。
看到你的建议中,变量计数的作用是什么?还有“没接到标识符,认为发送的是同一条指令”这个我试了,出现了上面我说的数据重叠现象。“放在一个数组里”这个不太明白,我的数据都是分数组放的,发送时是把数组里的数据给SCITXBUF,发完了还要放在同一个数组里吗?
对了,请问你能加我QQ吗?那样联系方便些。我做这个不久,需要阁下指点。谢谢。
我的QQ782853407.验证写DSP就好了。

出0入0汤圆

发表于 2009-5-18 20:22:29 | 显示全部楼层
我不能理解2812的通用定时器周期寄存器为什么存在?不是已经有了个通用定时器比较寄存器么?郁闷

出0入0汤圆

发表于 2009-5-18 20:45:35 | 显示全部楼层
问题已经明白了。。。

出0入0汤圆

 楼主| 发表于 2009-5-18 20:52:17 | 显示全部楼层
72楼,当有FIFO空中断时,你写16个字节到FIFO就可以了。这样是不会丢数据的哦
还是我65的火车方式来说,假设火车有16节车厢,你每次放满16节车厢后,火车就开走了咯。等火车再回来(FIFO为空)你就可以再放16节车厢的货物。这样是不会丢东西的
如果丢了,要检查是否在FIFO不空的情况下又写了16个字节进去,覆盖了未发送完毕的数据。

出0入0汤圆

发表于 2009-5-19 12:17:52 | 显示全部楼层
恩,我就是不知道火车是什么时候回来的。。所以不知道该在什么时候继续发剩下的数据。。

出0入0汤圆

发表于 2009-5-19 13:57:39 | 显示全部楼层
火车回来的时候会有中断,因此发送工作应该在中断中进行,而且当你初始化中使能了fifo的匹配中断后,SCI会立刻进入一次中断,在中断中奖要发送的数据按照最多16个字节的格式发送就可以了。这样就好像你只能在月台上像火车里面送东西,而月台在火车没有到之前是不开放的,因此不会出现覆盖的问题。

出0入0汤圆

发表于 2009-5-19 18:06:55 | 显示全部楼层
但是要在中断中发送两次,这个不会覆盖么?。。
我用接收中断触发发送中断,在发送中断里发送对应数据,当发送完16字节时检测结尾不是结束符,就又触发发送中断吗?这样在发送中断里触发发送中断可以吗?好像不行吧。就是这我卡住了。
如果不触发发送中断,直接检测后又把剩余数据给SCITXBUF,就会丢失中间部分了。。。

出0入0汤圆

发表于 2009-5-19 18:20:17 | 显示全部楼层
请教下我的PWM设置为递增递减模式,
一个是0占空比为高电平,100%占空比为低电平
一个是100%占空比为高电平,0占空比为低电平
我在调试的时候,从0占空比升到20%,1毫秒后 在降低为0%
结果出现一个错误的信号~如图圆圈处~
请教DX怎么回事?

(原文件名:1111.jpg)

出0入0汤圆

发表于 2009-5-19 20:32:39 | 显示全部楼层
楼上的没有明白我的意思,出发中断只要你设定的匹配条件满足就会发生,你可以将匹配之设置成0,这样发送完前16个字节,优惠自动触发发送中断,在发送后面的字节。

出0入0汤圆

发表于 2009-5-19 20:33:28 | 显示全部楼层
还有,楼上的没有看到你的程序怎么可能知道问题出在哪里?

出0入0汤圆

发表于 2009-5-19 21:29:57 | 显示全部楼层
PWM的设置:都是一样的   
pwminit(void){                                       
        EPwm1Regs.TBPRD = 1500;              
        EPwm1Regs.TBPHS.half.TBPHS=0;        
         EPwm1Regs.TBCTR=0;
        EPwm1Regs.TBCTL.bit.CTRMODE = 2;   
        EPwm1Regs.TBCTL.bit.PHSEN = 0;      
        EPwm1Regs.TBCTL.bit.PRDLD = 0;
        EPwm1Regs.TBCTL.bit.SYNCOSEL = 0;  
  

        EPwm1Regs.TBCTL.bit.HSPCLKDIV =0;         
        EPwm1Regs.TBCTL.bit.CLKDIV = 0;      

        EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;
        EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;
        EPwm1Regs.CMPCTL.bit.LOADAMODE = 0;
        EPwm1Regs.CMPCTL.bit.LOADBMODE = 0;

   

        EPwm1Regs.AQCTLA.bit.CAU = 1;
         EPwm1Regs.AQCTLA.bit.CAD = 2;
        EPwm1Regs.AQCTLB.bit.CBU = 2;
         EPwm1Regs.AQCTLB.bit.CBD = 1;  

   }  
main(){
EPwm1Regs.CMPA.half.CMPA=100;                  //A的输出占空比
EPwm1Regs.CMPB=100;
delay(1);
EPwm1Regs.CMPA.half.CMPA=0;                  //A的输出占空比
EPwm1Regs.CMPB=0;
delay(1);

}
就是这样的哈~

出0入0汤圆

发表于 2009-5-20 10:14:41 | 显示全部楼层
这个波形看上去很正常呀?你在后面CMPA和CMPB都变成了0,也就是说对于A来说,一开始就会变成低电平,然后知道周期完成,才会变成高电平你个,而B正好相反。

出0入0汤圆

发表于 2009-5-20 17:26:40 | 显示全部楼层
哦,原来这样哈,谢谢LS了~

出0入0汤圆

发表于 2009-5-23 23:27:28 | 显示全部楼层
楼主,MCBSP配置成SPI,一台为主,一台为从进行通信,先设置主机循环发送数据,再配置从机接收数据,但配置完从机后,主机MOSI脚上的电平低了一半,不知是何原因

出0入0汤圆

发表于 2009-5-24 22:04:32 | 显示全部楼层
请大家帮忙,F2812本身能提供当前时间的功能嘛?我想用打印机打出日期和时间来,有什么好办法吗?

急需解答,希望知道的能帮一下。

出0入0汤圆

 楼主| 发表于 2009-5-25 08:52:42 | 显示全部楼层
85楼,应该是从机的MISO为低导致的

86楼,F2812本身没有时间功能,最好扩展时钟芯片。另外用定时器自己做个时钟也是可以的,不过会有误差,掉电保持也是个问题

出0入0汤圆

发表于 2009-5-25 10:36:47 | 显示全部楼层
楼主,我说的是MOSI,主机的MOSI连接从机的MOSI,跟MISO是分开的

出0入0汤圆

发表于 2009-5-25 10:39:43 | 显示全部楼层
void InitMcbspaGpio(void)
{
        EALLOW;

/* Configure McBSP-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be McBSP functional pins.
// Comment out other unwanted lines.

        GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 2;        // GPIO20 is MDXA pin
        GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 2;        // GPIO21 is MDRA pin
    GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 2;        // GPIO22 is MCLKXA pin
    //GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 2;                // GPIO7 is MCLKRA pin (Comment as needed)
        GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 1;        // GPIO58 is MCLKRA pin (Comment as needed)
    GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 2;        // GPIO23 is MFSXA pin
    //GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 2;                // GPIO5 is MFSRA pin (Comment as needed)
        GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 1;        // GPIO59 is MFSRA pin (Comment as needed)

/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

        GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0;     // Enable pull-up on GPIO20 (MDXA)
        GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0;     // Enable pull-up on GPIO21 (MDRA)
        GpioCtrlRegs.GPAPUD.bit.GPIO22 = 0;     // Enable pull-up on GPIO22 (MCLKXA)
        //GpioCtrlRegs.GPAPUD.bit.GPIO7 = 0;      // Enable pull-up on GPIO7 (MCLKRA) (Comment as needed)
        GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;   // Enable pull-up on GPIO58 (MCLKRA) (Comment as needed)
        GpioCtrlRegs.GPAPUD.bit.GPIO23 = 0;     // Enable pull-up on GPIO23 (MFSXA)
        //GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;      // Enable pull-up on GPIO5 (MFSRA) (Comment as needed)
        GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;   // Enable pull-up on GPIO59 (MFSRA) (Comment as needed)

/* Set qualification for selected pins to asynch only */
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 3;   // Asynch input GPIO20 (MDXA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 3;   // Asynch input GPIO21 (MDRA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 3;   // Asynch input GPIO22 (MCLKXA)
    //GpioCtrlRegs.GPAQSEL1.bit.GPIO7 = 3;    // Asynch input GPIO7 (MCLKRA) (Comment as needed)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO58(MCLKRA) (Comment as needed)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 3;   // Asynch input GPIO23 (MFSXA)
    //GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 3;    // Asynch input GPIO5 (MFSRA) (Comment as needed)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO59 (MFSRA) (Comment as needed)

        EDIS;
}
void init_mcbsp_spi()
{
     // McBSP-A register settings
    McbspaRegs.SPCR2.all=0x0000;                 // Reset FS generator, sample rate generator & transmitter
        McbspaRegs.SPCR1.all=0x0000;                 // Reset Receiver, Right justify word, Digital loopback dis.
    McbspaRegs.PCR.all=0x0f08;           //(CLKXM=CLKRM=FSXM=FSRM= 1, FSXP = 1) clkxm = 1 ,so it is spi master
        McbspaRegs.PCR.bit.CLKXM = 1;
   
        McbspaRegs.SPCR1.bit.DLB = 0;//disable loopback spi
    McbspaRegs.SPCR1.bit.CLKSTP = 2;     // Together with CLKXP/CLKRP determines clocking scheme
        McbspaRegs.PCR.bit.CLKXP = 0;                 // CPOL = 0, CPHA = 0 rising edge no delay
        McbspaRegs.PCR.bit.CLKRP = 0;
    McbspaRegs.RCR2.bit.RDATDLY=01;      // FSX setup time 1 in master mode. 0 for slave mode (Receive)
    McbspaRegs.XCR2.bit.XDATDLY=01;      // FSX setup time 1 in master mode. 0 for slave mode (Transmit)

        McbspaRegs.RCR1.bit.RWDLEN1=2;     // 16-bit word
    McbspaRegs.XCR1.bit.XWDLEN1=2;     // 16-bit word

    McbspaRegs.SRGR2.all=0x2000;                   // CLKSM=1, FPER = 1 CLKG periods
    McbspaRegs.SRGR1.all= 0x000F;             // Frame Width = 1 CLKG period, CLKGDV=16
    //clkGDV = 0xf; spi clk = 100M/4/(0xf+1)
        //SRG input is LSPCLK (SYSCLKOUT/4)
         if(spi_slave == 1)//slave
        {
               McbspaRegs.PCR.bit.CLKXM = 0;//spi slave,clkx input
                McbspaRegs.PCR.bit.FSXM = 0;// ss input
                McbspaRegs.PCR.bit.FSXP =1;
                McbspaRegs.RCR2.bit.RDATDLY = 0;
                McbspaRegs.XCR2.bit.XDATDLY = 0;
                McbspaRegs.SRGR2.bit.CLKSM = 1;//clk source lspclk
                McbspaRegs.PCR.bit.SCLKME = 0;
                McbspaRegs.SRGR1.bit.CLKGDV = 0;
        }
       
    McbspaRegs.SPCR2.bit.GRST=1;         // Enable the sample rate generator
         DELAY_US(10);                  // Wait at least 2 SRG clock cycles
        McbspaRegs.SPCR2.bit.XRST=1;         // Release TX from Reset
        McbspaRegs.SPCR1.bit.RRST=1;         // Release RX from Reset
         McbspaRegs.SPCR2.bit.FRST=1;         // Frame Sync Generator reset
   
}

出0入0汤圆

发表于 2009-5-25 10:41:40 | 显示全部楼层
以上是我的初始化程序,麻烦楼主帮忙看一下

出0入0汤圆

发表于 2009-5-25 10:58:17 | 显示全部楼层
感谢楼主,问题已经解决,就是管脚接错了

出0入0汤圆

 楼主| 发表于 2009-5-29 21:59:38 | 显示全部楼层
大家继续盖楼啊
500楼,我就发我的四层2808核心板PCB,经过工业现场考验的哦

出0入0汤圆

发表于 2009-5-31 20:24:29 | 显示全部楼层
标记!

出0入0汤圆

发表于 2009-6-2 14:50:37 | 显示全部楼层
楼主在不,我用28335,sizeof(int),sizeof(char),sizeof(short)结果都是1,而且拷贝内存的时候也发现,这些数据类型好象都是32位一样?

出0入0汤圆

发表于 2009-6-2 20:23:17 | 显示全部楼层
我用的是f2808
想移植一个Modbus通讯程序,我把所有寄存器变量连续放在初始地址在0x009F00
通过在头文件用宏定义
#define MBRRegAdd   0x009F00 ,
然后
#define MBDriveVerB6   *(int *)(MBRRegAdd)/* 传动型号寄存器组 */
#define MBSoftVerBt6   *(int *)(MBRRegAdd+0x03)/* 软件版本寄存器组 */
#define MBSoftVerBt8   *(int *)(MBRRegAdd+0x06)/* 出厂编号寄存器组 */
#define MBStatusReg1_2 *(int *)(MBRRegAdd+0x0A)/* 状态寄存器1 */
#define MBStatusReg2_2 *(int *)(MBRRegAdd+0x0B)/* 状态寄存器2 */
#define MBStatusReg3_2 *(int *)(MBRRegAdd+0x0C)/* 状态寄存器3 */
#define MBStatusReg4_2 *(int *)(MBRRegAdd+0x0D)/* 状态寄存器4 */
#define MBStatusReg5_2 *(int *)(MBRRegAdd+0x0E)/* 状态寄存器5 */
#define MBStatusReg6_2 *(int *)(MBRRegAdd+0x0F)/* 状态寄存器6 */
#define MBFreqOut_4    *(int *)(MBRRegAdd+0x10)/* 实际频率输出寄存器 */
哪位大侠指点一下
不知道这样可行不?

出0入0汤圆

 楼主| 发表于 2009-6-2 21:43:22 | 显示全部楼层
95楼,可行
但不方便,可以使用结构体来实现

94楼,请看CCS关于变量类型及位宽的帮助

出0入0汤圆

发表于 2009-6-2 22:48:32 | 显示全部楼层
楼主,你好!
请教两个问题,DSP F2808内部的FLASH可以划分一个区域或者块做为存储数据吗(即作为EEPROM用)?
还有就是在使用SPI模块时,CS那个管脚配置成普通IO口(程序里面手动拉低使能)时可以正常使用外设,
但配置成SPI模块专用的CS引脚时,却不能正常工作,这是为什么呢?

出0入0汤圆

发表于 2009-6-3 12:43:01 | 显示全部楼层
请教一下,epwm模块里面的AQ寄存器组里面有一个AQSFRC和AQCSFRC寄存器。其中的单次强制和连续强制有什么区别呢?是不是和TZ里面的OSHT和CBC是一样的呢?我在想是不是能利用这个选项来单独控制某一路epwm引脚产生或者不产生epwm信号,如果不行的话,使用什么方法可以实现呢(使用cmpa或者B来控制占空比除外,感觉那种比较麻烦)。

出0入0汤圆

 楼主| 发表于 2009-6-4 22:43:48 | 显示全部楼层
97楼,有条件就用外部存储器吧,也没几个钱,都用DSP了,咱别那么抠
SPI的CS自己控制和自动控制,我都用过,是没问题的哦,自动控制时,你用示波器看一下时序是否符合器件要求吧

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

本版积分规则

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

GMT+8, 2024-3-29 20:16

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

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