久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4454|回復: 4
收起左側

STM32F103VC SPI 驅動AT45D642D問題

[復制鏈接]
ID:58348 發表于 2014-8-13 21:39 | 顯示全部樓層 |閱讀模式
這幾天在寫一個有關數據保存的程序(芯片為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,不知道為什么,求幫助。。
回復

使用道具 舉報

ID:1 發表于 2014-8-13 23:29 | 顯示全部樓層
注意延時時間,,現在是讀失敗 還是寫失敗?
回復

使用道具 舉報

ID:58348 發表于 2014-8-14 06:25 來自手機 | 顯示全部樓層
寫失敗
回復

使用道具 舉報

ID:58348 發表于 2014-8-14 06:38 來自手機 | 顯示全部樓層
擦除成功,寫的時候,沒寫進去。
回復

使用道具 舉報

ID:58348 發表于 2014-8-14 09:17 | 顯示全部樓層
admin 發表于 2014-8-13 23:29
注意延時時間,,現在是讀失敗 還是寫失敗?

擦出頁,寫數據到緩沖區,從緩沖區到內部頁存儲器;從內部頁存儲器讀數據到緩沖區,從緩沖區讀數據。這樣的思路對不對。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一区二区在线免费观看 | 在线国产一区二区三区 | 亚洲精品免费在线观看 | 欧美一二三区 | 日韩精品视频在线播放 | 在线免费观看a级片 | 国产传媒在线观看 | 久久香蕉精品视频 | 日韩精品视频在线播放 | 欧美成人综合 | 日本福利视频 | 欧美性猛交一区二区三区精品 | 国产精品美女在线观看 | 日韩一级在线 | 午夜国产精品视频 | 亚洲视频免费播放 | 国产清纯白嫩初高生在线播放视频 | 日韩精品在线观看一区二区 | 日韩一区二区免费视频 | 国产高清视频一区二区 | 一级黄a视频 | 亚洲精品4 | 中文字幕一区在线观看视频 | 国产sm主人调教女m视频 | 精品欧美一区二区精品久久 | 国产伦精品一区二区三区精品视频 | av中文字幕在线 | 午夜一区二区三区 | 欧美在线一区二区三区 | 日韩天堂av | 日日夜夜操天天干 | 国产亚洲精品美女久久久久久久久久 | 成人二区 | 久久精品视频91 | 91麻豆产精品久久久久久夏晴子 | 波多野吉衣在线播放 | 综合久久一区 | 成人久久一区 | 国产精品日本一区二区在线播放 | 岛国av一区二区 | 久久美女视频 |