標(biāo)題:
STM32F103VC SPI 驅(qū)動AT45D642D問題
[打印本頁]
作者:
姍姍
時間:
2014-8-13 21:39
標(biāo)題:
STM32F103VC SPI 驅(qū)動AT45D642D問題
這幾天在寫一個有關(guān)數(shù)據(jù)保存的程序(芯片為AT45D642D),寫了很久,但是調(diào)試總是不成功,希望哪位高手指點下,謝謝!
主要的程序如下:
#define AT45DB_BUFFER_1_WRITE 0x84 /* 寫入第一緩沖區(qū) */
#define AT45DB_BUFFER_2_WRITE 0x87 /* 寫入第二緩沖區(qū) */
#define AT45DB_BUFFER_1_WRITE_FLASH 0x82 /* 寫入第一緩沖區(qū) */
#define AT45DB_BUFFER_2_WRITE_FLASH 0x85 /* 寫入第二緩沖區(qū) */
#define AT45DB_MM_H_READ 0x0B /* 連續(xù)陣列讀,高速模式*/
#define AT45DB_BUFFER_1_READ 0xD4 /* 讀取第一緩沖區(qū) */
#define AT45DB_BUFFER_2_READ 0xD6 /* 讀取第二緩沖區(qū) */
#define AT45DB_B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83 /* 將第一緩沖區(qū)的數(shù)據(jù)寫入主存儲器(擦除模式)*/
#define AT45DB_B2_TO_MM_PAGE_PROG_WITH_ERASE 0x86 /* 將第二緩沖區(qū)的數(shù)據(jù)寫入主存儲器(擦除模式)*/
#define AT45DB_MM_PAGE_TO_B1_XFER 0x53 /* 將主存儲器的指定頁數(shù)據(jù)加載到第一緩沖區(qū) */
#define AT45DB_MM_PAGE_TO_B2_XFER 0x55 /* 將主存儲器的指定頁數(shù)據(jù)加載到第二緩沖區(qū) */
#define AT45DB_PAGE_ERASE 0x81 /* 頁刪除(每頁512/528字節(jié)) */
#define AT45DB_SECTOR_ERASE 0x7C /* 扇區(qū)擦除(每扇區(qū)128K字節(jié))*/
#define AT45DB_READ_STATE_REGISTER 0xD7 /* 讀取狀態(tài)寄存器 */
#define AT45DB_BLACK_ERASE 0x50 /* 塊刪除(每塊4KByte)*/
#define AT45DB_MM_PAGE_READ 0xD2 /* 直接讀主存儲器的內(nèi)存頁*/
#define AT45DB_DATAFLASH_BUSY_BIT 0x80
#define FLASH_PAGE_COUNT 4096
#define FLASH_PAGE_SIZE 512
#define FLASH_SIZE_KBYTE 2112
#define SPI_Data_Flash_AT_SELECT() GPIO_ResetBits(GPIOC, GPIO_Pin_6) /* AT45db CS = L */
#define SPI_Data_Flash_AT_DESELECT() GPIO_SetBits(GPIOC, GPIO_Pin_6) /* AT45db CS = H */
unsigned char present_count1[12]={0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03};
unsigned char present_count2[12]={0x03,0x04,0x01,0x02,0x05,0x04,0x01,0x02,0x06,0x08,0x06,0x04};
//SPI SI(15) SPI SO(14) SPI SCK(13)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//SPI CS
GPIO_SetBits(GPIOC, GPIO_Pin_6);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOC,GPIO_Pin_6);
/****************************SPI配置***************************/
void SPI_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
SPI_Cmd(SPI2, DISABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //設(shè)置SPI單向或者雙向的數(shù)據(jù)模式:SPI設(shè)置為雙線雙向全雙工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //設(shè)置SPI工作模式:設(shè)置為主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //設(shè)置SPI的數(shù)據(jù)大小:SPI發(fā)送接收8位幀結(jié)構(gòu)
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //選擇了串行時鐘的穩(wěn)態(tài):時鐘 懸空低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //數(shù)據(jù)捕獲于第二個時鐘沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信號由硬件(NSS管腳)還是 軟件(使用SSI位)管理:內(nèi)部NSS信號有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //定義波特 率預(yù)分頻的值:波特率預(yù)分頻值為256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定數(shù)據(jù)傳輸從MSB位還是LSB位開始:數(shù)據(jù)傳輸從MSB位開始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值計算的多項式
SPI_Init(SPI2, &SPI_InitStructure); //根據(jù)SPI_InitStruct中指定的參數(shù)初始化外設(shè)SPIx寄存器
SPI_Cmd(SPI2, ENABLE); //使能SPI外設(shè)
/***SPI_ReadWrite_Byte()****SPI發(fā)送或接收1字節(jié)***********************/
static u8 SPI_ReadWrite_Byte(u8 byte)
{
/*等待發(fā)送寄存器空*/
while((SPI2->SR & SPI_I2S_FLAG_TXE)==RESET);
/*發(fā)送一個字節(jié)*/
SPI2->DR = byte;
/* 等待接收寄存器有效*/
while((SPI2->SR & SPI_I2S_FLAG_RXNE)==RESET);
return(SPI2->DR);
}
/***Dataflash_read_status()*****讀取狀態(tài)寄存器**************************/
u8 Dataflash_read_status(void)
{
u8 data;
SPI_Data_Flash_AT_SELECT(); //片選Dataflash
SPI_ReadWrite_Byte(AT45DB_READ_STATE_REGISTER);
data = SPI_ReadWrite_Byte(0x00);
SPI_Data_Flash_AT_DESELECT();
return data;
}
/***SPI_Data_Flash_Busy_Detect()*******Data Flash 檢測忙*******************/
u8 SPI_Data_Flash_Busy_Detect(void)
{
u16 i=0;
if((Dataflash_read_status() & AT45DB_DATAFLASH_BUSY_BIT) == 0)
{
for(i=0;i<0xff;i++);
if((Dataflash_read_status() & AT45DB_DATAFLASH_BUSY_BIT) == 0)
return 1; //忙返回1
else
return 0;
}
else
{
return 0; //空閑返回0
}
}
/***Dataflash_read_flash2buffer()****設(shè)定AT45DB在讀取的時候,將數(shù)據(jù)送往內(nèi)部的1號Buffer或者 2號***/
u8 Dataflash_read_flash2buffer(FLASH_BUFFER_NUM buffer_num, u16 page)
{
if(SPI_Data_Flash_Busy_Detect()==0) //==0 Data Flash空閑
{
SPI_Data_Flash_AT_SELECT(); //片選Dataflash if (buffer_num == FLASH_BUFFER1)
if (buffer_num == FLASH_BUFFER1)
{
SPI_ReadWrite_Byte(AT45DB_MM_PAGE_TO_B1_XFER);
// SPI_ReadWrite_Byte(AT45DB_BUFFER_1_READ);
}
else
{
SPI_ReadWrite_Byte(AT45DB_MM_PAGE_TO_B2_XFER); // 8-bit opcode
// SPI_ReadWrite_Byte(AT45DB_BUFFER_2_READ);
}
// SPI_ReadWrite_Byte(AT45DB_MM_H_READ);
// SPI_ReadWrite_Byte(ADR_P_1(page));
// SPI_ReadWrite_Byte(ADR_P_2(page));
SPI_ReadWrite_Byte(0x00); // 8 don't care bits
SPI_Data_Flash_AT_DESELECT();
return 1;
}
return 0;
}
/***DataFlashPageRead()*****讀取AT45DB內(nèi)部頁數(shù)據(jù)***************/
void DataFlashPageRead(unsigned int page,unsigned char * pHeader)
{
// unsigned int i=0;
while(SPI_Data_Flash_Busy_Detect());
SPI_Data_Flash_AT_SELECT();
SPI_ReadWrite_Byte(AT45DB_MM_PAGE_READ);
SPI_ReadWrite_Byte((unsigned char)(page >> 6));
SPI_ReadWrite_Byte((unsigned char)(page << 2));
SPI_ReadWrite_Byte(0x00);
// SPI_Data_Flash_AT_DESELECT();
/* while(SPI_Data_Flash_Busy_Detect());
SPI_Data_Flash_AT_SELECT();
SPI_ReadWrite_Byte(AT45DB_BUFFER_1_READ);
SPI_ReadWrite_Byte(0x00);
SPI_ReadWrite_Byte(0x00);
SPI_ReadWrite_Byte(0x00);
SPI_ReadWrite_Byte(0x00); */
for (i=0; i<512; i++)
{
*pHeader++ = SPI_ReadWrite_Byte(0x00);
}
SPI_Data_Flash_AT_DESELECT();
}
/***FlashPageWrite()******將數(shù)據(jù)寫入AT45DB161內(nèi)部頁存儲空間***/
void FlashPageWrite(u16 page,u8 *Data) //寫一整頁,頁范圍0-4095
{
u16 i;
while(SPI_Data_Flash_Busy_Detect());
SPI_Data_Flash_AT_SELECT(); //片選Dataflash if (buffer_num == FLASH_BUFFER1)
SPI_ReadWrite_Byte(AT45DB_BUFFER_1_WRITE);
while(SPI_Data_Flash_Busy_Detect());
if ( page < 8192)
{
SPI_Data_Flash_AT_SELECT(); //片選Dataflash if (buffer_num == FLASH_BUFFER1)
SPI_ReadWrite_Byte(AT45DB_B2_TO_MM_PAGE_PROG_WITH_ERASE);
SPI_ReadWrite_Byte((u8)(page>>6));
SPI_ReadWrite_Byte((u8)(page<<2));
SPI_ReadWrite_Byte(0x00);
while(SPI_Data_Flash_Busy_Detect());
SPI_Data_Flash_AT_DESELECT();
}
/* SPI_ReadWrite_Byte(ADR_B_1(address));
SPI_ReadWrite_Byte(ADR_B_2(address)); */
// SPI_ReadWrite_Byte(0x00);
// SPI_ReadWrite_Byte(0x00);
for (i = 0;i <512; i++)
{
if(i<12)
SPI_ReadWrite_Byte(Data
)+0x30;
else SPI_ReadWrite_Byte(0x00);
}
SPI_Data_Flash_AT_DESELECT();
}
/***Dataflash_read_buffer()*****連續(xù)讀AT45DB161內(nèi)部緩沖區(qū)1或者緩沖區(qū)2的數(shù)據(jù)***/
u8 Dataflash_read_buffer(u8* data, u16 address, u16 size, FLASH_BUFFER_NUM buffer_num)
{
u16 i;
if(SPI_Data_Flash_Busy_Detect()==0) //==0 Data Flash空閑
{
SPI_Data_Flash_AT_SELECT(); //片選Dataflash if (buffer_num == FLASH_BUFFER1)
if (buffer_num == FLASH_BUFFER1)
{
SPI_ReadWrite_Byte(AT45DB_BUFFER_1_READ);
}
else
{
SPI_ReadWrite_Byte(AT45DB_BUFFER_2_READ);
}
SPI_ReadWrite_Byte(0x00);
SPI_ReadWrite_Byte(0x00|(address>>8));
SPI_ReadWrite_Byte(address);
SPI_ReadWrite_Byte(0x00); // 8 don't care
for (i=0; i<size; i++)
data
= SPI_ReadWrite_Byte(0x00);
SPI_Data_Flash_AT_DESELECT();
return 1;
}
else //總線忙
{
return 0;
}
}
/***Dataflash_write2flash()*****連續(xù)寫數(shù)據(jù)到SPI Flash內(nèi)部**************/
u8 Dataflash_write2flash(unsigned char* data, unsigned int page, unsigned int address, unsigned int size, FLASH_BUFFER_NUM buffer_num)
{
u16 i;
if(SPI_Data_Flash_Busy_Detect()==0) //==0 Data Flash空閑
{
SPI_Data_Flash_AT_SELECT(); //片選Dataflash
if(buffer_num == FLASH_BUFFER1)
SPI_ReadWrite_Byte(AT45DB_BUFFER_1_WRITE_FLASH );
else
SPI_ReadWrite_Byte(AT45DB_BUFFER_2_WRITE_FLASH);
SPI_ReadWrite_Byte(page>>5);
SPI_ReadWrite_Byte((page<<3)|(address>>8));
SPI_ReadWrite_Byte(address);
// SPI_ReadWrite_Byte(0x00);
for (i=0; i<size; i++)
SPI_ReadWrite_Byte(data
);
SPI_Data_Flash_AT_DESELECT();
return 1;
}
return 0;
}
/***AT45DB_ReadBytes()*****從某一頁的某個位置開始讀取一定長度的數(shù)據(jù),放入數(shù)據(jù)緩沖區(qū)***/
void AT45DB_ReadBytes(unsigned int page,unsigned int byte,unsigned int len,unsigned char *pbuf)
{
unsigned int i;
while(SPI_Data_Flash_Busy_Detect()==1); //==0 Data Flash空閑
SPI_Data_Flash_AT_SELECT(); //片選Dataflash
SPI_ReadWrite_Byte(0x0b);
SPI_ReadWrite_Byte((unsigned char)(page>>5));
SPI_ReadWrite_Byte((unsigned char)((page<<3)|(byte>>8)));
SPI_ReadWrite_Byte((unsigned char) (byte));
SPI_ReadWrite_Byte(0x00);
for(i=0;i<len;i++) pbuf
=SPI_ReadWrite_Byte(0x00);
SPI_Data_Flash_AT_DESELECT();
}
/***Dataflash_erase_page()*****刪除對應(yīng)的頁 每頁對應(yīng)512Byte*******/
void Dataflash_erase_page(u16 page)
{
while(SPI_Data_Flash_Busy_Detect());
SPI_Data_Flash_AT_SELECT(); //片選Dataflash
SPI_ReadWrite_Byte(AT45DB_PAGE_ERASE);
SPI_ReadWrite_Byte(page>>7);
SPI_ReadWrite_Byte(page<<1);
SPI_ReadWrite_Byte(0x00); // 8 don't care bits
SPI_Data_Flash_AT_DESELECT();
}
/***Dataflash_erase_block()*******DataFlash AT45DB642D 塊刪除,每一塊對應(yīng)4KByte***/
void Dataflash_erase_block(u16 block)
{
while(SPI_Data_Flash_Busy_Detect());
SPI_Data_Flash_AT_SELECT(); //片選Dataflash
SPI_ReadWrite_Byte(AT45DB_BLACK_ERASE);
SPI_ReadWrite_Byte(block>>3);
SPI_ReadWrite_Byte(block<<8);
SPI_ReadWrite_Byte(0x00); // 8 don't care bits
SPI_Data_Flash_AT_DESELECT();
}
int main(void)
{
delay_ms(100);
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
USART_Configuration();
SPI_Configuration();
TIM3_Configuration();
Dataflash_erase_page(1); //擦除頁
Dataflash_write2flash(present_count1,1,1,12,FLASH_BUFFER1);
while(1)
{
AT45DB_ReadBytes(1,1,12,present_count2);
SendData(present_count2,12);
SendData(start,15);
delay_ms(1000);
}}
如果保存數(shù)據(jù)成功的話,顯示器上present_count2中的內(nèi)容應(yīng)和present_count1中的一樣,可是現(xiàn)在顯示屏顯示的是12個BC,不知道為什么,求幫助。。
作者:
admin
時間:
2014-8-13 23:29
注意延時時間,,現(xiàn)在是讀失敗 還是寫失。
作者:
姍姍
時間:
2014-8-14 06:25
寫失敗
作者:
姍姍
時間:
2014-8-14 06:38
擦除成功,寫的時候,沒寫進去。
作者:
姍姍
時間:
2014-8-14 09:17
admin 發(fā)表于 2014-8-13 23:29
注意延時時間,,現(xiàn)在是讀失敗 還是寫失?
擦出頁,寫數(shù)據(jù)到緩沖區(qū),從緩沖區(qū)到內(nèi)部頁存儲器;從內(nèi)部頁存儲器讀數(shù)據(jù)到緩沖區(qū),從緩沖區(qū)讀數(shù)據(jù)。這樣的思路對不對。
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1