這幾天在寫一個有關數據保存的程序(芯片為AT45D642D),寫了很久,但是調試總是不成功,希望哪位高手指點下,謝謝!
主要的程序如下:
#define AT45DB_BUFFER_1_WRITE 0x84 /* 寫入第一緩沖區 */
#define AT45DB_BUFFER_2_WRITE 0x87 /* 寫入第二緩沖區 */
#define AT45DB_BUFFER_1_WRITE_FLASH 0x82 /* 寫入第一緩沖區 */
#define AT45DB_BUFFER_2_WRITE_FLASH 0x85 /* 寫入第二緩沖區 */
#define AT45DB_MM_H_READ 0x0B /* 連續陣列讀,高速模式*/
#define AT45DB_BUFFER_1_READ 0xD4 /* 讀取第一緩沖區 */
#define AT45DB_BUFFER_2_READ 0xD6 /* 讀取第二緩沖區 */
#define AT45DB_B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83 /* 將第一緩沖區的數據寫入主存儲器(擦除模式)*/
#define AT45DB_B2_TO_MM_PAGE_PROG_WITH_ERASE 0x86 /* 將第二緩沖區的數據寫入主存儲器(擦除模式)*/
#define AT45DB_MM_PAGE_TO_B1_XFER 0x53 /* 將主存儲器的指定頁數據加載到第一緩沖區 */
#define AT45DB_MM_PAGE_TO_B2_XFER 0x55 /* 將主存儲器的指定頁數據加載到第二緩沖區 */
#define AT45DB_PAGE_ERASE 0x81 /* 頁刪除(每頁512/528字節) */
#define AT45DB_SECTOR_ERASE 0x7C /* 扇區擦除(每扇區128K字節)*/
#define AT45DB_READ_STATE_REGISTER 0xD7 /* 讀取狀態寄存器 */
#define AT45DB_BLACK_ERASE 0x50 /* 塊刪除(每塊4KByte)*/
#define AT45DB_MM_PAGE_READ 0xD2 /* 直接讀主存儲器的內存頁*/
#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; //設置SPI單向或者雙向的數據模式:SPI設置為雙線雙向全雙工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //設置SPI工作模式:設置為主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //設置SPI的數據大小:SPI發送接收8位幀結構
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //選擇了串行時鐘的穩態:時鐘 懸空低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //數據捕獲于第二個時鐘沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信號由硬件(NSS管腳)還是 軟件(使用SSI位)管理:內部NSS信號有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //定義波特 率預分頻的值:波特率預分頻值為256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定數據傳輸從MSB位還是LSB位開始:數據傳輸從MSB位開始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值計算的多項式
SPI_Init(SPI2, &SPI_InitStructure); //根據SPI_InitStruct中指定的參數初始化外設SPIx寄存器
SPI_Cmd(SPI2, ENABLE); //使能SPI外設
/***SPI_ReadWrite_Byte()****SPI發送或接收1字節***********************/
static u8 SPI_ReadWrite_Byte(u8 byte)
{
/*等待發送寄存器空*/
while((SPI2->SR & SPI_I2S_FLAG_TXE)==RESET);
/*發送一個字節*/
SPI2->DR = byte;
/* 等待接收寄存器有效*/
while((SPI2->SR & SPI_I2S_FLAG_RXNE)==RESET);
return(SPI2->DR);
}
/***Dataflash_read_status()*****讀取狀態寄存器**************************/
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()****設定AT45DB在讀取的時候,將數據送往內部的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內部頁數據***************/
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()******將數據寫入AT45DB161內部頁存儲空間***/
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()*****連續讀AT45DB161內部緩沖區1或者緩沖區2的數據***/
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()*****連續寫數據到SPI Flash內部**************/
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()*****從某一頁的某個位置開始讀取一定長度的數據,放入數據緩沖區***/
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()*****刪除對應的頁 每頁對應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 塊刪除,每一塊對應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);
}}
如果保存數據成功的話,顯示器上present_count2中的內容應和present_count1中的一樣,可是現在顯示屏顯示的是12個BC,不知道為什么,求幫助。。
|