加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

DSP F2812 SPI调试

发布时间:2020-12-15 17:55:25 所属栏目:百科 来源:网络整理
导读:最近需要调试f2812 的Spi,我的spi口接的是flash,型号是S25FL016A,以前没摸过DSP,看了一个星期F2812的资料,然后开始调试,用的软件调试工具是CCStudio v3.3,编译加在线调试,网上调试f2812 spi的资料也有一些,大多是spi连eeprom和ADS的,应该是大同小

最近需要调试f2812 的Spi,我的spi口接的是flash,型号是S25FL016A,以前没摸过DSP,看了一个星期F2812的资料,然后开始调试,用的软件调试工具是CCStudio v3.3,编译加在线调试,网上调试f2812 spi的资料也有一些,大多是spi连eeprom和ADS的,应该是大同小异,查看了一些资料后,边写边移植,代码不多,很快就写完了,但spi一直不通,读写flash老是失败,整了一个多星期,总算调通了,下面是我觉得需要注意的地方(我没有用中断模式,也没有开启fifo)。

?

首先是初始化:

1.GpioMuxRegs.GPFMUX.all = 0x003F;?很多人都是这样初始化的,GPFMUX是控制寄存器,最后四位置1就是把CPU的这四个管脚配成spi功能,分别是MOSI(主输出从输入),MISO(主输入从输出),SCK(时钟),STE(片选),配成spi模式后,只要往SPITXBUF寄存器写数,时钟就会自动发起,片选自动选中(STE拉低),数据也自动传送,这就是我遇到的主要问题了,由于不通,我用示波器量了一下波形,发现发完一个字节后STE就自动拉高了,而这对于该flash读写是绝对不允许的,比如我要读一个地址的数据,发一个字节读命令,三个字节地址,然后准备读数,在这期间STE必须一直是低电平,如果中间拉高了,该读命令就结束了,我也不知道为什么2812发完一个自节就STE自动拉高了,很奇怪,后来我这样解决的,把STE设成gpio模式,方向设为输出(如下)

GpioMuxRegs.GPFMUX.all = 0x0037;

GpioMuxRegs.GPFDIR.all |= 0x0008;

这样我就可以用软件随便控制片选信号了。

还有更有意思的,把四个管脚全设成gpio模式,那么时钟也要用软件模拟的,这样需要一位一位发,稍微麻烦点,我没试过。

SpiaRegs.SPICCR.all=0x0047;?最后四位设成0111,表示每次数据传输位数为8位;关闭自回还模式

需要注意相位和极性的设置,由SPICCR.bit6(POLARITY) 和SPICTl.bit3(PHASE)控制

当SPICCR.bit6 = 1??SPICTl.bit3 = 0 下跳沿发数上跳沿收数

当SPICCR.bit6 = 0??SPICTl.bit3 = 1 在第一个高电平的前半个周期和紧接着的下跳沿发数,上跳沿收数

还有两种极性和相位设置就不介绍了,手册里讲这个flash是在上跳沿时收数,所以我上面讲的两种模式都是可以的(我自己做过实验,确实可以,大部分资料只讲了一种)

SpiaRegs.SPICTL.all=0x0006;???//配成主模式,禁止发送功能,禁止中断

SpiaRegs.SPISTS.all=0x0000;???//所有状态位清零

SpiaRegs.SPIBRR=0x001F;???????//设置波特率,波特率计算公式手册上有,BRR的值作是为除数,所以BBR的值设的越大,波特率越小,注意波特率不能太大,大到超过flash的范围那肯定工作就不正常了

SpiaRegs.SPICCR.all=SpiaRegs.SPICCR.all|0x0080;???//软复位

2.再讲一下读写函数(注意SPIRXBUF和 SPITXBUF都是16位的)

unsigned short SPI_read_8()

{

?????unsigned short mytemp = 0x1111;??//随便附一个值,这个无所谓,我自己调试用的

?????SpiaRegs.SPITXBUF=0xffff;????????//为了启动时钟,要发一个无效数

?????while((SpiaRegs.SPISTS.all&0x0040) != 0x0040) ;??//判断是否发完

?????mytemp = SpiaRegs.SPIRXBUF;????

?????return (mytemp & 0x00ff);???????//这个和前面的SPICCR后四位有关,因为设的是1次传输8位,注意收数时是右对齐的,即后面8位才是真正想要的数据

}???????

void SPI_send_8(unsigned short??a)

?????SpiaRegs.SPITXBUF=a;??????????//写到发送寄存器,

?????while((SpiaRegs.SPISTS.all&0x0040) != 0x0040) ;??//判断是否发完

?????SpiaRegs.SPIRXBUF=SpiaRegs.SPIRXBUF;???//发完后读一下接收寄存器,以便清除中断标志位

}

3.最后讲一下flash操作时序,命令主要有读写擦,注意写之前必须全擦一下,否则写不进去,只说一下如何写吧

char Read_RDSR(void)?// 读状态函数

?????????unsigned short read_data;

?????????GpioDataRegs.GPFDAT.bit.GPIOF3 = 0;????//拉低STE,使能flash,每个命令之前都别忘了这一步

?????????SPI_send_8(RDSR);???????????????????//发命令,手册里都有每个命令的解释

?????????read_data=SPI_read_8();??????????????//读状态数据

?????????GpioDataRegs.GPFDAT.bit.GPIOF3 = 1;??//拉高STE,操作完手动拉高,命令才能完全执行

????????

?????????return(read_data);

//下面是写的过程

while((temp = Read_RDSR())&0x01);??????//判断设备是否空闲

EALLOW;GpioDataRegs.GPFDAT.bit.GPIOF3 = 0; EDIS;

SPI_send_8(WREN);???????????????????//写操作前别忘了写使能

EALLOW;GpioDataRegs.GPFDAT.bit.GPIOF3 = 1; EDIS;

?

while((temp = Read_RDSR())&0x01);????????//判断设备是否空闲

EALLOW;GpioDataRegs.GPFDAT.bit.GPIOF3 = 0; EDIS;?

SPI_send_8(WRITE);??????????????????//发送写命令,这里也需要注意,写命令是0x02,而这里WRITE宏定义的值是0x0200,也是因为每次发8位,发的时候是左对齐的,即实际上只有高八位发出去了,后面的地址数据都是如此

SPI_send_8(0x0000);?????????????????????????????????????//发送三个字节写地址

SPI_send_8(0xF000);

SPI_send_8(0x0000);

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

SPI_send_8(0xEE00);?????????????//要写的数据

刚开始调试的时候可以发个最简单的RDID命令,看设备ID能否读回来,成功了再测读写

主要这么多了,把握好几个点,就比较简单了,调板子还是很需要耐心的的,多看手册,多思考,这次调试还是很有意义的,早就不用的示波器又用起来了,还是很有用啊,以后还是要多多学习硬件方面的东西

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读