msp430利用SPI协议读写FLASH

又是4天,昨晚师兄说进度太慢,今天一天开挂,终于把FLASH搞定了。spi代码很短,一晚就写完,但是debug就用了两天多。
觉得最大的问题是在FLASH上,本以为flash和eeprom一样。其实flash有很大不同,首先是通信的协议不同,eeprom是i2c,而flash是spi;其次eeprom传设备地址就可以直接读写,需要应答,单双工。flash 不需要设备地址,但需要先传一个8位命令,然后再进行一系列操作。再flash还有很多保护机制,写之前要enable write;
flash 的储存模式以不同,flash 写的时候只能写0,1就不用写,所以一开始要先擦除(erase),使所有位都变成1.擦除是又有4种模式,4k,32k,64k和全部擦除(chip erase)。

(测试: mcu:msp430f149 , flash:W25Q64BV ;对应引脚已在文件说明)
以下是代码:

//SPI MODE = 3

#ifndef SPI_H_
#define SPI_H_

#include <msp430x14x.h>
       
#define SI_1 (P6OUT |= BIT7)
#define SI_0 (P6OUT &= ~BIT7)        //P6.7

#define SO_1 (P6OUT |= BIT5)
#define SO_0 (P6OUT &= ~BIT5)        //P6.5      

#define SCK_1 (P2OUT |= BIT2)
#define SCK_0 (P2OUT &= ~BIT2)        //P6.5 

#define SS_1 (P6OUT |= BIT6)
#define SS_0 (P6OUT &= ~BIT6)        //P6.6

void Delay(void);
void Init_SPI(void);
void Writebyte(unsigned char wdata);
unsigned char Readbyte(void);

#endif

#include <msp430x14x.h>
#include “SPI.h”

void Init_SPI(void)
{
   P6DIR |= (BIT6 + BIT7);         //P6.6 ncs2,P6.7 SI
   P6DIR &= ~BIT5;                 //SO
   P6OUT  |= BIT7;                    //SI
   P2DIR |= BIT2 + BIT3 + BIT4;    //SCK,NSC1,NSC3
   P2OUT |= BIT3 + BIT4;   
   SS_1;                            //nsc2
   SCK_1;                            //
  
  
}

void Delay(void)
{
   unsigned char i;
   for( i=0; i<20; i++)
   {
       _NOP();
   }
}

void Writebyte(unsigned char wdata)
{
   unsigned char i;

   for (i=0; i<8; i++)
   {
       SCK_0;
       if (wdata & BIT7)
       {
           SI_1;
       }
       else
       {
           SI_0;
       }
      
       wdata<<=1;
       SCK_1;

   }
}

unsigned char Readbyte (void)
{
   unsigned char i,rdata;

   for (i=0; i<8; i++)
   {
       SCK_1;
       rdata<<=1;
       if (P6IN&BIT5)
       {
           rdata |= 0x01;
       }
      
       SCK_0;
   }
return rdata;
}

#ifndef W25Q64B_H_
#define W25Q64B_H_

void ReadNbyte(unsigned char Haddr,unsigned char Maddr,unsigned char Laddr,unsigned char *rbuff, unsigned int n);
void Erase(unsigned char era,unsigned char Haddr,unsigned char Maddr,unsigned char Laddr);
void WriteNbyte(unsigned char Haddr,unsigned char Maddr,unsigned char Laddr,unsigned char *wbuff,unsigned int n);

#endif

#include “SPI.h”
#include “w25q64b.h”

void WriteNbyte (unsigned char Haddr,unsigned char Maddr,unsigned char Laddr,unsigned char *wbuff,unsigned int n)
{
   unsigned int i;
  
   SS_0;  
   Writebyte(0x06);
   SS_1;

   SS_0;
   SCK_1;
  
   Writebyte(0x02);
   Writebyte(Haddr);
   Writebyte(Maddr);
   Writebyte(Laddr);

   for (i=0; i<n; i++)
   {
       Writebyte(wbuff[i]);
   }

   SS_1;
}

void ReadNbyte (unsigned char Haddr,unsigned char Maddr,unsigned char Laddr,unsigned char *rbuff,unsigned int n)
{
   unsigned int i;

   SS_0;
   SCK_1;
   Writebyte(0x03);
   Writebyte(Haddr);
   Writebyte(Maddr);
   Writebyte(Laddr);

   SCK_0;

   for (i=0; i<n; i++)
   {
       rbuff[i] = Readbyte();
   }

   SS_1;
}

void Erase(unsigned char era,unsigned char Haddr,unsigned char Maddr,unsigned char Laddr)
{
   SS_0;
   SCK_1;
   Writebyte(0x06);
   SS_1;
  
   SS_0;
   SCK_1;
  
   Writebyte(era);
   Writebyte(Haddr);
   Writebyte(Maddr);
   Writebyte(Laddr);
      
   SS_1;
}

#include <msp430x14x.h>
#include “SPI.h”
#include “w25q64b.h”

unsigned char Rbuff[10];    //receive data

void Init_clk(void)            //initialization clock
{
   unsigned char j;
   BCSCTL1 &= ~XT2OFF;

   do
   {
       IFG1 &= ~ OFIFG;
       for ( j = 0xff ; j>0 ; j–){
           _NOP();
       }
   }
   while ((IFG1&OFIFG)!=0);

   BCSCTL2 |= SELM_2 + SELS;

}
void main()
{
   unsigned char i,write_data[10];
  
   WDTCTL = WDTPW + WDTHOLD;            //close watchdot
  
   for (i=0; i<9; i++)                    //assignment
   {
       write_data[i] = 97 + i;
   }
  
   Init_clk();
   Init_SPI();
  
   while (1)
   {
   Erase(0x20,0x00,0x00,0x00);   // Sector Erase (20h) 
   Delay();
  
   ReadNbyte(0x00,0x00,0x00,Rbuff,9);  //read data(9 char)
  
   WriteNbyte(0x00,0x00,0x00,write_data,9);  //write data(9 char)
  
   ReadNbyte(0x00,0x00,0x00,Rbuff,9);        //read data(9 char)
  
   }

}

 

(2012-08-10 22:33:21)

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据