打印
[工具和软件]

SPI调试笔记

[复制链接]
816|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Vitality1|  楼主 | 2015-1-27 23:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
实现了通过CPU的SPI控制器来读写外部Flash,做一下笔记。
CPU:LPC2366,内置1个SPI控制器,两个SSP控制器。
Flash:AT45DB321,通过SPI接口读写,13 MHz Max Clock Frequency

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

SPI master初始化代码:

void mSPI_Init(void)
{
       U8 u8_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);   // spi controller 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)
{
       U8 u8_dat;

       S0SPDR = 0x00;           // wrtie dummy byte out to generate clock, then read data from miso
       while ((S0SPSR & 0x80) == 0);   // spi controller is busy when S0SPSR[7] == 0
       u8_dat = S0SPSR;
       u8_dat = S0SPDR;

       return u8_dat;
}

读AT45DB321状态寄存器的例子:
       mSPI1_Init();
       PIN_CLR(P0, PIN_AT45_CS);
       mSPI_SendByte(0xd7);
       u8_tmp = mSPI_RecvByte();
       PIN_SET(P0, PIN_AT45_CS);

通过LPC2366的SSP1读写AT45DB321的代码
void mSPI1_Init(void)
{
       U8 u8_i, u8_dat;

       SSP1CR1 = 0x00;                       // disable ssp 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 is master

       for (u8_i = 8; u8_i > 0; u8_i--){
              u8_dat = SSP1DR;               // clear RxFIFO
       }
}

写数据:
void mSPI1_Send(const U8 *u8_buf, U32 u32_len)
{
       U8 u8_dat;

       if (u32_len == 0){
              return;
       }
      
       do {
              while ( !(SSP1SR & 0x02) ); // TxFIFO is full when SSP1SR[1] is 0
              SSP1DR = *u8_buf++;
              while (SSP1SR & 0x10);      // Wait until the Busy bit is cleared
              u8_dat = SSP1DR; // flush RxFIFO, 一定要读,要不然后面mSPI1_RecByte读回来//的是0xff
       } while (u32_len--);
}

读数据:
U8 mSPI1_RecvByte(void)
{
       U8 u8_dat;

       SSP1DR = 0x00;    // wrtie dummy byte out to generate clock, then read data from miso
       while (SSP1SR & 0x10);      // Wait until the Busy bit is cleared
       u8_dat = SSP1DR;

       return u8_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
**  输入参数 :     dat :1字节数据
**    输出参数 :     无
**  影响变量 :  无
**    函数描述 :     写1字节到SPI总线
**  修改描述 :    root 2010-10-24
====================================================================*/
static void SPI_Wr(INT8U dat)
{
       INT8U i;

       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
**  输入参数 :     无
**    输出参数 :     dat :1字节数据
**  影响变量 :  无
**    函数描述 :     写1字节到SPI总线
**  修改描述 :    root 2010-10-24
====================================================================*/
static INT8U SPI_Rd(void)
{
       INT8U i, 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();

       return dat;
}

相关帖子

沙发
FSL_TICS_ZJJ| | 2015-1-28 10:29 | 只看该作者
楼主估计发错版块了。
下次请尽量发和飞思卡尔相关的贴子哦。

使用特权

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

本版积分规则

81

主题

421

帖子

9

粉丝