?? spi.c
字號:
/************************************************
文件:spi.c
用途:SPI驅(qū)動
注意:
創(chuàng)建:2008.1.25
修改:2008.1.25
Copy Right (c) www.avrvi.com AVR與虛擬儀器
************************************************/
#include "..\config.h"
/*************************************************************************
** 函數(shù)名稱: spi_init(void)
** 功能描述: SPI初始化
** 輸 入:
** 輸出 :
** 全局變量: 無
** 調(diào)用模塊:
** 說明:
** 注意:
**************************************************************************/
void spi_init(void)
{
DDRB |= (1<<MOSI)|(1<<SCK)|(1<<SS);//設(shè)置MOSI,SCK輸出
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);//使能SPI,主機模式
}
/*************************************************************************
** 函數(shù)名稱: SPI_MasterTransmit(char Data)
** 功能描述: SPI主機發(fā)送數(shù)據(jù)
** 輸 入: Data 需要通過SPI傳輸?shù)臄?shù)據(jù)
** 輸出 :
** 全局變量: 無
** 調(diào)用模塊:
** 說明:
** 注意:
**************************************************************************/
void SPI_MasterTransmit(char Data)
{
/* 啟動數(shù)據(jù)傳輸 */
SPDR = Data;
/* 等待傳輸結(jié)束 */
while(!(SPSR & (1<<SPIF)))
;
}
/*******************************************************
描述: 主 存讀取指定頁地址與字節(jié)地址固寫長度
參數(shù): page_adderss 主存的頁地址<=2047
buffer_adderss 緩存字節(jié)地址0-263
*Read_pHeader 讀出數(shù)據(jù)存貯地址指針
length 讀入數(shù)據(jù)的長度,<=263
*******************************************************/
void AT45DB041B_ContinuousArrayRead(unsigned int page_adderss,unsigned int buffer_adderss,unsigned char *Read_pHeader,unsigned char length)
{
unsigned int i;
unsigned char statu_bit=0;
for(i=0;i<255;++i) //AT45DB041 busy
{
statu_bit=AT45DB041B_StatusRegisterRead();
if(testbit(statu_bit,7)) break;
}
SPI_CS_E;
SPI_HostWriteByte(0xe8);
SPI_HostWriteByte((unsigned char)(page_adderss>>7));
SPI_HostWriteByte((unsigned char)((page_adderss<<1)|(buffer_adderss>>8)));
SPI_HostWriteByte((unsigned char)buffer_adderss);
for(i=0;i<4;i++)
{
SPI_HostWriteByte(0x00);
}
for(i=0;i<length;i++)
{
Read_pHeader[i]=SPI_HostReadByte();
}
SPI_CS_D;
}
/*******************************************************
描述:主存轉(zhuǎn)到緩存
參數(shù):buffer 緩存選擇0X01選取buffer 1, 0X02選取buffer 2,
page_adderss 主存的頁地址<=2047
*******************************************************/
void AT45DB041B_MainMemoryBufferTransfer(unsigned char buffer,unsigned char page_adderss)
{
unsigned int i;
unsigned char statu_bit=0;
for(i=0;i<255;++i) //AT45DB041 busy
{
statu_bit=AT45DB041B_StatusRegisterRead();
if(testbit(statu_bit,7)) break;
}
SPI_CS_E;
switch(buffer)
{
case 1:SPI_HostWriteByte(0x53);break; //buffer 1 writ
case 2:SPI_HostWriteByte(0x55);break; //buffer 2 writ
}
SPI_HostWriteByte((unsigned char)(page_adderss>>7));
SPI_HostWriteByte((unsigned char)(page_adderss<<1));
SPI_HostWriteByte(0x00);
SPI_CS_D;
}
/*******************************************************
Status Register Format:
-----------------------------------------------------------------------
| bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
|--------|--------|-----|------|-----|-----|------|------|
|RDY/BUSY| COMP | 0 | 1 | 1 | 1 | X | X |
| -----------------------------------------------------------------------
bit7 - 忙標(biāo)記,0為忙1為不忙
當(dāng)Status Register的位0移出之后,
接下來的時鐘脈沖序列將使SPI器件繼續(xù)
將最新的狀態(tài)字節(jié)送出
bit6 - 標(biāo)記最近一次Main Memory Page和Buffer的比較結(jié)果,0相同,1不同。
bit5
bit4
bit3
bit2 - 這4位用來標(biāo)記器件密度,對于AT45DB041B,這4位應(yīng)該是0111,一共能標(biāo)記
16種不同密度的器件。
bit1
bit0 - 這2位暫時無效
*******************************************************/
uchar AT45DB041B_StatusRegisterRead(void)
{
uchar i;
SPI_CS_E;
SPI_HostWriteByte(0xd7);
i=SPI_HostReadByte();
SPI_CS_D;
return i;
}
/*******************************************************
描述: 一、 將指定的數(shù)據(jù)寫入buffer 中的指定地址(0-263)
二、帶擦除將buffer 中的數(shù)據(jù)寫入到指定的頁中
參數(shù): buffer 緩存選擇0X01選取buffer 1, 0X02選取buffer 2,
buffer_adderss 緩存字節(jié)地址0-263
*writ_pHeader 待寫入數(shù)據(jù)的指針
length 寫入數(shù)據(jù)的長度,<=263
page_adderss 主存的頁地址<=2047
*******************************************************/
void AT45DB041B_BufferToMainMemoryPageProgramWithBuilt_inErase(unsigned char buffer,unsigned int buffer_adderss,unsigned char *writ_pHeader,unsigned int length,unsigned int page_adderss)
{
unsigned int i=0;
unsigned char statu_bit=0;
AT45DB041B_BufferWrite(buffer,buffer_adderss,writ_pHeader,length);
for(i=0;i<1000;++i) //AT45DB041 busy
{
statu_bit=AT45DB041B_StatusRegisterRead();
if(testbit(statu_bit,7)) break;
}
SPI_CS_E;
switch(buffer)
{
case 1:SPI_HostWriteByte(0x83);break;
case 2:SPI_HostWriteByte(0x86);break;
}
SPI_HostWriteByte((unsigned char)(page_adderss>>7));
SPI_HostWriteByte((unsigned char)(page_adderss<<1));
SPI_HostWriteByte(0x00);
SPI_CS_D;
}
/*******************************************************
描述: 將指定的數(shù)據(jù)寫入buffer 中的指定地址(0-263)
參數(shù): buffer 緩存選擇0X01選取buffer 1, 0X02選取buffer 2,
buffer_adderss 緩存字節(jié)地址0-263
*writ_pHeader 待寫入數(shù)據(jù)的指針
length 寫入數(shù)據(jù)的長度,<=263
*******************************************************/
void AT45DB041B_BufferWrite(unsigned char buffer,unsigned int buffer_adderss,unsigned char *writ_pHeader,unsigned int length)
{
unsigned int i=0;
unsigned char statu_bit=0;
for(i=0;i<255;++i) //AT45DB041 busy
{
statu_bit=AT45DB041B_StatusRegisterRead();
if(testbit(statu_bit,7)) break;
}
SPI_CS_E;
switch(buffer)
{
case 1:SPI_HostWriteByte(0x84);break; //buffer 1 writ
case 2:SPI_HostWriteByte(0x87);break; //buffer 2 writ
}
SPI_HostWriteByte(0x00);
SPI_HostWriteByte((unsigned char)(buffer_adderss>>8));
SPI_HostWriteByte((unsigned char)buffer_adderss);
for(i=0;i<length;i++)
{
SPI_HostWriteByte(writ_pHeader[i]);
}
SPI_CS_D;
}
void SPI_HostWriteByte(unsigned char send_data)
{
SPDR=0;
SPDR=send_data;
while(!(SPSR&(1<<SPIF)));
}
unsigned char SPI_HostReadByte(void)
{
while(!(SPSR&(1<<SPIF)));
return SPDR;
}
int main(void)
{
uint16_t i,j;
DDRB|=_BV(PB0);
for(i=0;i<128;i++)
xx[i]=i+5;
IoInit();
df_init();
printf_P(PSTR("\n開始測試AT45DB161D!\n"));
/* //測試寫
df_write_open(8000);
for(i=0;i<5;i++)
df_write(xx,128);
df_write_close();
*/
//測試讀
df_read_open(8000);
for(j=0;j<5;j++)
{
df_read(xx,128);
for(i=0;i<128;i++)
{
if(i%16 == 0)
printf("\n");
printf("%x ",xx[i]);
}
}
df_read_close();
printf("\n");
/* //測試讀器件ID
df_read_deviceid(xx);
for(i=0;i<4;i++)
printf("0x%x ",xx[i]);
*/
while(1)
{
DelayMs(300);
PORTB^=_BV(PB0); //測試完后進(jìn)入LED閃爍死循環(huán)
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -