/*****************《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比较合适

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

  1. SPI—读写串行FLASH

    1 SPI协议简介 SPI协议是由摩托罗拉公司提出的通讯协议(SerialPeripheralInterface),即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在ADC.LCD等设备 ...

  2. 第24章 SPI—读写串行FLASH—零死角玩转STM32-F429系列

    第24章     SPI-读写串行FLASH 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...

  3. SPI—读写串行FLASH(时序中的无关项)

    SPI-读写串行FLASH 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章 ...

  4. SPI应用——W25Q128串行FLASH

    一.FLASH存储器介绍 FLASH存储器又称闪存,它与EEPROM都是掉电后数据不丢失的存储器,但FLASH存储器容量普遍大于EEPROM,现在基本取代了它的地位.在存储控制上,最主要的区别是FLA ...

  5. 25章 SPI—读写串行FLASH

    SPI 协议简介 3 条总线分别为SCK(时钟).MOSI(主出从入).MISO(主入从出),片选线为SS1.2.3(从设备)(多少设备也就这三条ss) MOSI和MISO能看出是全双工(输入输出两条 ...

  6. STM32CUBEIDE之SPI读写FLASH进阶串行FLASH文件系统FatFs

    预备知识 >>W25Q128是16M spi flash,一共有256个block ,每个Block 64KB. >>一个Block可以分割为16个扇区(small secto ...

  7. 3.3 SPI串行Flash配置模式

     SPI串行Flash配置模式 1.SPI串行配置介绍 串行Flash的特点是占用管脚比较少,作为系统的数据存贮非常合适,一般都是采用串行外设接口(SPI 总线接口).Flash 存贮器与EEPROM ...

  8. 利用硬件SPI控制WS2812,驱动1024颗灯珠

    " 简 介: 利用ESP32中的硬件SPI控制WS2812的显示.使用了高频三极管9018 作为输出接口反向器,确定合适的电阻参数,验证了驱动方案的硬件和软件的可行性. 关键词: WS281 ...

  9. STM32F103标准库开发---SPI实验---读写 W25Q128 外部 Flash

    STM32F103标准库开发----目录 W25Q128读写----程序源码----点击下载 W25Qxx全系列数据手册-点击下载 一.实验前期准备 本次实验的 MCU 是 STM32F103C8T6 ...

最新文章

  1. 静态时序分析的概念以及约束的作用理解
  2. 图像矫正与车牌识别资料整理
  3. Java面试题(亲身经历)
  4. 华为海外版操作系统曝光?HUAWEI ARK OS现身
  5. caffe(4):mnist实例---手写数字识别
  6. FAT32文件系统结构
  7. 无线AP 传输、认证
  8. wangEditor上传不了图片
  9. 搜狗输入法 for Mac
  10. Java视频教程百度网盘,Java精选面试Spring全家桶
  11. ARCore⭐四、图片识别
  12. 手机实名认证接口有哪些类别?
  13. 腾讯云服务器有多垃圾,腾讯云真的垃圾,无处申诉,腾讯服务器垃圾
  14. [深度应用]·实战掌握PyTorch图片分类简明教程
  15. 普氏分析 matlab,降维和特征提取 - MATLAB Simulink - MathWorks 中国
  16. 无人驾驶车辆路径跟踪的增量式PID控制
  17. 计算机和电脑键盘进水怎么办,小编教你笔记本键盘进水了怎么办
  18. 图像中的高频分量和低频分量
  19. 【详细】AS400系统安装gcc教程
  20. CS230学习笔记(一)

热门文章

  1. Facebook Shop和Facebook Marketplace如何选择?
  2. Adobe Premiere Pro 2021安装方法(附阿里云盘链接)
  3. 怎么释放mysql连接数_MySQL连接数太多应该怎么解决?
  4. 如何快速开发可演示的微信小应用(应用号)
  5. 2022前端面经---(js高级)一文让你搞懂闭包
  6. git pull 代码后,远程删除了文件,本地未提交文件被删除了怎么办
  7. Linux的ntp和firewalld服务_16
  8. Ubuntu 18.04 安装博通(Broadcom)无线网卡驱动
  9. 包膜机西门子PLC和维纶触摸屏程序,西门子1512和5台1214C通讯控制20轴程序
  10. Danalab线束测试仪