您的位置:首页 > 其它

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)

#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  STM32 SPI DMA