模拟SPI驱动W25Q16程序 (DSP 28X系列)
为了驱动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系列)相关推荐
- 【全志T113-S3_100ask】15-2 linux系统gpio模拟spi驱动屏幕——ILI9341
[全志T113-S3_100ask]15-2 linux系统gpio模拟spi驱动屏幕--ILI9341 背景 (一)查阅参考文档 (二)使能内核模块 (三)修改设备树 (四)测试 (五)后语 背景 ...
- 鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920_基于code-2.0-CANARY
鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920源码.rar-C文档类资源-CSDN下载鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920源码.rar博文链接:htt ...
- 外设驱动库开发笔记43:GPIO模拟SPI驱动
SPI总线是我们常用的串行设备接口,一般情况下我们都会适应硬件SPI接口,但有些时候当硬件端口不足时,我们也希望可以使用软件来模拟SPI硬件接口,特别是要求不是很高的时候.在这一篇中我们将来讨论如 ...
- MSP430杂谈--AD7793硬件SPI驱动与模拟SPI驱动
最近项目中用到了AD7793读取铂电阻值来得到相应的温度,编写了基于MSP430的硬件驱动程序和模拟驱动程序,并且能成功运行,现在记录一下分享给大家. AD7793硬件IIC驱动完整版下载链接:htt ...
- 鸿蒙开发板Hi3861模拟SPI驱动JLX12864_LCD(UC1701X)_基于code-2.0
鸿蒙开发板驱动晶联讯LCDjlx12864_lcd_hi3861源码-C文档类资源-CSDN下载鸿蒙开发板驱动晶联讯LCDjlx12864_lcd_hi3861源码博文介绍https://t更多下载资 ...
- MAX535 单路13位DAC 模拟SPI驱动
一.MAX535 max535是低功耗.13位.电压输出DAC,采用串行接口和µMAX封装.MAX535通过单个+5V/3.3V电源工作,仅需要280µA电流工作. MAX535/MAX5351适用于 ...
- TLV5618 双路12位DAC 模拟SPI驱动
一.TLV65618芯片 TLV5618A 带掉电功能 2.7V-5.5V,低功耗双路 12 位数模转换器 特点 ●双路 12 位电压输出 DAC ●可编程调节转换时间 - 快速模式 3μs - 低速 ...
- STM8S1003 模拟SPI 驱动 SI4432
网上关于stm8s1003 驱动si4432的 驱动不是很多 ,我也是弄了大半天才可以和si4432 spi驱动成功. 接下来要做无线收发和组网. 暂时先贴 spi驱动的 spi模拟方式: main. ...
- 模拟SPI驱动SD卡
使用新唐的SDIO例子修改为SDH1始终驱动不了SD卡,所以使用模拟的方式驱动SD卡 头文件: #ifndef __SD_H #define __SD_H#include "NuMicro. ...
最新文章
- 何恺明团队最新力作:超越EfficientNet,GPU上提速5倍|CVPR 2020
- 【 C 】用动态数组实现堆栈
- 火星上的甲烷从哪里来,科学家用算法给出了答案
- Ubuntu下安装和配置Apache2方法简介
- Python学习笔记(基础知识点二)开更了~
- 【Maven】Eclipse中的Maven项目安装与配置
- HBase之重试机制
- Abp vnext Web应用程序开发教程 6 —— 作者:领域层
- mysql三张表关联查询成绩表_mysql三张表关联查询
- vba 添加outlook 签名_在Excel 2013中使用vba插入电子邮件签名
- 引用arXiv的文章标准的Latex的bib如何编辑
- 微信小程序 渲染层网络错误_渲染层网络层错误 微信小程序开发 - 云计算资讯 - 服务器之家...
- Ubuntu-安装输入法
- 软件测试面试题含答案
- Java数据类型和变量
- Excel在数字单元格后面怎么添加统一的内容(数字或其他内容)
- Perfect Office Manner for Secretary 完美文秘办公礼仪
- java修改图形属性_开发者选项 Disable HW overlays - 分析
- c语言怎么写出2次元方程,三次樣条C语言的实现.doc
- 阿里云ecs安装mysql数据库途中遇到的坑