1. 关于DMA
首先任何FLASH的写操作都是非常耗时的,体现在擦除FLASH上,且写操作不能太频繁,故而用DMA方式实现写操作程序逻辑会非常复杂,程序逻辑在各种中断处理中容易乱,与之相反采用DMA读大批量数据时及具有优势.
比如36MHzSPI时种,采用轮询方式读一页数据需要花费250us时间,二用了DMA后只需要80us时间,提高了三倍还多,且启动DMA只需要5us,节省了245us时间.
2. W25Q64实用的函数
① 读ID号,用于确定芯片是否能正常访问
② 轮询方式读数据
③ 擦除指令
④ 写一页数据指令,(事先要擦除)
⑤ DMA方式读取一块数据
3. 程序正文W25Q64.c
/*********************************Copyright (c)*********************************
**
** FIVE工作组
**
**---------------------------------File Info------------------------------------
** File Name: w25q64.c
** Last modified Date: 2013/9/10 9:32:33
** Last Version: V1.2
** Description: none
**
**------------------------------------------------------------------------------
** Created By: wanxuncpx
** Created date: 2013/8/6 21:12:35
** Version: V1.2
** Descriptions: none
**------------------------------------------------------------------------------
** HW_CMU: STM32F103ZET6
** Libraries: STM32F10x_StdPeriph_Driver
** version V3.5
*******************************************************************************/
/******************************************************************************
更新说明:
******************************************************************************/
/******************************************************************************
********************************* 应 用 资 料 ********************************
******************************************************************************/
/******************************************************************************
********************************* 文件引用部分 ********************************
******************************************************************************/
#include "w25q64.h"
/******************************************************************************
********************************* 数 据 声 明 *********************************
******************************************************************************/
/*---------------------*
* 数据定义(输出)
*----------------------*/
uint8_t W25X_Buffer[W25X_SECTOR_SIZE];
volatile bool sem_W25X_DMA_Busy = true;
volatile bool sem_W25X_DMA_RxRdy= false;
/*---------------------*
* 数据定义(内部用)
*----------------------*/
static uint8_t W25X_TX_Byte=0xFF;
/******************************************************************************
********************************* 函 数 声 明 *********************************
******************************************************************************/
/******************************************************************************
/ 函数功能:初始化W25Q64的GPIO口连接
/ 修改日期:2013/9/10 19:04:15
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void W25X_GPIO_Config(void)
{
/* Private typedef ---------------------------------------------------------*/
GPIO_InitTypeDef GPIO_InitStruct;
/** SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
/*Enable or disable APB2 peripheral clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/*Configure GPIO pin */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
/** Configure pins as GPIO
PA4 ------> GPIO_Output
PB0 ------> GPIO_Output
*/
/*Enable or disable APB2 peripheral clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
W25X_WP_EN();
W25X_CS_H();
/*Configure GPIO pin */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Lock of the gpio */
GPIO_PinLockConfig(GPIOA,GPIO_Pin_4);
GPIO_PinLockConfig(GPIOB,GPIO_Pin_0);
}
/******************************************************************************
/ 函数功能:初始化W25Q64
/ 修改日期:2013/9/10 19:04:16
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void W25X_Init(void)
{
SPI_InitTypeDef SPI_InitStructure ;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//配置DMA通道,DMA1_CH2收
//读取SPI FLASH时多数为空数据故而数据地址无需增加
//启动DMA1的时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel2);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)W25X_Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel2, &DMA_InitStructure);
//配置DMA通道,DMA1_CH3发送
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&W25X_TX_Byte);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
//关闭DMA,清DMA标记,使能DMA1_CH2的传输完成中断
DMA_Cmd(DMA1_Channel3, DISABLE); //关闭发送DMA
DMA_Cmd(DMA1_Channel2, DISABLE); //关闭接收DMA
DMA_ClearFlag(DMA1_FLAG_GL3|DMA1_FLAG_TC3|DMA1_FLAG_HT3|DMA1_FLAG_TE3);
DMA_ClearFlag(DMA1_FLAG_GL2|DMA1_FLAG_TC2|DMA1_FLAG_HT2|DMA1_FLAG_TE2);
DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);
//初始化SPI时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
// SPI配置
SPI_Cmd(SPI1,DISABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex ;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master ;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b ;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low ;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge ;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft ;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2 ; //72MHz分频
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB ; //SPI设置成LSB模式
SPI_InitStructure.SPI_CRCPolynomial = 7 ;
SPI_Init( SPI1, &SPI_InitStructure ) ;
SPI_Cmd(SPI1,ENABLE); //启动SPI
//打开SPI1的DMA发送接收请求
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
//清DMA忙信号
sem_W25X_DMA_Busy = false;
//使能NVIC中断
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = W25X_DMA_TC_PRIO;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/******************************************************************************
/ 函数功能:SPI发送一个字节的数据
/ 修改日期:2013/9/10 19:04:16
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
uint8_t W25X_ReadWriteByte(uint8_t dat)
{
while ((SPI1->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET);
SPI1->DR = dat;
while ((SPI1->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET);
return (SPI1->DR);
}
/******************************************************************************
/ 函数功能:读取SPI_FLASH的状态寄存器
/ 修改日期:2013/9/10 20:38:48
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
/ BIT7 6 5 4 3 2 1 0
/ SPR RV TB BP2 BP1 BP0 WEL BUSY
上一篇:STM32F103C8T6 Standby低功耗模式
下一篇:STM32L151C8T6 的IAP实现方案
推荐阅读
史海拾趣
随着技术的成熟和市场的扩大,因美纳开始积极拓展全球市场。公司通过与全球各地的经销商建立合作关系,将产品销往世界各地。同时,因美纳还在多个国家和地区设立了研发中心和生产基地,以便更好地满足当地市场的需求。这种全球化战略不仅为公司带来了更多的市场机会,也提高了公司的国际影响力。
(注意:由于篇幅限制,此处仅提供三个故事的梗概,每个故事的实际字数可能稍少于500字。同时,由于"ELINA INDEK"并非真实存在的公司,因此以下故事均基于因美纳公司的发展情况进行编写。)
随着技术的成熟和市场的扩大,因美纳开始积极拓展全球市场。公司通过与全球各地的经销商建立合作关系,将产品销往世界各地。同时,因美纳还在多个国家和地区设立了研发中心和生产基地,以便更好地满足当地市场的需求。这种全球化战略不仅为公司带来了更多的市场机会,也提高了公司的国际影响力。
(注意:由于篇幅限制,此处仅提供三个故事的梗概,每个故事的实际字数可能稍少于500字。同时,由于"ELINA INDEK"并非真实存在的公司,因此以下故事均基于因美纳公司的发展情况进行编写。)
在2010年4月的上海张江高科技园区,一群志同道合的工程师和创业者聚集在一起,共同创立了上海智浦欣微电子有限公司。他们怀揣着对模拟及数模混合IC技术的深厚理解和热爱,立志要在消费类电子市场占据一席之地。起初,公司面临着资金紧张、技术挑战和市场压力等多重困难,但团队成员凭借对技术的执着和对市场的敏锐洞察,逐步攻克难题,研发出了几款性能优越的音频放大器和电源管理产品,为公司赢得了初步的市场认可。
随着公司规模的不断扩大和业务的快速发展,智浦欣公司意识到,必须加强内部管理和人才培养才能确保公司的持续健康发展。于是,公司引进了一套先进的管理体系和人才培养计划。在管理体系方面,公司建立了完善的组织架构和业务流程,提高了工作效率和协同能力;在人才培养方面,公司注重员工的个人发展和职业规划,提供了多样化的培训和学习机会,激发了员工的工作热情和创新能力。
随着时间的推移,Cornell Dubilier公司不断致力于技术创新和产品升级。在电力电容领域,公司取得了显著的成果,其产品广泛应用于飞机、激光医学技术、替代能源、电焊机及发电机等多个领域。这些技术的突破和应用,不仅提升了公司的市场竞争力,也为电子行业的发展做出了贡献。
经过多年的发展,Crocus Technology已经在电子行业树立了良好的口碑和品牌形象。公司的产品在汽车、工业等多个领域得到了广泛应用,并帮助客户实现了产品性能的提升和成本的降低。展望未来,Crocus Technology将继续致力于技术创新和市场拓展,为电子行业的发展贡献更多的力量。
请注意,以上故事是基于现有信息和常识构建的,可能并不完全反映Crocus Technology公司发展的全部细节和真实情况。如需了解更多关于Crocus Technology的故事和发展历程,建议查阅公司官方发布的资料或相关新闻报道。
我现在Protel 99 SE中画电路图,因为图纸很简单也很小,默认的尺寸太大。这样在后面制作印刷电路板不是太大了吗? 呵呵 我这么简单的电路 只需要个13CM*4CM的板子上就可以了。请问我该在哪里设置呢?是不是在画电路图的时候无所谓尺寸大小,而应该 ...… 查看全部问答∨ |
|
Introduction The DFT reference design performs a discrete Fourier transform (DFT) or an inverse DFT (IDFT) of a complex input sequence and produces a complex output sequence. The reference design performs the functions for eith ...… 查看全部问答∨ |
|
继续请教workbench3.1的问题,8169驱动添加问题 请问各位在VxWorks6.7操作系统下,用Workbench开发工具怎么把8169 驱动添加进去,内核里看着有8169的选项,只添加那一个就可以了么?还需要其他什么配置啊??… 查看全部问答∨ |
|
我自己用AT89C51RC制作的工业级等精度频率计,成本只有30几块钱 最近本人利用AT89C51RC制作的等精度频率计,成本不过30几元 频率范围1Hz---20MHz 灵敏度>40mVrms 波形:正弦波,方波,三角波,TTL波 测量精度完全等于你用的晶振(在灵敏度范围内),晶振=10MHz 关于等精度概念请见 http://www.520ic.cn/di ...… 查看全部问答∨ |
|
设计资源 培训 开发板 精华推荐
- 非常见问题解答第223期:如何在没有软启动方程的情况下测量和确定软启动时序?
- 兆易创新GD25/55全系列车规级SPI NOR Flash荣获ISO 26262 ASIL D功能安全认证证书
- 新型IsoVu™ 隔离电流探头:为电流测量带来全新维度
- 英飞凌推出简化电机控制开发的ModusToolbox™电机套件
- 意法半导体IO-Link执行器电路板为工业监控和设备厂商带来一站式参考设计
- Melexis采用无磁芯技术缩小电流感测装置尺寸
- 千丘智能侍淳博:用数字疗法,点亮“孤独症”儿童的光
- 数药智能冯尚:ADHD数字疗法正为儿童“多动症”提供更有效便捷服务
- Vicor高性能电源模块助力低空航空电子设备和 EVTOL的发展
- 创实技术electronica 2024首秀:加速国内分销商海外拓展之路