huhuan6 发表于 2011-5-5 11:22:33

卡壳了,请教430 5438 SPI flash m25p32 能读到ID号,读不到数据,程序如下,希望有人能指点

SPI 的SCK配为1MHz


#include"msp430x54x.h"

#define uintunsignedint
#define uchar unsigned char

//==============================================================================
//P32
#define   SPI_CS       (1<<0)
#define   SPI_CS_H   P3DIR|= SPI_CS,P3OUT|= SPI_CS
#define   SPI_CS_L   P3DIR|= SPI_CS,P3OUT&= ~SPI_CS

#defineEEPROM_CMD_READ   0x03      // Read Command
#defineEEPROM_CMD_PP   0x02      // Page Program Command
#defineEEPROM_CMD_WRDI   0x04      // Reset Write Enable Latch Command
#defineEEPROM_CMD_WREN   0x06      // Set Write Enable Latch Command
#defineEEPROM_CMD_RDSR   0x05      // Read Status Register Command
#defineEEPROM_CMD_WRSR   0x01      // Write Status Register Command
#defineEEPROM_CMD_SE           0xD8                   // Sector Erase
#defineEEPROM_CMD_BE           0XC7                   // Bulk Erase

#define SPIMEM_DP          0xb9
#define SPIMEM_RES         0xab


void Init_Clk(void);

void delay(int n);
void delay1 (uint ms);
//SPI
void master_io_set();
void master_init();
void df_read_deviceid(char *buf);

void sub_init();
void sub_io_set();
//==============================================================================
void M25P32_Data_Initvol(void);
void M25P32_Sector_Erase(unsigned long address);
void M25P32_Bulk_Erase(void);
unsigned long M25P32_Data_Seek(unsigned long CurrectID, unsigned long TotalID);

void M25P32_WritePage(unsigned char * S,unsigned char num,unsigned char page,unsigned int address);
void M25P32_ReadData (unsigned char *EEPROM_data, unsigned char Num,unsigned char page,unsigned int address);
void read_ID(unsigned char *EEPROM_data);
void Write_Status(unsigned char com);
uchar Read_Status(void);
void M25P32_All_Erase(void);
void M25P32_Sector_Erase(unsigned long address);
void spi_reset (void);


unsigned char M25P32_Data;
unsigned int s_xuhao;
unsigned int Frequecy_Store ;   //储器频率值,默认为0001-6553.5
unsigned int s_temper ;      //存储温度寄存器

unsigned char Dat = {1,2,3,4,5,6,7,8,9};




char buf1;
uchar xx=1;
uint DATA_0 = 0;
uint DATA_1 = 0;
uchar status=0;

void main()
{
WDTCTL = WDTPW + WDTHOLD; //停止看门狗定时器

//P11DIR |= BIT2 + BIT1 + BIT0; //P11:012设为输出模式
//P11SEL |= BIT2 + BIT1 + BIT0; //设为第二功能作为频率输出

Init_Clk(); //时钟初始化
//SPI
master_io_set();
master_init();

_BIS_SR(GIE);

//read_ID(M25P32_Data);
M25P32_All_Erase();

while(1)
{

    //read_ID(M25P32_Data);
   
    M25P32_WritePage(Dat,9,0,0X0000);
    M25P32_ReadData (M25P32_Data, 9,0,0X0000);
   
   
}

}

//delay
void delay(int n)
{
    while(n--);
}
void delay1 (uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<1000;j++)
;
}
//时钟初始化
void Init_Clk(void)
{
P7SEL |= 0x03;                     // Port select XT1
UCSCTL6 &= ~(XT1OFF);                // Set XT1 On
UCSCTL6 |= XCAP_3;                        // Internal load cap

UCSCTL3 |= SELREF_0;                      // 选 FLL 时钟源
UCSCTL4 = SELA_0 + SELM_4 ++ SELS_4;    //选时钟源:ACLK = XT1 = 32768Hz, MCLK = SMCLK = 8MHz
UCSCTL5 = DIVPA_0 + DIVA_0 + DIVM_0 + DIVS_0;

__bis_SR_register(SCG0);                  // Disable the FLL control loop
UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_5;                      // Select DCO range 16MHz operation
UCSCTL2 = FLLD_1 + 243;                   // Set DCO Multiplier for 8MHz
                                          // (N + 1) * FLLRef = Fdco
                                          // (243 + 1) * 32768 = 8MHz
                                          // Set FLL Div = fDCOCLK/2
__bic_SR_register(SCG0);                  // Enable the FLL control loop
// Loop until XT1,XT2 & DCO stabilizes
do
{
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
                                          // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
}
while (SFRIFG1&OFIFG);                  // Test oscillator fault flag

}

//==============================================================================
//SPI
//spi 主机端口配置
void master_io_set()
{
P3SEL|=BIT1+BIT2+BIT3;
P3DIR|=BIT1+BIT3;
//P3DIR&=~BIT2;
}

void master_init()
{
UCB0CTL1|=UCSWRST;
UCB0CTL0|=UCMST+UCSYNC+UCCKPL+UCMSB;
UCB0CTL1|=UCSSEL_2;
UCB0BR0=8;
UCB0BR1=0;
UCB0CTL1&=~UCSWRST;
//UCB0IE|=UCRXIE;
}


//==============================================================================
//==============================================================================
//读ID号
void read_ID(unsigned char *EEPROM_data)
{
   unsigned char i;

   SPI_CS_L;   
   delay1 (10);
   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = 0x9f;
   for(i=0;i<4;i++)
   {
   while(!(UCB0IFG&UCRXIFG));
   UCB0TXBUF = 0XFF;
   EEPROM_data = UCB0RXBUF;;
   }
   SPI_CS_H;      
}
//等内部写周期完成
void M25P32_Check(void)
{
   do
   {
      SPI_CS_L;
      while(!(UCB0IFG&UCTXIFG));
      UCB0TXBUF = 0X05;//EEPROM_CMD_RDSR;
      while(!(UCB0IFG&UCRXIFG));
      UCB0TXBUF = 0xff;
      SPI_CS_H;
   }
   while(UCB0RXBUF & 0x01);
}
//写使能
void M25P32_WriteEN(void)
{
   SPI_CS_L;
   delay1 (10);
   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = 0X06;//EEPROM_CMD_WREN;
   SPI_CS_H;
   do
   {
      SPI_CS_L;
      delay1 (10);
      while(!(UCB0IFG&UCTXIFG));
      UCB0TXBUF = 0X05;//EEPROM_CMD_RDSR;
      while(!(UCB0IFG&UCRXIFG));
      UCB0TXBUF = 0xff;
      //SPI_CS_H;
   }
   while(UCB0RXBUF & 0x01);
   SPI_CS_H;
}
//写数据
void M25P32_WritePage(unsigned char * S,unsigned char num,unsigned char page,unsigned int address)
{
   unsigned char i;

   M25P32_WriteEN();
   
   SPI_CS_L;
   delay1 (10);
   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = EEPROM_CMD_PP;

   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = (page & 0xFF);

   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = (unsigned char)((address>>8)& 0x00FF);

   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = (unsigned char)((address)& 0x00FF);

   for (i = 0;i < num;i++)       
   {
      while(!(UCB0IFG&UCTXIFG));
      UCB0TXBUF = S;
   }
   SPI_CS_H;

   // Step5: Poll on the Write In Progress (WIP) bit in Read Status Register
   
   do
   {
      SPI_CS_L;
      while(!(UCB0IFG&UCTXIFG));
      UCB0TXBUF = 0X05;//EEPROM_CMD_RDSR;
      
      while(!(UCB0IFG&UCRXIFG));
      UCB0TXBUF = 0xff;
      SPI_CS_H;
   }
   while(UCB0RXBUF & 0x01);
   //return(0);
}

//读数据
void M25P32_ReadData (unsigned char *EEPROM_data, unsigned char Num,unsigned char page,unsigned int address)
{
   unsigned char i;

   SPI_CS_L;                     
   delay1 (10);
   
   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = 0X03;
   
   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = (page & 0XFF);

   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = (unsigned char)((address>>8) & 0x00FF);

   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = (unsigned char)((address) & 0x00FF);

      
   //while(!(UCB0IFG&UCTXIFG));
   //UCB0TXBUF = 0XFF;
         
   for(i=0;i<Num;i++)
   {
   while(!(UCB0IFG&UCRXIFG));
   UCB0TXBUF = 0XFF;
   EEPROM_data = UCB0RXBUF;
   }
   
   SPI_CS_H;                     
}
//写状态寄存器
void Write_Status(unsigned char com)
{
   M25P32_WriteEN();
   
   SPI_CS_L;                     

   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = 0x01;
   
   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = com;

   SPI_CS_H;   
   do
   {
      SPI_CS_L;
      while(!(UCB0IFG&UCTXIFG));
      UCB0TXBUF = 0X05;//EEPROM_CMD_RDSR;
      
      while(!(UCB0IFG&UCRXIFG));
      UCB0TXBUF = 0xff;
      SPI_CS_H;
   }
   while( (UCB0RXBUF & 0x01) == 0x01 );
}
//读状态寄存器
uchar Read_Status(void)
{
   unsigned char i=0;

   SPI_CS_L;                     // Activate Slave Select

   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = 0x05;

   while(!(UCB0IFG&UCRXIFG));
   UCB0TXBUF = 0X00;
   i = UCB0RXBUF;
   
   SPI_CS_H;                     // Deactivate Slave Select
   return(i);
}

//擦整片flash
void M25P32_All_Erase(void)
{
   M25P32_WriteEN();
   
   SPI_CS_L;   
   delay1 (20);
   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = 0xC7;
   SPI_CS_H;                     // Deactivate Slave Select
   delay1 (1000);
   do
   {
      SPI_CS_L;
      while(!(UCB0IFG&UCTXIFG));
      UCB0TXBUF = 0X05;//EEPROM_CMD_RDSR;
      while(!(UCB0IFG&UCRXIFG));
      UCB0TXBUF = 0xff;
      SPI_CS_H;
   }
   while(UCB0RXBUF & 0x01);
   
}

void M25P32_Sector_Erase(unsigned long address)
{
   SPI_CS_L;                     // Step1.1: Activate Slave Select
   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = 0X06;//EEPROM_CMD_WREN;
   SPI_CS_H;
   delay1 (1000);
   // Send the SE command
   SPI_CS_L;                     // Activate Slave Select
   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = 0xD8;

   // Send the sector address (MSB first)
   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = (unsigned char)((address >> 16)& 0x000000FF);

   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = (unsigned char)((address>>8)& 0x00FF);

   while(!(UCB0IFG&UCTXIFG));
   UCB0TXBUF = (unsigned char)((address)& 0x00FF);
   
   SPI_CS_H;
   delay1 (50000);
   // Poll on the Write In Progress (WIP) bit in Read Status Register
   do
   {
      SPI_CS_L;
      while(!(UCB0IFG&UCTXIFG));
      UCB0TXBUF = 0X05;//EEPROM_CMD_RDSR;
      while(!(UCB0IFG&UCRXIFG));
      UCB0TXBUF = 0xff;
      SPI_CS_H;
   }
   while( (UCB0RXBUF & 0x01) == 0x01 );
}

huhuan6 发表于 2011-5-5 11:24:51

http://cache.amobbs.com/bbs_upload782111/files_39/ourdev_636668JYEQYN.jpg
原理图如下 (原文件名:94ZMQK99ZE$D~~K{8)QJ3XN.jpg)

scofiled 发表于 2011-5-5 11:41:22

以前遇到过问题, 32Mb及以上容量 SPI FLASH
最好不要用杜邦线连接

会读不到数据或者读到错误数据, 就是连接线尽可能短,FLASH电源正负 加个104电容

huhuan6 发表于 2011-5-5 11:47:55

没有用杜连啊,也有加电容啊,只能读到ID号:00 20 20 16

suxilong 发表于 2013-2-18 15:38:17

请问有用FPGA操作的 这款flash 的吗?
页: [1]
查看完整版本: 卡壳了,请教430 5438 SPI flash m25p32 能读到ID号,读不到数据,程序如下,希望有人能指点