在學(xué)習(xí)過程中,發(fā)現(xiàn)一點(diǎn)容易被忽視而又很嚴(yán)重的問題---那就是關(guān)于SSP1的引腳使用P0[7]-P0[8]-P0[9]時(shí),是W型IO配置。寄存器的第7位很容易被我們?cè)O(shè)置為0--但是手冊(cè)上是要求必須為1,否則不能正常工作,這里我走了一點(diǎn)彎路。
#include“ssp_lpc1788.h”
#define SPI_FLASH_PageSize 256 //頁大小
#define SPI_FLASH_PerWritePageSize 256 //寫頁大小
/*----------------初始化SSP0-------------*/
void SSP0_Init(unsigned long sysClk, unsigned spiClk)
{
volatile uint32_t dummy;
dummy = dummy;
LPC_IOCON-》P2_22 =0x22; // SSP0_SCK
LPC_IOCON-》P2_26 =0x22; // SSP0_MISO
LPC_IOCON-》P2_27 =0x22; // SSP0_MOSI
LPC_IOCON-》P2_23=0x30; //SSP1_CS-直接普通上拉IO
LPC_GPIO2-》DIR “= (1UL 《《 23); //輸出
LPC_GPIO2-》SET|=(1《《23);//置一
LPC_SC-》PCONP |= (1UL 《《 21); //SSP0 時(shí)鐘開啟
LPC_SSP0-》CR0 = 0x0007; // 8Bit, CPOL=0, CPHA=0
LPC_SSP0-》CR1 = 0x0002; // SSP0-使能-主模式
LPC_SSP0-》CPSR = sysClk/spiClk; //時(shí)鐘預(yù)分頻寄存器
while( LPC_SSP0-》SR & ( 1 《《 4 ) ); //忙
while( LPC_SSP0-》SR & ( 1 《《 2 ) ) //接收FIFO不為空
{
dummy = LPC_SSP0-》DR; //假讀取去清空FIFO
}
}
/*-------------SSP0-發(fā)送數(shù)據(jù)-----------------*/
void SSP0_WriteByte(unsigned char data)
{
uint8_t Dummy;
LPC_SSP0-》DR = data; //載入要發(fā)送的數(shù)據(jù)
while (LPC_SSP0-》SR & (1 《《 4)){}//等待發(fā)送完成
Dummy=LPC_SSP0-》DR; //假讀取去清空FIFO
}
/*-------------SSP0-接收數(shù)據(jù)-----------------*/
uint8_t SSP0_RegisterByte(void)
{
LPC_SSP0-》DR = 0xFF; //無效指令
while (LPC_SSP0-》SR & (1 《《 4)){}//忙等待
return (LPC_SSP0-》DR); //接收數(shù)據(jù)
}
/*-----------------------------------SSP1--------------------------*/
/*----------------初始化SSP1-------------*/
void SSP1_Init(unsigned long sysClk, unsigned spiClk)
{
volatile uint32_t dummy;
LPC_IOCON-》P0_7 =0xA2; // SSP1_SCK
LPC_IOCON-》P0_8 =0xA2; // SSP1_MISO
LPC_IOCON-》P0_9 =0xA2; // SSP1_MOSI
LPC_IOCON-》P0_6=0x30; //SSP1_CS-普通上拉IO
LPC_GPIO0-》DIR |= (1UL 《《 6); //輸出
LPC_GPIO0-》SET|=(1《《6);//置一
LPC_SC-》PCONP |= (1UL 《《 10); //SSP1 時(shí)鐘開啟
LPC_SSP1-》CR0 = 0x0007; // 8Bit, CPOL=0, CPHA=0
LPC_SSP1-》CR1 = 0x0002; // SSP1-使能-主模式
LPC_SSP1-》CPSR = sysClk/spiClk; //時(shí)鐘預(yù)分頻寄存器
while( LPC_SSP1-》SR & ( 1 《《 4 ) ); //忙
while( LPC_SSP1-》SR & ( 1 《《 2 ) ) //接收FIFO不為空
{
dummy = LPC_SSP1-》DR; //假讀取去清空FIFO
}
}
/*-------------SSP1-發(fā)送數(shù)據(jù)-----------------*/
void SSP1_WriteByte(unsigned char data)
{
uint8_t Dummy;
LPC_SSP1-》DR = data; //載入要發(fā)送的數(shù)據(jù)
while (LPC_SSP1-》SR & (1 《《 4)){} //等待發(fā)送完成
Dummy=LPC_SSP1-》DR; //假讀取去清空FIFO
}
/*-------------SSP1-接收數(shù)據(jù)-----------------*/
uint8_t SSP1_RegisterByte(void)
{
LPC_SSP1-》DR = 0xFF; //無效指令
while (LPC_SSP1-》SR & (1 《《 4)){} //忙等待
return (LPC_SSP1-》DR); //接收數(shù)據(jù)
}
/*---------------------W25Q16---------------*/
//---------寫使能---
void SSP_FLASH_WriteEnable(void)
{
FLASH_CS_LOW();
SSP0_WriteByte(0x06);
FLASH_CS_HIGH();
}
//--------等待寫完成--
void SSP_FLASH_WaitForWriteEnd(void)
{
uint16_t i=2000;
uint8_t FLASH_Status = 0;
FLASH_CS_LOW();
SSP0_WriteByte(0x05);
do
{
FLASH_Status = SSP0_RegisterByte();
i--;
}
while (((FLASH_Status & 0x01) == 1)||(i==0));
FLASH_CS_HIGH();
}
/*----關(guān)于擦除---在寫入數(shù)據(jù)之前必須保證被寫入的位值是0xff---這就是擦除的作用*/
//-------------扇區(qū)擦除----------
void SSP_FLASH_SectorErase(uint32_t SectorAddr)
{
SSP_FLASH_WriteEnable();//寫使能
SSP_FLASH_WaitForWriteEnd();//忙狀態(tài)
FLASH_CS_LOW();//CS=0
SSP0_WriteByte(0x20);//0x20
SSP0_WriteByte((SectorAddr & 0xFF0000) 》》 16);//擦除扇區(qū)起始地址
SSP0_WriteByte((SectorAddr & 0xFF00) 》》 8);
SSP0_WriteByte(SectorAddr & 0xFF);
FLASH_CS_HIGH();//CS=1
SSP_FLASH_WaitForWriteEnd();//忙狀態(tài)--等待擦除完成
}
//-----------塊擦除-------
void SSP_FLASH_BlockErase(uint32_t BlockAddr)
{
BlockAddr*=65536;//0x010000
SSP_FLASH_WriteEnable();//寫使能
SSP_FLASH_WaitForWriteEnd();
FLASH_CS_LOW();
SSP0_WriteByte(0xD8);//0xD8
SSP0_WriteByte((BlockAddr & 0xFF0000) 》》 16);//擦除塊起始地址
SSP0_WriteByte((BlockAddr & 0xFF00) 》》 8);
SSP0_WriteByte(BlockAddr & 0xFF);
FLASH_CS_HIGH();
SSP_FLASH_WaitForWriteEnd();
}
//----------整片擦除--
void SSP_FLASH_BulkErase(void)
{
SSP_FLASH_WriteEnable(); //寫使能
FLASH_CS_LOW();
SSP0_WriteByte(0xc7); //整片擦除
FLASH_CS_HIGH();
SSP_FLASH_WaitForWriteEnd();
}
//---------單頁寫入-----
void SSP_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
SSP_FLASH_WriteEnable();
FLASH_CS_LOW();
SSP0_WriteByte(0x02);//CMD2--0x02--------頁寫入
SSP0_WriteByte((WriteAddr & 0xFF0000) 》》 16);//寫入起始地址
SSP0_WriteByte((WriteAddr & 0xFF00) 》》 8);
SSP0_WriteByte(WriteAddr & 0xFF);
if(NumByteToWrite 》 SSP_FLASH_PerWritePageSize) //寫入數(shù)據(jù)多余頁最大數(shù)據(jù)
NumByteToWrite = SSP_FLASH_PerWritePageSize;
while (NumByteToWrite--)
{
SSP0_WriteByte(*pBuffer); //寫數(shù)據(jù)
pBuffer++;
}
FLASH_CS_HIGH();
SSP_FLASH_WaitForWriteEnd();
}
//--------多頁寫入---
void SSP_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
Addr = WriteAddr % SSP_FLASH_PageSize; //首頁地址
count = SSP_FLASH_PageSize - Addr;//首頁要寫入的數(shù)據(jù)個(gè)數(shù)
NumOfPage = NumByteToWrite / SSP_FLASH_PageSize;//頁數(shù)
NumOfSingle = NumByteToWrite % SSP_FLASH_PageSize; //余數(shù)--最后一頁不滿一頁個(gè)數(shù)
if (Addr == 0)
{
if (NumOfPage == 0) //只有一頁
{
SSP_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite); //?±?óD′è?
}
else //多頁
{
while (NumOfPage--) //寫滿頁的數(shù)據(jù)
{
SSP_FLASH_PageWrite(pBuffer, WriteAddr, SSP_FLASH_PageSize);
WriteAddr += SSP_FLASH_PageSize;
pBuffer += SSP_FLASH_PageSize;
}
SSP_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);//寫最后不滿一頁的數(shù)據(jù)
}
}
else
{
if (NumOfPage == 0)
{
if (NumOfSingle 》 count)
{
temp = NumOfSingle - count;
SSP_FLASH_PageWrite(pBuffer, WriteAddr, count);
WriteAddr += count;
pBuffer += count;
SSP_FLASH_PageWrite(pBuffer, WriteAddr, temp);
}
else
{
SSP_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
}
}
else
{
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / SSP_FLASH_PageSize;
NumOfSingle = NumByteToWrite % SSP_FLASH_PageSize;
SSP_FLASH_PageWrite(pBuffer, WriteAddr, count);
WriteAddr += count;
pBuffer += count;
while (NumOfPage--)
{
SSP_FLASH_PageWrite(pBuffer, WriteAddr, SSP_FLASH_PageSize);
WriteAddr += SSP_FLASH_PageSize;
pBuffer += SSP_FLASH_PageSize;
}
if (NumOfSingle != 0)
{
SSP_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
}
}
}
}
//--------讀數(shù)據(jù)-----------
void SSP_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
FLASH_CS_LOW();
SSP0_WriteByte(0x03); //CMD3--0x03-----//讀數(shù)據(jù)
SSP0_WriteByte((ReadAddr & 0xFF0000) 》》 16);
SSP0_WriteByte((ReadAddr& 0xFF00) 》》 8);
SSP0_WriteByte(ReadAddr & 0xFF);
while (NumByteToRead--)
{
*pBuffer = SSP0_RegisterByte();//讀入到指定數(shù)組
pBuffer++;
}
FLASH_CS_HIGH();
}
/*-----------讀取廠家ID------------*/
uint32_t SSP_FLASH_ReadID(void)
{
uint32_t temp1=0,temp2=0,temp3=0,temp=0;
LPC_GPIO0-》CLR|=(1《《6); //CS=0
SSP1_WriteByte(0x9F); //讀取ID指令
temp1 =SSP1_RegisterByte(); //廠家編號(hào)
temp2 =SSP1_RegisterByte();//存儲(chǔ)類型
temp3 =SSP1_RegisterByte();//容量
temp =(temp1《《16)|(temp2《《8)|(temp3);
LPC_GPIO0-》SET|=(1《《6);//CS=1;
return temp;
評(píng)論
查看更多