为了驱动SPI FLASH而写的驱动程序,写的时候主要是板子的自带SPI接口被占用,只好使用IO口模拟一个SPI接口程序;

w25q16 芯片工作在SPI工作模式0和模式3中;在此spi的原理不多做说明,只需知道模式0和模式3主要是在时钟的上升沿采样即可。(时钟空闲时电平为低,则为模式1;时钟空闲时电平为高,则为模式3)

下面直接贴代码:

#define W25Q16_PAGE_SIZE    256                          //一页的大小,256字节
#define W25Q16_SECTOR_SIZE (4*1024)                      //扇区大小,字节
#define W25Q16_BLOCK_SIZE  (16*W25Q16_SECTOR_SIZE)
#define W25Q16_SIZE        (32*W25Q16_BLOCK_SIZE)#define MOSI_H                  (GpioDataRegs.GPASET.bit.GPIO16 = 1)
#define MOSI_L                   (GpioDataRegs.GPACLEAR.bit.GPIO16 = 1)
#define SPICLK_H                 (GpioDataRegs.GPASET.bit.GPIO17 = 1)
#define SPICLK_L                 (GpioDataRegs.GPACLEAR.bit.GPIO17 = 1)#define FLASH_CS_SET            (GpioDataRegs.AIOSET.bit.AIO12  = 1)
#define FLASH_CS_RESET          (GpioDataRegs.AIOCLEAR.bit.AIO12  = 1)#define READ_MISO GpioDataRegs.GPADAT.bit.GPIO6const Uint8 byDUMMY = 0xff;void SPI_Init(void)
{FLASH_CS_SET;SPICLK_L;MOSI_H;
}static void SPI_Set_MOSI(Uint8 val)
{if(val)MOSI_H;elseMOSI_L;
}/*******************************************************************************
* Function Name  : SPIReadWriteByte
* Description    : SPI读写函数
* Input          : val      传输数据
* Output         : RevData  接收数据
* Return         : None
*******************************************************************************/
static Uint8 SPIReadWriteByte(Uint8 val)
{Uint16 i;Uint8  RevData = 0;//Uint16 wReadDO;for(i=0; i<8; i++){SPICLK_L;SPI_Set_MOSI(val & 0x80);DSP28x_usDelay(1);val <<= 1;SPICLK_H;RevData <<= 1;//wReadDO = GpioDataRegs.GPADAT.bit.GPIO6;RevData |=READ_MISO;DSP28x_usDelay(1);}return RevData;
}/*******************************************************************************
* Function Name  : W25Q16_ReadWriteDate
* Description    : SPIFLASH 读写函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
Uint8 W25Q16_ReadWriteDate(Uint8 val)
{return SPIReadWriteByte(val);
}/*******************************************************************************
* Function Name  : W25q64_WriteEnable
* Description    : 写使能
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void W25q16_WriteEnable(void)
{FLASH_CS_RESET;W25Q16_ReadWriteDate(0x06);FLASH_CS_SET;
}/*******************************************************************************
* Function Name  : W25Q16_WaitForWriteEnd
* Description    : 等待FLASH内部时序操作完成
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void W25Q16_WaitForWriteEnd(void)
{Uint8 status = 0;FLASH_CS_RESET;W25Q16_ReadWriteDate(0x05);do{status = W25Q16_ReadWriteDate(byDUMMY);}while((status & 0x01) == 1);FLASH_CS_SET;
}/*******************************************************************************
* Function Name  : W25q16_WriteStatusReg1
* Description    : 写状态寄存器1
* Input          : status:状态值
* Output         : None
* Return         : None
*******************************************************************************/
void W25q16_WriteStatusReg1(Uint16 status)
{W25q16_WriteEnable();FLASH_CS_RESET;W25Q16_ReadWriteDate(0x01);W25Q16_ReadWriteDate(status & 0xFF);W25Q16_ReadWriteDate((status>>8) & 0xFF);FLASH_CS_SET;W25Q16_WaitForWriteEnd();
}/*******************************************************************************
* Function Name  : W25q16_ReadStatus
* Description    : 读状态寄存器
* Input          : None
* Output         : None
* Return         : 状态寄存器值
*******************************************************************************/
Uint16 W25q16_ReadStatus(void)
{Uint16 status=0;FLASH_CS_RESET;W25Q16_ReadWriteDate(0x05);status = W25Q16_ReadWriteDate(byDUMMY);FLASH_CS_SET;FLASH_CS_RESET;W25Q16_ReadWriteDate(0x35);status |= W25Q16_ReadWriteDate(byDUMMY)<<8;FLASH_CS_SET;return status;
}/*******************************************************************************
* Function Name  : W25q16_ReadDeviceID
* Description    : 读芯片ID
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
Uint16 W25q16_ReadDeviceID(void)
{Uint8 DeviceID=0;FLASH_CS_RESET;W25Q16_ReadWriteDate(0xAB);W25Q16_ReadWriteDate(byDUMMY);W25Q16_ReadWriteDate(byDUMMY);W25Q16_ReadWriteDate(byDUMMY);DeviceID = W25Q16_ReadWriteDate(0X00);FLASH_CS_SET;return DeviceID;
}/*******************************************************************************
* Function Name  : W25q16_ReadJEDE_ID
* Description    : 读芯片ID
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
Uint16 W25q16_ReadJEDE_ID(void)
{Uint16 DeviceID=0;FLASH_CS_RESET;W25Q16_ReadWriteDate(0x9F);W25Q16_ReadWriteDate(byDUMMY);
//  W25Q16_ReadWriteDate(byDUMMY);
//  W25Q16_ReadWriteDate(0x00);DeviceID = W25Q16_ReadWriteDate(byDUMMY)<<8;DeviceID |= W25Q16_ReadWriteDate(byDUMMY);FLASH_CS_SET;return DeviceID;
}/*******************************************************************************
* Function Name  : W25q16_Read
* Description    : 读数据
* Input          : buf:数据缓冲区len:长度addr:起始地址
* Output         : None
* Return         : None
*******************************************************************************/
void W25q16_Read(Uint8 *buf, Uint32 len, Uint32 addr)
{Uint32 i;FLASH_CS_RESET;W25Q16_ReadWriteDate(0x03);W25Q16_ReadWriteDate((addr & 0xFF0000)>>16);W25Q16_ReadWriteDate((addr & 0x00FF00)>>8);W25Q16_ReadWriteDate(addr & 0xFF);for (i=0; i<len; i++){buf[i] = W25Q16_ReadWriteDate(byDUMMY);}FLASH_CS_SET;
}/*******************************************************************************
* Function Name  : W25q16_4KErase
* Description    : 4K片擦除
* Input          : addr:起始地址
* Output         : None
* Return         : None
*******************************************************************************/
void  W25q16_4KErase(Uint32 addr)
{W25q16_WriteEnable();FLASH_CS_RESET;W25Q16_ReadWriteDate(0x20);W25Q16_ReadWriteDate((addr & 0xFF0000)>>16);W25Q16_ReadWriteDate((addr & 0x00FF00)>>8);W25Q16_ReadWriteDate(addr & 0xFF);FLASH_CS_SET;W25Q16_WaitForWriteEnd();
}/*******************************************************************************
* Function Name  : W25q16_32KErase
* Description    : 32K片擦除
* Input          : addr:起始地址
* Output         : None
* Return         : None
*******************************************************************************/
void  W25q16_32KErase(Uint32 addr)
{W25q16_WriteEnable();FLASH_CS_RESET;W25Q16_ReadWriteDate(0x52);W25Q16_ReadWriteDate((addr & 0xFF0000)>>16);W25Q16_ReadWriteDate((addr & 0x00FF00)>>8);W25Q16_ReadWriteDate(addr & 0xFF);FLASH_CS_SET;W25Q16_WaitForWriteEnd();
}/*******************************************************************************
* Function Name  : W25q16_64KErase
* Description    : 64K片擦除
* Input          : addr:起始地址
* Output         : None
* Return         : None
* Date           : 2014-10-24
* Author         : ADT LL
*******************************************************************************/
void  W25q16_64KErase(Uint32 addr)
{W25q16_WriteEnable();FLASH_CS_RESET;W25Q16_ReadWriteDate(0xD8);W25Q16_ReadWriteDate((addr & 0xFF0000)>>16);W25Q16_ReadWriteDate((addr & 0x00FF00)>>8);W25Q16_ReadWriteDate(addr & 0xFF);FLASH_CS_SET;W25Q16_WaitForWriteEnd();
}/*******************************************************************************
* Function Name  : W25q16_PageProgram
* Description    : 页写
* Input          : buf:要写内的数据len:数据长度add:起始地址
* Output         : None
* Return         : 状态码
*******************************************************************************/
static void W25q16_PageProgram(Uint8 *buf, Uint16 len, Uint32 addr)
{//是否判断len 与addr 超限问题???//......W25q16_WriteEnable();FLASH_CS_RESET;W25Q16_ReadWriteDate(0x02);W25Q16_ReadWriteDate((addr & 0xFF0000)>>16);W25Q16_ReadWriteDate((addr & 0x00FF00)>>8);W25Q16_ReadWriteDate(addr & 0xFF);while (len--){W25Q16_ReadWriteDate(*buf);buf++;}FLASH_CS_SET;W25Q16_WaitForWriteEnd();
}/*******************************************************************************
* Function Name  : W25q64_Write
* Description    : 数据存储
* Input          : buf:要写内的数据len:数据长度add:起始地址
* Output         : None
* Return         : None
*******************************************************************************/
void W25q16_Write(Uint8 *buf, Uint16 len, Uint32 addr)
{Uint8 pagenum;Uint8 addrbyte;//最低八位地址addrbyte = addr%W25Q16_PAGE_SIZE;if (len > (W25Q16_PAGE_SIZE - addrbyte))//跨页了{W25q16_PageProgram(buf, W25Q16_PAGE_SIZE - addrbyte, addr);//写满本页addr += W25Q16_PAGE_SIZE-addrbyte;buf += W25Q16_PAGE_SIZE-addrbyte;len -= W25Q16_PAGE_SIZE-addrbyte;pagenum = len/W25Q16_PAGE_SIZE;while (pagenum--){W25q16_PageProgram(buf, W25Q16_PAGE_SIZE, addr);addr += W25Q16_PAGE_SIZE;buf += W25Q16_PAGE_SIZE;len -= W25Q16_PAGE_SIZE;}W25q16_PageProgram(buf, len, addr);}else{W25q16_PageProgram(buf, len, addr);}
}

模拟SPI驱动W25Q16程序 (DSP 28X系列)相关推荐

  1. 【全志T113-S3_100ask】15-2 linux系统gpio模拟spi驱动屏幕——ILI9341

    [全志T113-S3_100ask]15-2 linux系统gpio模拟spi驱动屏幕--ILI9341 背景 (一)查阅参考文档 (二)使能内核模块 (三)修改设备树 (四)测试 (五)后语 背景 ...

  2. 鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920_基于code-2.0-CANARY

    鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920源码.rar-C文档类资源-CSDN下载鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920源码.rar博文链接:htt ...

  3. 外设驱动库开发笔记43:GPIO模拟SPI驱动

      SPI总线是我们常用的串行设备接口,一般情况下我们都会适应硬件SPI接口,但有些时候当硬件端口不足时,我们也希望可以使用软件来模拟SPI硬件接口,特别是要求不是很高的时候.在这一篇中我们将来讨论如 ...

  4. MSP430杂谈--AD7793硬件SPI驱动与模拟SPI驱动

    最近项目中用到了AD7793读取铂电阻值来得到相应的温度,编写了基于MSP430的硬件驱动程序和模拟驱动程序,并且能成功运行,现在记录一下分享给大家. AD7793硬件IIC驱动完整版下载链接:htt ...

  5. 鸿蒙开发板Hi3861模拟SPI驱动JLX12864_LCD(UC1701X)_基于code-2.0

    鸿蒙开发板驱动晶联讯LCDjlx12864_lcd_hi3861源码-C文档类资源-CSDN下载鸿蒙开发板驱动晶联讯LCDjlx12864_lcd_hi3861源码博文介绍https://t更多下载资 ...

  6. MAX535 单路13位DAC 模拟SPI驱动

    一.MAX535 max535是低功耗.13位.电压输出DAC,采用串行接口和µMAX封装.MAX535通过单个+5V/3.3V电源工作,仅需要280µA电流工作. MAX535/MAX5351适用于 ...

  7. TLV5618 双路12位DAC 模拟SPI驱动

    一.TLV65618芯片 TLV5618A 带掉电功能 2.7V-5.5V,低功耗双路 12 位数模转换器 特点 ●双路 12 位电压输出 DAC ●可编程调节转换时间 - 快速模式 3μs - 低速 ...

  8. STM8S1003 模拟SPI 驱动 SI4432

    网上关于stm8s1003 驱动si4432的 驱动不是很多 ,我也是弄了大半天才可以和si4432 spi驱动成功. 接下来要做无线收发和组网. 暂时先贴 spi驱动的 spi模拟方式: main. ...

  9. 模拟SPI驱动SD卡

    使用新唐的SDIO例子修改为SDH1始终驱动不了SD卡,所以使用模拟的方式驱动SD卡 头文件: #ifndef __SD_H #define __SD_H#include "NuMicro. ...

最新文章

  1. 何恺明团队最新力作:超越EfficientNet,GPU上提速5倍|CVPR 2020
  2. 【 C 】用动态数组实现堆栈
  3. 火星上的甲烷从哪里来,科学家用算法给出了答案
  4. Ubuntu下安装和配置Apache2方法简介
  5. Python学习笔记(基础知识点二)开更了~
  6. 【Maven】Eclipse中的Maven项目安装与配置
  7. HBase之重试机制
  8. Abp vnext Web应用程序开发教程 6 —— 作者:领域层
  9. mysql三张表关联查询成绩表_mysql三张表关联查询
  10. vba 添加outlook 签名_在Excel 2013中使用vba插入电子邮件签名
  11. 引用arXiv的文章标准的Latex的bib如何编辑
  12. 微信小程序 渲染层网络错误_渲染层网络层错误 微信小程序开发 - 云计算资讯 - 服务器之家...
  13. Ubuntu-安装输入法
  14. 软件测试面试题含答案
  15. Java数据类型和变量
  16. Excel在数字单元格后面怎么添加统一的内容(数字或其他内容)
  17. Perfect Office Manner for Secretary 完美文秘办公礼仪
  18. java修改图形属性_开发者选项 Disable HW overlays - 分析
  19. c语言怎么写出2次元方程,三次樣条C语言的实现.doc
  20. 阿里云ecs安装mysql数据库途中遇到的坑

热门文章

  1. Google面经,已拿到offer哦!
  2. PhP Socket+Redis 实现客户端
  3. 山东理工大学-2022级-程序设计基础I-顺序结构
  4. 介绍一个免费的虚拟显示器的解决方案
  5. pycharm终端运行manage.py没有反应
  6. previousSibling和nextSibling用法
  7. 福建省国家税务局关于增值税一般纳税人认定生效时间的通知
  8. 【学习记录】激光雷达与相机标定
  9. 浅谈偏序关系和全序关系
  10. 在LINUX系统下安装RTL8111/8168网卡驱动程序