STM32 SPI工作在主模式时用DMA方式接收数据
2015-06-27 00:00
2141 查看
摘要: STM32 SPI工作在主模式时用DMA方式接收数据,方便从SPI FLASH中取出数据
平台:STM32F103
功能:SPI工作在主模式时用DMA方式接收数据,在需要从SPI FLASH中读出大量数据时,可以在读数据的同时释放CPU的占用,提高系统利用效率
DMA不可以自动帮忙发送时钟信号,但是如果让spi发送数据并且使用DMA方式,spi可以帮忙自动发送时钟信号。基于这样的理论, 直接上代码(参考:http://blog.sina.com.cn/s/blog_9d8d362b0101cukb.html)
平台:STM32F103
功能:SPI工作在主模式时用DMA方式接收数据,在需要从SPI FLASH中读出大量数据时,可以在读数据的同时释放CPU的占用,提高系统利用效率
DMA不可以自动帮忙发送时钟信号,但是如果让spi发送数据并且使用DMA方式,spi可以帮忙自动发送时钟信号。基于这样的理论, 直接上代码(参考:http://blog.sina.com.cn/s/blog_9d8d362b0101cukb.html)
#if (ON == SPI_DMA_ON) //DMA1的各通道配置 //这里的传输形式是固定的,这点要根据不同的情况来修改 //从存储器->外设模式/8位数据宽度/存储器增量模式 //DMA_CHx:DMA通道CHx //cpar:外设地址 //cmar:存储器地址 void SPI_DMA_Config(u32 MBAr) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输 //接收DMA配置 DMA_Cmd(SPI_RX_DMA_CH, DISABLE); //DMA关闭后才能配置 DMA_DeInit(SPI_RX_DMA_CH); //将DMA的通道1寄存器重设为缺省值 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&SPI_FLASH_NUM->DR);//DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = MBAr; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,外设->内存 DMA_InitStructure.DMA_BufferSize = 0; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; &nb 3ff8 sp; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 SPI_I2S_ReceiveData(SPI_FLASH_NUM); //空读一次数据 /*传输完成中断使能*/ DMA_ITConfig(SPI_RX_DMA_CH, DMA_IT_TC, ENABLE); DMA_Init(SPI_RX_DMA_CH, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器 //发送DMA配置 DMA_Cmd(SPI_TX_DMA_CH, DISABLE); //DMA关闭后才能配置 DMA_DeInit(SPI_TX_DMA_CH); //将DMA的通道1寄存器重设为缺省值 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设 DMA_InitStructure.DMA_BufferSize = 0; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //内存地址寄存器不用递增,因为只是为了发送时钟 DMA_Init(SPI_TX_DMA_CH, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器 } //开启一次DMA传输 void SPI_DMA_Enable(u16 len) { DMA_Cmd(SPI_RX_DMA_CH, DISABLE ); //关闭 指示的通道 DMA_SetCurrDataCounter(SPI_RX_DMA_CH,len); //DMA通道的DMA缓存的大小 DMA_Cmd(SPI_RX_DMA_CH, ENABLE); DMA_Cmd(SPI_TX_DMA_CH, DISABLE ); //关闭 指示的通道 DMA_SetCurrDataCounter(SPI_TX_DMA_CH,len); //DMA通道的DMA缓存的大小 DMA_Cmd(SPI_TX_DMA_CH, ENABLE); //开启DMA传输 } void SPI_FLASH_Data_Read_By_DMA(uint8_t *s,const uint32_t Add,const uint16_t Date_Length) { uint32_t Add_24; uint32_t n; uint8_t Shift_Bit,Temp; //重新配置DMA通道 while(DMA_GetCurrDataCounter(SPI_RX_DMA_CH)!=0); //等待上一次通道传输完成 SPI_DMA_Config((u32)s); ErrorFlashStatus = ERROR_OK; //开始一次新的读操作,错误状态复位 /*SPI_FLASH_NUM的片选有效*/ SPI_FLASH_Enable; /*地址有效位数为24,屏蔽高12位*/ Add_24 = Add & 0x00FFFFFF; /*发送读数据指令*/ SPI_FLASH_Byte_Send(READ); /*24位地址要分三次发送*/ for(n=3;n>0;n--) { Shift_Bit = (n-1)*8; Temp = (uint8_t)(0xFF & (Add_24 >> Shift_Bit)); SPI_FLASH_Byte_Send(Temp); } /*开始读数据*/ SPI_DMA_Enable(Date_Length); /*结束读操作,SPI_FLASH_NUM片选无效,放在DAM中断中完成*/ } /* * 函数名:void DMA1_Channel1_IRQHandler(void) * 描述 :DMA1中断服务函数 * 输入 :无 * 输出 :无 */ void DMA1_Channel2_IRQHandler(void) { /*结束读操作,SPI_FLASH_NUM片选无效*/ SPI_FLASH_Disable; /* 清除 DMA1 Channel2 transfer complete 中断标志 */ DMA_ClearITPendingBit(DMA1_IT_TC2); DMA_Cmd(SPI_RX_DMA_CH, DISABLE ); } #endif
相关文章推荐
- 基于Linux内核SPI子系统工作机制
- eMMC的MMC模式与SPI模式
- 打开DMA传输方式
- DMA timeout error
- SPI总线协议
- Keil STM32工程环境搭建
- SPI总线规范
- stm32之RTC
- STM32串口操作相关事项
- [嵌入式裸机课程]Cortex-M3开发实训班
- stm32的1602操作显示
- STM32 UART DMA实现未知数据长度接收(转自amoBBs)
- STM32F429 LTDC学习笔记1
- stm32f4 DAC DMA 频率发生器+FreeRTOS
- java spi
- stm32学习笔记---入门环境搭建及开发板的选用
- stm32中断服务函数的机制
- pc寄存器与可寻址空间
- 关于STM32 库函数3.5版的各种坑
- 上船容易——从阿里云迁移SQL数据库到Azure云的尝试 之二