下载的内容:MSP430F149利用硬件SPI口读写串行Flash M25P64

/*****************《SPI_Flash.C》**************************************/

#include "SPI_Flash.h"

//在这个里有被"/* */"引起来的代码是利用IO口模仿SPI时序,要利用模仿的SPI接口,需要将子函数的
//“ MSP430_SPI_Read_Btye();            先要预读一次,这可能是在硬件SPI的特殊情况,在通过IO口模拟的情况下,不需要”
//去掉就可以了
//使用过程先调用Master_SPI_Init() , 接着SPI_Flash_Sector_Erase() , SPI_Flash_Read_ID() ,SPI_Flash_Read_Elecsign()上述两个函数的返//回值可以验证你的结果是不是对。
/*#define CLOCK_LOW (P5OUT &=~BIT3)
#define CLOCK_HIGH (P5OUT |=BIT3)
#define MOSI_LOW (P5OUT &=~BIT1)
#define MOSI_HIGH (P5OUT |= BIT1)*/
void Master_SPI_Init(void)

  U1CTL = CHAR+ SYNC + MM;              //八位数据,SPI模式,主机
  U1TCTL = STC +SSEL1 ;                  //选择ACLK作为时钟源,三线SPI模式
  U1BR0 = 0x02;                         //波特率分频因子位4
  U1BR1 = 0x00;                         //
  U1MCTL = 0x00;                        
  ME2 |= USPIE1;                       //SPI1模块允许
  P5SEL |= 0x0E;  
  //U1IE |= URXIE1 + UTXIE1;    // Enable USART0 RX interrupt 
  U1CTL &= ~SWRST;                     // SWRET复位,USART1模块允许
  SPI_Flash_Dir |= BIT0 +BIT4 ;               //hold和CS信号输出
  SPI_Flash_CS_ON;
  SPI_Flash_CS_OFF;                       //CS信号要置位,等到写指令或数据时再将其清零
  SPI_Flash_Stop_Hold;                    //不中止
  //_EINT();
 /* SPI_Flash_Dir |=BIT0 +BIT1 +BIT3 +BIT4;
  SPI_Flash_CS_ON;
  SPI_Flash_CS_OFF;                       //CS信号要置位,等到写指令或数据时再将其清零
  SPI_Flash_Stop_Hold;                   //不中止
*/
}

void MSP430_SPI_Write_Byte(uchar data)
{
  IFG2 &= ~UTXIFG1;                    // 清除标志,USART1发送中断标志位
  U1TXBUF = data;                      //将数据发送到U1TXBUF中,自动发送
  while (!(IFG2 & UTXIFG1));           // 等待发送完成
  IFG2 &= ~URXIFG1;                    //因为在MOSI发送数据的时候,也可能有数据在SOMI接口接收数据,所以将接收标志位清掉
  IFG2 &= ~UTXIFG1;                    //清掉发送标志
/*  uchar i;
  for(i=0 ; i<8 ;i++)
  {
    CLOCK_LOW;
    _NOP();
    if((data & 0x80)!=0) MOSI_HIGH;
    else                MOSI_LOW;
    data<<=1;
    CLOCK_HIGH;
    _NOP();
  }
  CLOCK_LOW;*/
}

uchar MSP430_SPI_Read_Btye(void)
{
  uchar data=0;
  IFG2 &= ~UTXIFG1;            //清除标志
  U1TXBUF = 0x00;
  while (!(IFG2 & URXIFG1));             // 等待
  data = U1RXBUF;                   // 接收
  IFG2 &= ~URXIFG1;
  while(!(IFG2 & UTXIFG1));    //等待 U1TXBUF = 0发送完成
  IFG2 &= ~UTXIFG1;            //清除标志RXBUF1
  return data;
 /*   uchar data=0,i;
  for(i=0; i<8; i++)
  {
    CLOCK_LOW;
    _NOP();
    data <<=1;
    if((P5IN & BIT2)!=0) data |=0x01;
    else                 data &=0x0FE;
    CLOCK_HIGH;
    _NOP();
  }
  return data;*/
}


void SPI_Flash_Read_Busy(void)
{
  uchar data;
  do
  {
    SPI_Flash_CS_ON;                         //片选有效
    MSP430_SPI_Write_Byte(RDSR);             //读状态寄存器0x05
    MSP430_SPI_Read_Btye();
    data = MSP430_SPI_Read_Btye();           //从接收缓存中读取数据??????
    SPI_Flash_CS_OFF;                        //片选无效
   }while(data&0x01 != 0);                  //当读取的数据末位为1表示繁忙,为0表示空闲  
}

//写使能
void SPI_Flash_Write_En(void)
{
  SPI_Flash_CS_ON;
  MSP430_SPI_Write_Byte(WREN);    //写使能0x06          
  SPI_Flash_CS_OFF;
}


//块擦除
void SPI_Flash_Bulk_Erase(void)
{
  SPI_Flash_Read_Busy();            // 读忙状态
  SPI_Flash_Write_En();             //写使能
  SPI_Flash_Read_Busy();            // 读忙状态
  SPI_Flash_CS_ON;                  //片选有效
  MSP430_SPI_Write_Byte(BE);        //整块擦除0x0C7
  SPI_Flash_CS_OFF;                 //片选无效
  SPI_Flash_Read_Busy();
}


//某一扇区擦除 输入参数为某一扇区的24位首地址
void SPI_Flash_Sector_Erase(unsigned long Addr)
{
  uchar Addr_High,Addr_Midd,Addr_Low;
  Addr_High = (Addr & 0x00ff0000) >> 16;
  Addr_Midd = (Addr & 0x0000ff00) >> 8;
  Addr_Low = Addr & 0x000000ff;
  SPI_Flash_Read_Busy();            // 读忙状态
  SPI_Flash_Write_En();             //写使能
  SPI_Flash_Read_Busy();            // 读忙状态  
  SPI_Flash_CS_ON;                  //片选有效
  MSP430_SPI_Write_Byte(SE);        //单块擦除0x0D8
  MSP430_SPI_Write_Byte(Addr_High); //写地址高位
  MSP430_SPI_Write_Byte(Addr_Midd); //写地址高中间位
  MSP430_SPI_Write_Byte(Addr_Low);  //写地址低位
  SPI_Flash_CS_OFF;                 //片选无效
  SPI_Flash_Read_Busy();
}

//对某一页写数据 输入参数分别为:某一24首地址,要写的数据缓存,要写的数据长度
void SPI_Flash_Write_Data(unsigned long Addr ,uchar *Data_Buff ,uchar Data_Len)
{
  uchar Addr_High,Addr_Midd,Addr_Low,i;
  Addr_High = (Addr & 0x00ff0000) >> 16;
  Addr_Midd = (Addr & 0x0000ff00) >> 8;
  Addr_Low = Addr & 0x000000ff;
  SPI_Flash_Read_Busy();            // 读忙状态
  SPI_Flash_Write_En();             //写使能
  SPI_Flash_Read_Busy();            // 读忙状态  
  SPI_Flash_CS_ON;                  //片选有效
  MSP430_SPI_Write_Byte(PP);        //页面数据写入0x02       
  MSP430_SPI_Write_Byte(Addr_High); //写地址高位
  MSP430_SPI_Write_Byte(Addr_Midd); //写地址高中间位
  MSP430_SPI_Write_Byte(Addr_Low);  //写地址低位
  for(i =0 ; i<Data_Len ;i++)
  {
    MSP430_SPI_Write_Byte(Data_Buff[i]);
    _NOP();
  }
  SPI_Flash_CS_OFF;                 //片选无效
}

//对某一页读数据 输入参数分别为:某24位地址,读出得数据存放的缓存,要读得数据长度
void SPI_Flash_Read_Data(unsigned long Addr ,uchar *Data_Buff ,uchar Data_Len)
{
  uchar Addr_High,Addr_Midd,Addr_Low,i;
  Addr_High = (Addr & 0x00ff0000) >> 16;
  Addr_Midd = (Addr & 0x0000ff00) >> 8;
    
  Addr_Low = Addr & 0x000000ff;
  SPI_Flash_Read_Busy();            // 读忙状态
  SPI_Flash_Write_En();             //写使能
  SPI_Flash_Read_Busy();            // 读忙状态  
  SPI_Flash_CS_ON;                  //片选有效
  MSP430_SPI_Write_Byte(READ);      //读取数据0x03 
  
  MSP430_SPI_Write_Byte(Addr_High); //写地址高位
  MSP430_SPI_Write_Byte(Addr_Midd); //写地址高中间位
  MSP430_SPI_Write_Byte(Addr_Low);  //写地址低位
  MSP430_SPI_Read_Btye();            先要预读一次,这可能是在硬件SPI的特殊情况,在通过IO口模拟的情况下,不需要
  for(i =0 ; i<Data_Len ;i++)
  {
    Data_Buff[i] = MSP430_SPI_Read_Btye();   //从接收缓存中读取数据??????
    _NOP();
  }
  SPI_Flash_CS_OFF;                 //片选无效
}

//读芯片ID号 生产商ID号20H,和Device ID号20H、17H ;输入参数为三个字节的数组
void SPI_Flash_Read_ID(uchar *ID)
{
  SPI_Flash_CS_ON;                  //片选有效
  MSP430_SPI_Write_Byte(RDID);      //读标识0x9F
  MSP430_SPI_Read_Btye();            先要预读一次,这可能是在硬件SPI的特殊情况,在通过IO口模拟的情况下,不需要
  ID[0] = MSP430_SPI_Read_Btye();                   //从接收缓存中读取数据??????
  ID[1] = MSP430_SPI_Read_Btye();                   //从接收缓存中读取数据??????
  ID[2] = MSP430_SPI_Read_Btye();                   //从接收缓存中读取数据??????
  SPI_Flash_CS_OFF;                 //片选无效
}

//读电子签名,无输入参数,返回的数值应为16H
uchar SPI_Flash_Read_Elecsign(void)
{
  uchar status;

  SPI_Flash_CS_ON;                  //片选有效
  MSP430_SPI_Write_Byte(RES);       //读电子签名0x0AB
  MSP430_SPI_Write_Byte(0x00);
  MSP430_SPI_Write_Byte(0x00);
  MSP430_SPI_Write_Byte(0x00);
  MSP430_SPI_Read_Btye();            先要预读一次,这可能是在硬件SPI的特殊情况,在通过IO口模拟的情况下,不需要
  status = MSP430_SPI_Read_Btye();             //从接收缓存中读取数据??????
  SPI_Flash_CS_OFF;                 //片选无效

  return status;
}


//去除写保护状态
void SPI_Flash_Unprotected(void)
{
  SPI_Flash_CS_ON;                  //片选有效
  SPI_Flash_Write_En();             //写使能
  MSP430_SPI_Write_Byte(WRSR);      //写状态寄存器0x01
  MSP430_SPI_Write_Byte(0x00);
  SPI_Flash_CS_OFF;                 //片选无效
}
/***********《SPI_Flash.h》*****************************************************/

#ifndef _SPI_FLASH_H
#define _SPI_FLASH_H
/*******************************************************************************
2012-7-21    BY    ZJX
//使用时只需修改前7行代码
*******************************************************************************/
#include "my_msp430x14x.h"

#define WREN 0x06                   //写使能
#define WRDI 0x04                   //写无效
#define RDID 0x9F                   //读标识


#define RDSR 0x05                   //读状态寄存器
#define WRSR 0x01                   //写状态寄存器
#define READ 0x03                   //读取数据
#define FAST_READ 0x0B              //快速读取数据
#define PP 0x02                     //页面数据写入
#define SE 0x0D8                    //单块擦除
#define BE 0x0C7                    //整块擦除
#define RES 0x0AB                   //读电子签名


#define SPI_Flash_Hold_Out P5OUT
#define SPI_Flash_CS_Out P5OUT
#define SPI_Flash_Dir P5DIR
#define SPI_Flash_Hold_BIT BIT4
#define SPI_Flash_CS_BIT BIT0
#define SPI_Flash_Hold (SPI_Flash_Hold_Out &= ~SPI_Flash_Hold_BIT)
#define SPI_Flash_Stop_Hold (SPI_Flash_Hold_Out |= SPI_Flash_Hold_BIT)
#define SPI_Flash_CS_OFF (SPI_Flash_CS_Out |=SPI_Flash_CS_BIT)
#define SPI_Flash_CS_ON (SPI_Flash_CS_Out &= ~SPI_Flash_CS_BIT)

void Master_SPI_Init(void);
void MSP430_SPI_Write_Byte(uchar data);
void SPI_Flash_Read_Busy( void );
void SPI_Flash_Write_En(void);
void SPI_Flash_Bulk_Erase(void);
void SPI_Flash_Sector_Erase(unsigned long Addr);
void SPI_Flash_Write_Data(unsigned long Addr ,uchar *Data_Buff ,uchar Data_Len);
void SPI_Flash_Read_Data(unsigned long Addr ,uchar *Data_Buff ,uchar Data_Len);
void SPI_Flash_Read_ID(uchar *ID);
uchar SPI_Flash_Read_Elecsign(void);
void SPI_Flash_Unprotected(void);
#endif

链接: https://pan.baidu.com/s/1kAQgutIqBOV433cngYP24g

提取码: cysd  

最后放弃了25P64了,因为擦除需要64K内存。103c8t6才20K的RAM。4k的w25q64比较合适

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值