找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3649|回复: 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 单片机教程网

快速回复 返回顶部 返回列表