SPI调试笔记

    技术2026-08-29  4

    SPI调试笔记

    root2011-01-09

    实现了通过CPUSPI控制器来读写外部Flash,做一下笔记。

    CPULPC2366,内置1SPI控制器,两个SSP控制器。

    FlashAT45DB321,通过SPI接口读写,13 MHzMax Clock Frequency

     

    CPU设置为SPI masterAT45DB321Slave,读写时钟都是由master发出的,在读AT45DB321的时候通过写CPUSPI数据寄存器来产生读时钟。

     

    SPI master初始化代码:

     

    void mSPI_Init(void)

    {

           U8u8_dummy;

     

           PINSEL0&= ~(3U << 30);

           PINSEL0|= 3U << 30; // P0[15], SCK

           PINSEL1&= ~0xffU;          // P0[16-19],SSEL, MISO, MOSI, WP

           PINSEL1|= 0x3c;

     

           PIN_SET(P0,PIN_AT45_WP | PIN_AT45_CS);

           PIN_DIR(P0,PIN_AT45_WP | PIN_AT45_CS, OUT);

     

           S0SPCCR= 0x52;             // 分频时钟

           S0SPCR= (0 << 2) |           //bitEnable, 8bit

                          (0 << 3) |          // cpha

                       (0 << 4) |          // cpol

                       (1 << 5) |          //mstr = 1, 主模式

                       (0 << 6) |              // lsbf = 0, msb位在先

                       (0 << 7);          //禁止spi中断

           u8_dummy= S0SPSR;    // flush SPI Rx buffer

           u8_dummy= S0SPDR;

           u8_dummy= S0SPSR;

           u8_dummy= S0SPDR;

    }

     

    SPI master发送1byte数据:

    static void mSPI_SendByte(U8 u8_dat)

    {

          S0SPDR = u8_dat;

           while((S0SPSR & 0x80) == 0);  // spicontroller is busy when S0SPSR[7] == 0

           u8_dat= S0SPSR;

           u8_dat =S0SPDR;          // flush the Rx buffer,这个一定要读,否则后面调用读函//数的时候读出来的是0xff

    }

    SPI master接收1byte数据:

    static U8 mSPI_RecvByte(void)

    {

           U8u8_dat;

     

           S0SPDR= 0x00;          // wrtie dummy byte outto generate clock, then read data from miso

           while((S0SPSR & 0x80) == 0);  // spicontroller is busy when S0SPSR[7] == 0

           u8_dat= S0SPSR;

           u8_dat= S0SPDR;

     

           returnu8_dat;

    }

     

    AT45DB321状态寄存器的例子:

           mSPI1_Init();

           PIN_CLR(P0,PIN_AT45_CS);

           mSPI_SendByte(0xd7);

           u8_tmp= mSPI_RecvByte();

           PIN_SET(P0,PIN_AT45_CS);

     

    通过LPC2366SSP1读写AT45DB321的代码

    void mSPI1_Init(void)

    {

           U8u8_i, u8_dat;

     

           SSP1CR1= 0x00;                      // disablessp controller before configuration

     

           PINSEL0&= ~(0x3ff << 10);

           PINSEL0|= 0x2a0 << 10;

     

           PIN_DIR(P0,PIN_AT45_WP | PIN_AT45_CS, OUT);

           PIN_SET(P0,PIN_AT45_WP | PIN_AT45_CS); 

          

           SSP1CR0= (7 << 0)    |     // 8bit

                          (0 << 4)   |   // ssp is configured to spi

                          (0 << 6)     |   // cpol

                          (0 << 7)   |   // cpha

                          (0x07 << 8);     // scr

           SSP1CPSR= 0x30;

           SSP1CR1= (0 << 0)           |  // noraml operation

                          (1 << 1)            |   // ssp enable

                          (0 << 2);               // spi ismaster

     

           for(u8_i = 8; u8_i > 0; u8_i--){

                  u8_dat= SSP1DR;              // clear RxFIFO

           }

    }

     

    写数据:

    void mSPI1_Send(const U8 *u8_buf, U32u32_len)

    {

           U8u8_dat;

     

           if(u32_len == 0){

                  return;

           }

          

           do{

                  while( !(SSP1SR & 0x02) );// TxFIFO isfull when SSP1SR[1] is 0

                  SSP1DR= *u8_buf++;

                  while(SSP1SR & 0x10);     // Wait untilthe Busy bit is cleared

                  u8_dat = SSP1DR;// flush RxFIFO,一定要读,要不然后面mSPI1_RecByte读回来//的是0xff

           }while (u32_len--);

    }

     

    读数据:

    U8 mSPI1_RecvByte(void)

    {

           U8u8_dat;

     

           SSP1DR= 0x00;   // wrtie dummy byte out togenerate clock, then read data from miso

           while(SSP1SR & 0x10);     // Wait untilthe Busy bit is cleared

           u8_dat= SSP1DR;

     

           returnu8_dat;

    }

     

    AT45DB321状态寄存器的例子

           mSPI1_Init();

           PIN_CLR(P0,PIN_AT45_CS);

           buf_w[0]= 0xd7;

           mSPI1_Send(buf_w,1);

           buf_r[0]= mSPI1_RecvByte();

           PIN_SET(P0,PIN_AT45_CS);

     

    通过普GPIO仿SPI时序读写AT45DB321

    /*====================================================================

    **    函数名称 :    SPI_Wr

    **  输入参数 :    dat1字节数据

    **    输出参数 :    

    **  影响变量

    **    函数描述 :    1字节到SPI总线

    **  修改描述 :  root 2010-10-24

    ====================================================================*/

    static void SPI_Wr(INT8U dat)

    {

           INT8Ui;

     

           OS_ENTER_CRITICAL();   

           for(i = 0;i<8;i++){

                  if((dat & 0x80)==0x80){

                         PIN_SET(P0,PIN_AT45_SI);

                  }

                  else{

                         PIN_CLR(P0,PIN_AT45_SI);

                  }

                  PIN_SET(P0,PIN_AT45_SCK);

                  PIN_CLR(P0,PIN_AT45_SCK);

                  dat<<= 1;

           }

           OS_EXIT_CRITICAL();

    }

     

    /*====================================================================

    **    函数名称 :    SPI_Rd

    **  输入参数 :    

    **    输出参数 :    dat1字节数据

    **  影响变量

    **    函数描述 :    1字节到SPI总线

    **  修改描述 :  root 2010-10-24

    ====================================================================*/

    static INT8U SPI_Rd(void)

    {

           INT8Ui, dat;

     

           OS_ENTER_CRITICAL();   

           for(dat = 0, i = 0;i<8;i++){

                  PIN_SET(P0,PIN_AT45_SCK);

                  dat<<= 1;

                  if(PIN_GET(P0, PIN_AT45_SO)){

                         dat|= 1; 

                  }

                  PIN_CLR(P0,PIN_AT45_SCK);

           }

           OS_EXIT_CRITICAL();

     

           returndat;

    }

    最新回复(0)