打印
[技术问答]

SPI详解(代码基于新唐M451)

[复制链接]
5012|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lijiankun|  楼主 | 2015-2-12 17:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
   SPI分主设备和从设备,对于主设备是有自己的时钟的,但是对于从设备,自身是没有时钟的,它的时钟必须由主设备提供,所以在用SPI对FLASH进行操作时,一般分为这样几个过程,首先是发送命令(比如0x90是读设备ID;0x03是读命令;0x06是写命令;0x02是对FLASH芯片进行编程的命令),发完命令之后就是发地址,最后才是读数据或者写数据。
  下面是读ID的函数,其中有几点做一下简单的说明
unsigned int SpiFlash_ReadMidDid(void)
{
    unsigned int au32SourceData;
    unsigned int au32DestinationData;

    // /CS: 片选拉低
    SPI_SET_SS_LOW(SPI2);

    // configure transaction length as 8 bits
    SPI_SET_DATA_WIDTH(SPI2, 8);

    // send Command: 0x90, Read Manufacturer/Device ID
    au32SourceData = 0x90;
    SPI_WRITE_TX(SPI2, au32SourceData);
    while(SPI_IS_BUSY(SPI2));

    // configure transaction length as 24 bits
    SPI_SET_DATA_WIDTH(SPI2, 24);

    // send 24-bit '0', dummy
    au32SourceData = 0x0;           //这里发送0x00是因为从设备不能自己产生时钟,所以主设备
                               // 通过向从设备发数据来提供时钟
    SPI_WRITE_TX(SPI2, au32SourceData);
    while(SPI_IS_BUSY(SPI2));

    // configure transaction length as 16 bits
    SPI_SET_DATA_WIDTH(SPI2, 16);

    I2S_CLR_RX_FIFO(SPI2);            //禁止音频接口功能,因为它与SPI公用的一个FIFO

    // receive
    au32SourceData = 0x0;      //同样发0x00是为了给从设备提供时钟
    SPI_WRITE_TX(SPI2, au32SourceData);
    while(SPI_IS_BUSY(SPI2));

    // /CS: de-active
    SPI_SET_SS_HIGH(SPI2);

    // dump Rx register
    au32DestinationData = SPI_READ_RX(SPI2);

    return (au32DestinationData & 0xffff);

}

对于SPI,新唐提供的基本操作函数还是挺全的,读数据可以用SpiFlash_ReadData()
向FLASH写数据可以用SpiFlash_PageProgram()不过这个函数是一次编程一页的数据进去。
擦除的话可以用SpiFlash_ChipErase(void)

一般应用就是对FLASH进行读写就够了,可以像下面这样写
  Open_SPI_Flash();          //使能SPI       
   MidDid = SpiFlash_ReadMidDid();   //读设备ID
   printf("\n MID and DID = %x\n ", MidDid);   

    SpiFlash_ChipErase();      //进行片擦,写之前一般都要先擦出一块来
    printf("\n Flash Erasing... \n");


    SpiFlash_WaitReady();    //等待FLASH准备好
    printf("\n Done!\n");
               
   SpiFlash_PageProgram(Buff, u32ProgramFlashAddress, 256);   //对FLASH进行写操作
    SpiFlash_WaitReady();   
               
   SpiFlash_ReadData(DestArray, u32VerifyFlashAddress, 256);  //对FLASH进行读操作

   SPI_Display(DestArray, 256);  //这是一个对读回来的数据进行串口打印的一个函数,这个是自
                             //己写的,不是官方自带的.函数源码在下面
               
    while(1);            //让程序死到这里
----------------------------------------------------------------------------------------------------------------------
void SPI_Display(unsigned char *DataBuff, unsigned int ByteCount)
{
     unsigned int i;
     for(i=0; i<ByteCount;i++)
    {
        printf(" %02x",*DataBuff++);
     }       
}
至于对SPI进本概念的详解,时序的详解,这类帖子有很多,这里就不重复了。
沙发
gaoyang9992006| | 2015-2-12 22:37 | 只看该作者
我以为楼主讲新唐451单片机的SPI接口的使用方法呢,原来不是啊。

使用特权

评论回复
板凳
gaoyang9992006| | 2015-2-12 22:37 | 只看该作者
我以为楼主讲新唐451单片机的SPI接口的使用方法呢,原来不是啊。

使用特权

评论回复
地板
598330983| | 2015-2-16 22:06 | 只看该作者
楼主讲的不错,谢谢楼主,希望多多发点

使用特权

评论回复
5
lijiankun|  楼主 | 2015-2-21 22:24 | 只看该作者
gaoyang9992006 发表于 2015-2-12 22:37
我以为楼主讲新唐451单片机的SPI接口的使用方法呢,原来不是啊。

我是个新手,对于SPI接触最多的就是对FLASH的操作,所以就简单的描述了一下在这方面的用法

使用特权

评论回复
6
quray1985| | 2015-3-26 22:13 | 只看该作者
请问,用spi读写flash的速度能有多快?
怎样才能提高读写速度呢?

使用特权

评论回复
7
lijiankun|  楼主 | 2015-3-26 22:44 | 只看该作者
quray1985 发表于 2015-3-26 22:13
请问,用spi读写flash的速度能有多快?
怎样才能提高读写速度呢?

这个速度是很快的,具体是多少没测。要提高速度,把系统时钟增大就行了。

使用特权

评论回复
8
quray1985| | 2015-3-26 22:57 | 只看该作者
lijiankun 发表于 2015-3-26 22:44
这个速度是很快的,具体是多少没测。要提高速度,把系统时钟增大就行了。 ...

我现在正在弄spi的flash,4M,读数据真是龟速。

使用特权

评论回复
9
qwe12377yu| | 2017-7-25 17:51 | 只看该作者
大神,还在这儿么,你还有新唐的SPI对flash读写操作程序么

使用特权

评论回复
10
caoqing| | 2017-7-25 19:56 | 只看该作者
不是官方有代码吗

使用特权

评论回复
11
qwe12377yu| | 2017-7-26 10:08 | 只看该作者
caoqing 发表于 2017-7-25 19:56
不是官方有代码吗

新唐M0,M4没有对SPI对flash的读写操作啊,我希望有这个例程,大神你有么

使用特权

评论回复
12
qwe12377yu| | 2017-7-26 10:10 | 只看该作者
gaoyang9992006 发表于 2015-2-12 22:37
我以为楼主讲新唐451单片机的SPI接口的使用方法呢,原来不是啊。

版主大大,有新唐M0,M4 SPI对flash操作的例程,项目急需,拜托啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

94

帖子

3

粉丝