AD1871采样后和DSP28335的McBsp通信

AD1871采样后和DSP28335的McBsp通信,第1张

首先,AD1871的采样率是可以调整的,LZ没有好好读芯片资料啊,上面对采样率的问题有详细的说明啊。你说的96KHz是芯片最大支持的采样率。资料上写的采样率是由你提供的时钟频率决定的。http://www.21icsearch.com/pdfdetil_E5E3547630C59C1C.html这是芯片资料的下载地址

其次,如果不能更改芯片的采样率的话,也能实现这几种采样,这是数字信号处理方法中的采样率转换问题,都有经典的理论体系。简单的说如果你采的是96KHz,那么你隔一个点取一个点,不就变成了48KHz了吗?具体可以找本数字信号处理书看看!

#include "myapp.h"

#include "ICETEK-VC5509-EDU.h"

#include "scancode.h"

// :-- Define Timer 0 's Registers ---//

ioport unsigned int *tim0

ioport unsigned int *prd0

ioport unsigned int *tcr0

ioport unsigned int *prsc0

// :-- End of Define -----------------//

void InitMcBSP() //函数声明

unsigned int uN,nCount,nCount1//定义外部变量

main() //主程序

{

unsigned char dbScanCode,dbOld //定义内部变量

dbScanCode=dbOld=0

nCount=nCount1=0

PLL_Init(20) //初始化PLL

SDRAM_init() //初始化SDRAM

InitCTR() //初始化CTR

InitMcBSP() //初始化McBSP

uN=60

CTRGR=1

InitInterrupt() //初始化中断

TIME_init() //初始化定时器

while ( 1 )

{

if ( nCount1==0 )

{

dbScanCode=GetKey() //读取键盘输入的信息

if ( dbScanCode!=dbOld ) //如果键盘输入信息改变,执行

{

dbOld=dbScanCode

if ( dbScanCode==SCANCODE_9 )

break

else if ( dbScanCode==SCANCODE_7 )

PCR1|=2

else if ( dbScanCode==SCANCODE_8)

PCR1&=0x0fffd

else if ( dbScanCode==SCANCODE_1 )

uN=60

else if ( dbScanCode==SCANCODE_2 )

uN=40

else if ( dbScanCode==SCANCODE_3 )

uN=20

else if ( dbScanCode==SCANCODE_4 )

uN=10

else if ( dbScanCode==SCANCODE_5 )

uN=0

}

}

}

CloseCTR() //关显示器

exit(0)

}

void InitInterrupt(void)

{

// 设置中断控制寄存器

IVPD=0x80

IVPH=0x80

IER0=0x10

DBIER0 =0x10

IFR0=0xffff

asm(" BCLR INTM")

}

void interrupt Timer() //中断响应函数

{

nCount++nCount%=100

if ( nCount>uN ) PCR2|=4

else PCR2&=0x0fffb

nCount1++nCount1%=5120

}

void InitMcBSP()

{

// IOPin: McBSP2.FSR S22

//SPCR1.RRST_=0,PCR.RIOEN=1,PCR.FSRM=1,PCR.FSRP=0/1

SPCR1_2&=0x0fffe

PCR2|=0x1400

// IOPin: McBSP1.CLKX S14

//SPCR2.XRST_=0,PCR.XIOEN=1,PCR.CLKXM=1,PCR.CLKXP=0/1

SPCR2_1&=0x0fffe

PCR1|=0x2200

}

void TIME_init(void)

{

tim0 = (unsigned int *)0x1000

prd0 = (unsigned int *)0x1001

tcr0 = (unsigned int *)0x1002

prsc0 = (unsigned int *)0x1003

*tcr0 = 0x04f0

*tim0 = 0

*prd0 = 0x0100

*prsc0 = 2

*tcr0 = 0x00e0

}

涉及到外设部分就得看具体的DSP型号了,查查数据手册吧。

id) //将McBSP0初始化为SPI

{

SPSA0=SPCR10_SUB

SPSD0=0x00//接收端复位RRST=0

SPSA0=SPCR20_SUB

SPSD0=0x00//发送端复位XRST=0

SPSA0=SPCR10_SUB

SPSD0=0x1800 //CLKSTP=11

SPSA0=PCR0_SUB

SPSD0=0x0A08 //CLKXM=1(主设备)CLKXP=0

SPSA0=RCR10_SUB

SPSD0=0x00//RWDLEN1=000,接收包长度为8

SPSA0=RCR20_SUB

SPSD0=0x0001 //在BFSX信号上提供正确的建立时间

SPSA0=XCR10_SUB

SPSD0=0x00//XWDLEN1=000,发送包长度为8

SPSA0=XCR20_SUB

SPSD0=0x0001 //在BFSX信号上提供正确的建立时间

SPSA0=SRGR10_SUB

SPSD0=0x00FE //为采样率时钟定义分频因子

SPSA0=SRGR20_SUB

SPSD0=0x2000//CLKSM=1,从CPU得到时钟每个包传送时,激活BFSX信号

SPSA0=SPCR20_SUB

SPSD0=0x0063 //发送端脱离复位XRST=1

SPSA0=SPCR10_SUB

SPSD0|=0x0001 //接收端脱离复位RRST=1采样率产生器脱离复位GRST=1

delay(256) //为使McBSP逻辑稳定,需等待两个采样率产生器时钟周期

}

二.HDn作为片选信号时DSP与MCP2510通信过程

2.1读程序

2.1.1 MCP2510读取过程

在读 *** 作开始时,CS引脚将被置为低电平。随后读指令和8 位地址码(A7 至 A0)将被依次送入MCP2510 。在接收到读指令和地址码之后, MCP2510 指定地址寄存器中的数据将被移出通过SO引脚进行发送。每一数据字节移出后,器件内部的地址指针将自动加一以指向下一地址。因此可以对下一个连续地址寄存器进行读 *** 作。通过该方法可以顺序读取任意个连续地址寄存器中的数据。通过拉高CS引脚电平可以结束读 *** 作。

编程时需注意问题:

1. SPI的读 *** 作是通过写 *** 作完成的。因此在DSP发送地址字节后,再发送一任意8位数据以产生接收时钟。

2. 在发送完任意8位数据后,DSP要有个延时,以等待写入DXR的数据从发送端移出,从而保证从2510输出的数据能够正确地被DSP接收。延时时间应大于采样率产生器输出的8个周期,最好长一些。

3. 由于SPI在发送数据的同时也在接收数据,所以在读取有效数据前(即在发送地址字节完毕后)要先清空接收缓冲器,否则可能会因为接收缓冲器溢出而无法接收有用的数据。可以通过读取3次(因为5402的McBSP有3个接收缓冲器)接收缓冲器DRR的值来实现清空缓冲器的 *** 作,读取之前要注意延时(等待地址字节发送完毕)。

2.1.2 示例程序

Uint16 ReadMCP2510(Uint16 Addr)

{

ChipSlctMCP2510(0) //打开片选

NOP

NOP

NOP

//发送读指令

DXR10=READ_MCP2510

SPSA0=SPCR20_SUB

while(!(SPSD0&0x02)) //等待上一个数据发送完毕

//发送地址

DXR10=Addr

SPSA0=SPCR20_SUB

while(!(SPSD0&0x02)) //等待上一个数据发送完毕

delay(1000) //延时,等待地址字节从DX移出

//读取数据

Addr=DRR10//读3次,清空缓冲器

Addr=DRR10

Addr=DRR10

DXR10=0 //发送任意数据,以便产生接收时钟

SPSA0=SPCR20_SUB

while(!(SPSD0&0x02)) //等待上一个数据发送完毕

delay(1000) //延时,等待数据接收

Addr=DRR10 //第一次为无效数据

ChipSlctMCP2510(3)

return Addr

}

2.2写程序

2.2.1 MCP2510写 *** 作

置CS引脚为低电平启动写 *** 作。 启动写指令后,地址码以及至少一个字节的数据被依次发送到MCP2510 。只要 CS 保持低电平,就可以对连续地址寄存器进行顺序写 *** 作。在SCK 引线上的上升沿,数据字节将从D0位开始依次被写入。如果CS 引脚在字节的8 位数据尚未发送完之前跳变到高电平,该字节的写 *** 作将被中止,而之前发送的字节已经写入。

编程时需注意问题:

1. 2510如何区分指令、地址和数据?由于读写指令、地址字节和数据字节的值可能会一样,所以有必要通过一定的时序来将他们区分开来。经实验验证,2510应该是通过片选信号CS来区分这几个数据的,当CS从高变低后,第一个字节就是指令,哪怕上次没有正确的读写,只要将CS置1,然后再置0,就会重新开始一个指令的周期。

2. 发送完数据字节后一定要有个延时来等待数据字节从DX引脚发送出去,之后才能将片选信号CS置1,否则无法正确写入数据。

2.2.2 示例程序

void WriteMCP2510(Uint16 Addr,Uint16 wrData)

{

ChipSlctMCP2510(0)

NOP

NOP

NOP

DXR10=WRITE_MCP2510

SPSA0=SPCR20_SUB

while(!(SPSD0&0x02)) //等待上一个数据发送完毕

DXR10=Addr

SPSA0=SPCR20_SUB

while(!(SPSD0&0x02)) //等待上一个数据发送完毕

DXR10=wrData

SPSA0=SPCR20_SUB

while(!(SPSD0&0x02)) //等待上一个数据发送完毕

delay(1000)

ChipSlctMCP2510(3)

}

三.BFSX作为片选信号时DSP与MCP2510通信过程

由于要完成2510的读写 *** 作需要3个字节,所以采用BFSX引脚作为MCP2510的片选信号时需要将XCR1和RCR1中的XWDLEN1、RWDLEN1设置为100(24bit)。

由于发送接收字长度设置为24位,因此在发送过程中需要用到DXR2和DRR2寄存器,在此需要注意的一点就是,DXR2(DRR2)必须要比DXR1(DRR1)先初始化或读取。其中DXR2(DRR2)中存放的是24bit的高8位,DXR1(DRR1)中存放的是24bit的低16位。发送时DXR2中的数据首先发送,接收时数据首先存放到DRR2中,因此DXR2(DRR2)中存放指令字节,DXR1(DRR1)中由高到低存放地址和数据。

下面为一个简单的调试程序。

Uint16 Debug24bit( )

{

int i

DXR20=0x02 //写指令

DXR10=0x0F01 //0F为CANCTRL地址,01为待写入的数据

delay(3000) //延时,等待发送完毕

i=DRR10//清空接收缓冲器

i=DRR10

i=DRR10

DXR20=0x03 //读指令

DXR10=0x0F00 //0F为CANCTRL地址,00用于读取数据

delay(3000) //延时,等待接收完毕

i=DRR10&0x00FF //DRR10低8位为有用数据

return i

}

四. 通信时MCP2510的初始化

4.1.1 确定时间份额

计算公式:

时间份额TQ定义为:TQ = 2*(BaudRate + 1)*TOSC

其中,BaudRate 是由 CNF1.BRP<5:0>表征的二进制数。

标称位时间 = TQ * (Sync_Seg + Prop_Seg +Phase_Seg1 + Phase_Seg2)

- 同步段(Sync_Seg)

- 传播时间段(Prop_Seg)

- 相位缓冲段1 (Phase_Seg1)

- 相位缓冲段2 (Phase_Seg2)

假设每个标称位包含N个时间份额TQ,则根据以上公式有:1/100K = N*TQ

现设定分频值BaudRate为1,根据以上公式计算,得出在4MHz时钟时,要实现100Kbps的波特率每个标称位包含个10时间份额TQ,在N满足要求的情况下BaudRate还可以设置为其他值,由MCP2510的手册得知的TQ数量N应在6-25之间。然而在满足这个前提下,应尽量使TQ的时间短一些,即一个标称位的时间份额数量N多一些,这样选择采样点位置时具有更好的分辨率。

4.1.2 设置时间段和采样点

在确定了一个标称位包含的时间份额数量后,还需要对各个时间段包含的时间份额进行分配,以确定采样点的位置。位的采样时刻取决于系统参数,通常应发生在位时间的60-70%处。同时,同步段的时间份额为1 TQ,TDELAY典型值为1-2TQ。因此时间份额分配如下:

(Sync_Seg + Prop_Seg +Phase_Seg1 + Phase_Seg2)=(1+2+3+4)

4.1.3 确定同步跳转宽度和采样次数

根据规则,SJW最大值 为4TQ。然而通常情况下,只有当不同节点的时钟发生不够精确或不稳定时,例如采用陶瓷谐振器时,才需要较大的SJW。一般情况下, SJW取1即可满足要求。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/11843216.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-19
下一篇2023-05-19

发表评论

登录后才能评论

评论列表(0条)

    保存