|
|
@@ -0,0 +1,492 @@
|
|
|
+#include "SPI_DMA.h"
|
|
|
+
|
|
|
+u8 RxCounterSpi1;
|
|
|
+u8 TxCounterSpi1;
|
|
|
+u8 RxCounterSpi2;
|
|
|
+u8 TxCounterSpi2;
|
|
|
+
|
|
|
+u8 SPI1_TX_Buff[BufferSize] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
|
|
+ 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
|
|
|
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
|
|
+ 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20
|
|
|
+ };
|
|
|
+u8 SPI1_RX_Buff[BufferSize+4];
|
|
|
+u8 SPI2_TX_Buff[BufferSize] = {0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
|
|
+ 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60,
|
|
|
+ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
|
|
|
+ 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70
|
|
|
+ };
|
|
|
+u8 SPI2_RX_Buff[BufferSize+4];
|
|
|
+
|
|
|
+bool SPI1_data_come = false;
|
|
|
+bool SPI2_data_come = false;
|
|
|
+
|
|
|
+/******************************SPI1 配置************************************/
|
|
|
+void SPI1_GPIO_Configuration ( void )
|
|
|
+{
|
|
|
+#if SPI1_DMA_SD_def
|
|
|
+ GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
+ SPI_InitTypeDef SPI_InitStructure;
|
|
|
+
|
|
|
+ //启动GPIO/AFIO
|
|
|
+ SPI1_RCC_GPIO_CONFIG();
|
|
|
+ //启动SPI1
|
|
|
+ SPI1_RCC_CONFIG();
|
|
|
+
|
|
|
+ /* Configure SPI1 pins: SCK, MISO and MOSI */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = SPI1_PIN_AF_CONFIG;
|
|
|
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
|
+ GPIO_Init ( SPI1_PORT_CONFIG, &GPIO_InitStructure );
|
|
|
+ /* Configure I/O for EEPROM Chip select */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = SPI1_PIN_CS_CONFIG;
|
|
|
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
|
|
+ GPIO_Init ( SPI1_PORT_CONFIG, &GPIO_InitStructure );
|
|
|
+ SPI_EEPROM_CS_HIGH();
|
|
|
+
|
|
|
+ /* SPI1 configuration */
|
|
|
+ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI1设置为两线全双工
|
|
|
+ SPI_InitStructure.SPI_Mode = SPI1_Mode_CONFIG; //设置SPI1为主模式
|
|
|
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI发送接收8位帧结构
|
|
|
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行时钟在不操作时,时钟为1电平
|
|
|
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第2个时钟沿开始采样数据
|
|
|
+ SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件(使用SSI位)管理
|
|
|
+ SPI_InitStructure.SPI_BaudRatePrescaler = SPI1_Baud_CONFIG; //定义波特率预分频的值:波特率预分频值为8
|
|
|
+ SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
|
|
|
+ SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
|
|
|
+ SPI_Init(SPI1_CONFIG, &SPI_InitStructure);
|
|
|
+
|
|
|
+ /* SPI CRC */
|
|
|
+ SPI_CalculateCRC(SPI1_CONFIG, ENABLE);
|
|
|
+
|
|
|
+ //SPI中断
|
|
|
+ //SPI_I2S_ITConfig ( SPI1_CONFIG, SPI_I2S_IT_RXNE, ENABLE );
|
|
|
+ //SPI_I2S_ITConfig(SPI1_CONFIG, SPI_I2S_IT_IDLE,ENABLE);
|
|
|
+
|
|
|
+ /* Enable SPI1 */
|
|
|
+ SPI_Cmd(SPI1_CONFIG, ENABLE);
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void SPI1_NVIC_Configuration ( void )
|
|
|
+{
|
|
|
+#if SPI1_DMA_SD_def
|
|
|
+ NVIC_InitTypeDef NVIC_InitStructure;
|
|
|
+
|
|
|
+ /* 1 bit for pre-emption priority, 3 bits for subpriority */
|
|
|
+ NVIC_PriorityGroupConfig ( SPI1_NVIC_Group );
|
|
|
+
|
|
|
+ /* Configure and enable SPI1 interrupt -------------------------------------*/
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannel = SPI1_NVIC_Interrupt;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SPI1_NVIC_Pre;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = SPI1_NVIC_Sub;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
+ NVIC_Init ( &NVIC_InitStructure );
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+* Function Name : SPI1_DMA_Configuration
|
|
|
+* Description : 配置SPI1_RX的DMA通道2,SPI1_TX的DMA通道3
|
|
|
+* Input : None
|
|
|
+* Output : None
|
|
|
+* Return : None
|
|
|
+* Attention :
|
|
|
+*******************************************************************************/
|
|
|
+void DMA1_SPI1_Configuration ( void )
|
|
|
+{
|
|
|
+#if SPI1_DMA_SD_def
|
|
|
+ DMA_InitTypeDef DMA_InitStructure;
|
|
|
+
|
|
|
+ //启动DMA时钟
|
|
|
+ RCC_AHBPeriphClockCmd ( DMA_SPI1_RCC_CONFIG, ENABLE );
|
|
|
+
|
|
|
+ /* DMA1 Channel2 (triggered by SPI1 Rx event) Config */
|
|
|
+ DMA_DeInit ( DMA_SPI1_Rx_CHANNLE_CONFIG );
|
|
|
+ DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI1_DR_Addr; //设置 SPI1 发送外设(0x4001300C) 地址(目的地址)
|
|
|
+ DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI1_Rx_ADDR_CONFIG; //设置 SRAM 存储地址(目的地址)
|
|
|
+ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传输方向 外设-内存
|
|
|
+ DMA_InitStructure.DMA_BufferSize = BufferSize+1; //设置 SPI1 发送长度
|
|
|
+ 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_Circular;//DMA_Mode_Normal
|
|
|
+ DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
|
|
+ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
|
|
+ DMA_Init ( DMA_SPI1_Rx_CHANNLE_CONFIG, &DMA_InitStructure );
|
|
|
+
|
|
|
+ /* DMA1 Channel3 (triggered by SPI1 Tx event) Config */
|
|
|
+ DMA_DeInit ( DMA_SPI1_Tx_CHANNLE_CONFIG );
|
|
|
+ DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI1_DR_Addr; //设置 接收外设(0x4001300C) 地址(源地址)
|
|
|
+ DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI1_Tx_ADDR_CONFIG; //设置 SRAM 存储地址(源地址)
|
|
|
+ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //传输方向 内存-外设
|
|
|
+ DMA_InitStructure.DMA_BufferSize = BufferSize; //设置 SPI1 接收长度
|
|
|
+ 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_Low;
|
|
|
+ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
|
|
+ DMA_Init ( DMA_SPI1_Tx_CHANNLE_CONFIG, &DMA_InitStructure );
|
|
|
+
|
|
|
+ /* 中断标志*/
|
|
|
+ DMA_ITConfig(DMA_SPI1_Rx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
|
|
|
+ DMA_ITConfig(DMA_SPI1_Rx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);
|
|
|
+ DMA_ITConfig(DMA_SPI1_Tx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
|
|
|
+ DMA_ITConfig(DMA_SPI1_Tx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);
|
|
|
+
|
|
|
+ /* Enable SPI1 DMA Tx/Rx request */
|
|
|
+ SPI_I2S_DMACmd(SPI1_CONFIG, SPI_I2S_DMAReq_Tx, ENABLE);
|
|
|
+ SPI_I2S_DMACmd(SPI1_CONFIG, SPI_I2S_DMAReq_Rx, ENABLE);
|
|
|
+
|
|
|
+ /* Enable channe2 and channel3 */
|
|
|
+ DMA_Cmd(DMA_SPI1_Rx_CHANNLE_CONFIG, ENABLE); //开接收
|
|
|
+ DMA_Cmd(DMA_SPI1_Tx_CHANNLE_CONFIG, DISABLE); //关发送
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+void DMA1_SPI1_NVIC_Configuration ( void )
|
|
|
+{
|
|
|
+#if SPI1_DMA_SD_def
|
|
|
+ NVIC_InitTypeDef NVIC_InitStructure;
|
|
|
+
|
|
|
+ /* 1 bit for pre-emption priority, 3 bits for subpriority */
|
|
|
+ NVIC_PriorityGroupConfig ( DMA_SPI1_NVIC_Group );
|
|
|
+
|
|
|
+ /* Configure and enable DMA1 interrupt -------------------------------------*/
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI1_NVIC_Rx_Interrupt;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI1_NVIC_Rx_Pre;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI1_NVIC_Rx_Sub;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
+ NVIC_Init ( &NVIC_InitStructure );
|
|
|
+
|
|
|
+ /* Configure and enable DMA1 interrupt -------------------------------------*/
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI1_NVIC_Tx_Interrupt;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI1_NVIC_Tx_Pre;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI1_NVIC_Tx_Sub;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
+ NVIC_Init ( &NVIC_InitStructure );
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+//SPIx 读写一个字节
|
|
|
+//返回值:读取到的字节
|
|
|
+u8 SPIx_ReadWriteByte(u8 byte)
|
|
|
+{
|
|
|
+ /* Loop while DR register in not emplty */
|
|
|
+ while(SPI_I2S_GetFlagStatus(SPI1_CONFIG, SPI_I2S_FLAG_TXE) == RESET);
|
|
|
+
|
|
|
+ /* Send byte through the SPI2 peripheral */
|
|
|
+ SPI_I2S_SendData(SPI1_CONFIG, byte);
|
|
|
+
|
|
|
+ /* Wait to receive a byte */
|
|
|
+ while(SPI_I2S_GetFlagStatus(SPI1_CONFIG, SPI_I2S_FLAG_RXNE) == RESET);
|
|
|
+
|
|
|
+ /* Return the byte read from the SPI bus */
|
|
|
+ return SPI_I2S_ReceiveData(SPI1_CONFIG);
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+* Function Name : SPI1_Send
|
|
|
+* Description : SPI1的DMA方式发送
|
|
|
+* Input : SPI1_TX_Buff[SPI1_SendBufferSize]
|
|
|
+* Output : None
|
|
|
+* Return : None
|
|
|
+* Attention : 关闭DMA通道3之前必须等待TXE为1,等待忙标志为0
|
|
|
+*******************************************************************************/
|
|
|
+void SPI1_Send ( u8 *buff, u32 len )
|
|
|
+{
|
|
|
+ DMA_SPI1_Tx_CHANNLE_CONFIG->CPAR = DMA_SPI1_DR_Addr; //外设地址
|
|
|
+ DMA_SPI1_Tx_CHANNLE_CONFIG->CMAR = ( u32 ) buff; //mem地址
|
|
|
+ DMA_SPI1_Tx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
|
|
|
+ DMA_SPI1_Tx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
|
|
|
+ ( 2 << 12 ) | // 通道优先级高
|
|
|
+ ( 0 << 11 ) | // 存储器数据宽度8bit
|
|
|
+ ( 0 << 10 ) | // 存储器数据宽度8bit
|
|
|
+ ( 0 << 9 ) | // 外设数据宽度8bit
|
|
|
+ ( 0 << 8 ) | // 外设数据宽度8bit
|
|
|
+ ( 1 << 7 ) | // 存储器地址增量模式
|
|
|
+ ( 0 << 6 ) | // 外设地址增量模式(不增)
|
|
|
+ ( 0 << 5 ) | // 非循环模式
|
|
|
+ ( 1 << 4 ) | // 从存储器读
|
|
|
+ ( 1 << 3 ) | // 允许传输错误中断
|
|
|
+ ( 0 << 2 ) | // 允许半传输中断
|
|
|
+ ( 1 << 1 ) | // 允许传输完成中断
|
|
|
+ ( 1 ); // 通道开启
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+* Function Name : SPI1_Recive
|
|
|
+* Description : SPI1的DMA方式接收
|
|
|
+* Input : None
|
|
|
+* Output : SPI1_RX_Buff[SPI1_ReciveBufferSize]
|
|
|
+* Return : None
|
|
|
+* Attention : 必须要先关闭通道2,然后再配置通道2的参数
|
|
|
+*******************************************************************************/
|
|
|
+void SPI1_Recive ( u8 *buff, u32 len )
|
|
|
+{
|
|
|
+ DMA_SPI1_Rx_CHANNLE_CONFIG->CCR &= ~ ( 1 << 0 ); //关闭DMA通道2
|
|
|
+
|
|
|
+ DMA_SPI1_Rx_CHANNLE_CONFIG->CPAR = DMA_SPI1_DR_Addr; //外设地址
|
|
|
+ DMA_SPI1_Rx_CHANNLE_CONFIG->CMAR = ( uint32_t ) buff; //mem地址
|
|
|
+ DMA_SPI1_Rx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
|
|
|
+ DMA_SPI1_Rx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
|
|
|
+ ( 2 << 12 ) | // 通道优先级高
|
|
|
+ ( 0 << 11 ) | // 存储器数据宽度8bit
|
|
|
+ ( 0 << 10 ) | // 存储器数据宽度8bit
|
|
|
+ ( 0 << 9 ) | // 外设数据宽度8bit
|
|
|
+ ( 0 << 8 ) | // 外设数据宽度8bit
|
|
|
+ ( 1 << 7 ) | // 存储器地址增量模式
|
|
|
+ ( 0 << 6 ) | // 外设地址增量模式(不增)
|
|
|
+ ( 0 << 5 ) | // 非循环模式
|
|
|
+ ( 0 << 4 ) | // 传输方向 外设-内存
|
|
|
+ ( 0 << 3 ) | // 允许传输错误中断
|
|
|
+ ( 0 << 2 ) | // 允许半传输中断
|
|
|
+ ( 1 << 1 ) | // 允许传输完成中断
|
|
|
+ ( 1 ); // 通道开启
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************SPI2 配置************************************/
|
|
|
+void SPI2_GPIO_Configuration ( void )
|
|
|
+{
|
|
|
+#if SPI2_DMA_SD_def
|
|
|
+ GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
+ SPI_InitTypeDef SPI_InitStructure;
|
|
|
+
|
|
|
+ //启动GPIO/AFIO
|
|
|
+ SPI2_RCC_GPIO_CONFIG();
|
|
|
+ //启动SPI2
|
|
|
+ SPI2_RCC_CONFIG();
|
|
|
+
|
|
|
+ /* Configure SPI1 pins: SCK, MISO and MOSI */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = SPI2_PIN_AF_CONFIG;
|
|
|
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
|
+ GPIO_Init ( SPI2_PORT_CONFIG, &GPIO_InitStructure );
|
|
|
+#if 1 //副的接收cs
|
|
|
+ /* Configure I/O for EEPROM Chip select */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = SPI2_PIN_CS_CONFIG;
|
|
|
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
|
|
+ GPIO_Init ( SPI2_PORT_CONFIG, &GPIO_InitStructure );
|
|
|
+ //SPI_EEPROM_CS_HIGH();
|
|
|
+#endif
|
|
|
+
|
|
|
+ /* SPI2 configuration */
|
|
|
+ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI1设置为两线全双工
|
|
|
+ SPI_InitStructure.SPI_Mode = SPI2_Mode_CONFIG; //设置SPI1为主模式
|
|
|
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI发送接收8位帧结构
|
|
|
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行时钟在不操作时,时钟为1电平
|
|
|
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第2个时钟沿开始采样数据
|
|
|
+ SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件(使用SSI位)管理
|
|
|
+ SPI_InitStructure.SPI_BaudRatePrescaler = SPI2_Baud_CONFIG; //定义波特率预分频的值:波特率预分频值为8
|
|
|
+ SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
|
|
|
+ SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
|
|
|
+ SPI_Init(SPI2_CONFIG, &SPI_InitStructure);
|
|
|
+
|
|
|
+ /* SPI CRC */
|
|
|
+ SPI_CalculateCRC(SPI2_CONFIG, ENABLE);
|
|
|
+
|
|
|
+ //SPI中断
|
|
|
+ //SPI_I2S_ITConfig ( SPI2_CONFIG, SPI_I2S_IT_RXNE, ENABLE );
|
|
|
+// SPI_I2S_ITConfig(SPI1_CONFIG, SPI_I2S_IT_IDLE,ENABLE);
|
|
|
+
|
|
|
+ /* Enable SPI1 */
|
|
|
+ SPI_Cmd(SPI2_CONFIG, ENABLE);
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void SPI2_NVIC_Configuration ( void )
|
|
|
+{
|
|
|
+#if SPI1_DMA_SD_def
|
|
|
+ NVIC_InitTypeDef NVIC_InitStructure;
|
|
|
+
|
|
|
+ /* 1 bit for pre-emption priority, 3 bits for subpriority */
|
|
|
+ NVIC_PriorityGroupConfig ( SPI2_NVIC_Group );
|
|
|
+
|
|
|
+ /* Configure and enable SPI1 interrupt -------------------------------------*/
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannel = SPI2_NVIC_Interrupt;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SPI2_NVIC_Pre;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = SPI2_NVIC_Sub;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
+ NVIC_Init ( &NVIC_InitStructure );
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+* Function Name : SPI1_DMA_Configuration
|
|
|
+* Description : 配置SPI1_RX的DMA通道2,SPI1_TX的DMA通道3
|
|
|
+* Input : None
|
|
|
+* Output : None
|
|
|
+* Return : None
|
|
|
+* Attention :
|
|
|
+*******************************************************************************/
|
|
|
+void DMA1_SPI2_Configuration ( void )
|
|
|
+{
|
|
|
+#if SPI2_DMA_SD_def
|
|
|
+ DMA_InitTypeDef DMA_InitStructure;
|
|
|
+
|
|
|
+ //启动DMA时钟
|
|
|
+ RCC_AHBPeriphClockCmd ( DMA_SPI2_RCC_CONFIG, ENABLE );
|
|
|
+
|
|
|
+ /* DMA1 Channel2 (triggered by SPI1 Rx event) Config */
|
|
|
+ DMA_DeInit ( DMA_SPI2_Rx_CHANNLE_CONFIG );
|
|
|
+ DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI2_DR_Addr; //设置 SPI1 发送外设(0x4001300C) 地址(目的地址)
|
|
|
+ DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI2_Rx_ADDR_CONFIG; //设置 SRAM 存储地址(目的地址)
|
|
|
+ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传输方向 外设-内存
|
|
|
+ DMA_InitStructure.DMA_BufferSize = BufferSize+1; //设置 SPI1 发送长度
|
|
|
+ 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_Circular;//DMA_Mode_Normal
|
|
|
+ DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
|
|
+ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
|
|
+ DMA_Init ( DMA_SPI2_Rx_CHANNLE_CONFIG, &DMA_InitStructure );
|
|
|
+
|
|
|
+ /* DMA1 Channel3 (triggered by SPI1 Tx event) Config */
|
|
|
+ DMA_DeInit ( DMA_SPI2_Tx_CHANNLE_CONFIG );
|
|
|
+ DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI2_DR_Addr; //设置 接收外设(0x4001300C) 地址(源地址)
|
|
|
+ DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI2_Tx_ADDR_CONFIG; //设置 SRAM 存储地址(源地址)
|
|
|
+ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //传输方向 内存-外设
|
|
|
+ DMA_InitStructure.DMA_BufferSize = BufferSize; //设置 SPI1 接收长度
|
|
|
+ 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_Low;
|
|
|
+ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
|
|
+ DMA_Init ( DMA_SPI2_Tx_CHANNLE_CONFIG, &DMA_InitStructure );
|
|
|
+
|
|
|
+ /* 中断标志*/
|
|
|
+ DMA_ITConfig(DMA_SPI2_Rx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
|
|
|
+ DMA_ITConfig(DMA_SPI2_Rx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);
|
|
|
+ DMA_ITConfig(DMA_SPI2_Tx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
|
|
|
+ DMA_ITConfig(DMA_SPI2_Tx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);
|
|
|
+
|
|
|
+ /* Enable SPI1 DMA Tx/Rx request */
|
|
|
+ SPI_I2S_DMACmd(SPI2_CONFIG, SPI_I2S_DMAReq_Tx, ENABLE);
|
|
|
+ SPI_I2S_DMACmd(SPI2_CONFIG, SPI_I2S_DMAReq_Rx, ENABLE);
|
|
|
+
|
|
|
+ /* Enable channe2 and channel3 */
|
|
|
+ DMA_Cmd(DMA_SPI2_Rx_CHANNLE_CONFIG, ENABLE); //开接收
|
|
|
+ DMA_Cmd(DMA_SPI2_Tx_CHANNLE_CONFIG, DISABLE); //关发送
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+void DMA1_SPI2_NVIC_Configuration ( void )
|
|
|
+{
|
|
|
+#if SPI2_DMA_SD_def
|
|
|
+ NVIC_InitTypeDef NVIC_InitStructure;
|
|
|
+
|
|
|
+ /* 1 bit for pre-emption priority, 3 bits for subpriority */
|
|
|
+ NVIC_PriorityGroupConfig ( DMA_SPI2_NVIC_Group );
|
|
|
+
|
|
|
+ /* Configure and enable DMA1 interrupt -------------------------------------*/
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI2_NVIC_Rx_Interrupt;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI2_NVIC_Rx_Pre;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI2_NVIC_Rx_Sub;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
+ NVIC_Init ( &NVIC_InitStructure );
|
|
|
+
|
|
|
+ /* Configure and enable DMA1 interrupt -------------------------------------*/
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI2_NVIC_Tx_Interrupt;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI1_NVIC_Tx_Pre;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI2_NVIC_Tx_Sub;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
+ NVIC_Init ( &NVIC_InitStructure );
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+//SPIx 读写一个字节
|
|
|
+//返回值:读取到的字节
|
|
|
+u8 SPI2_ReadWriteByte(u8 byte)
|
|
|
+{
|
|
|
+ /* Loop while DR register in not emplty */
|
|
|
+ while(SPI_I2S_GetFlagStatus(SPI2_CONFIG, SPI_I2S_FLAG_TXE) == RESET);
|
|
|
+
|
|
|
+ /* Send byte through the SPI2 peripheral */
|
|
|
+ SPI_I2S_SendData(SPI2_CONFIG, byte);
|
|
|
+
|
|
|
+ /* Wait to receive a byte */
|
|
|
+ while(SPI_I2S_GetFlagStatus(SPI2_CONFIG, SPI_I2S_FLAG_RXNE) == RESET);
|
|
|
+
|
|
|
+ /* Return the byte read from the SPI bus */
|
|
|
+ return SPI_I2S_ReceiveData(SPI2_CONFIG);
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+* Function Name : SPI1_Send
|
|
|
+* Description : SPI1的DMA方式发送
|
|
|
+* Input : SPI1_TX_Buff[SPI1_SendBufferSize]
|
|
|
+* Output : None
|
|
|
+* Return : None
|
|
|
+* Attention : 关闭DMA通道3之前必须等待TXE为1,等待忙标志为0
|
|
|
+*******************************************************************************/
|
|
|
+void SPI2_Send ( u8 *buff, u32 len )
|
|
|
+{
|
|
|
+ DMA_SPI2_Tx_CHANNLE_CONFIG->CPAR = DMA_SPI2_DR_Addr; //外设地址
|
|
|
+ DMA_SPI2_Tx_CHANNLE_CONFIG->CMAR = ( u32 ) buff; //mem地址
|
|
|
+ DMA_SPI2_Tx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
|
|
|
+ DMA_SPI2_Tx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
|
|
|
+ ( 2 << 12 ) | // 通道优先级高
|
|
|
+ ( 0 << 11 ) | // 存储器数据宽度8bit
|
|
|
+ ( 0 << 10 ) | // 存储器数据宽度8bit
|
|
|
+ ( 0 << 9 ) | // 外设数据宽度8bit
|
|
|
+ ( 0 << 8 ) | // 外设数据宽度8bit
|
|
|
+ ( 1 << 7 ) | // 存储器地址增量模式
|
|
|
+ ( 0 << 6 ) | // 外设地址增量模式(不增)
|
|
|
+ ( 0 << 5 ) | // 非循环模式
|
|
|
+ ( 1 << 4 ) | // 从存储器读
|
|
|
+ ( 1 << 3 ) | // 允许传输错误中断
|
|
|
+ ( 0 << 2 ) | // 允许半传输中断
|
|
|
+ ( 1 << 1 ) | // 允许传输完成中断
|
|
|
+ ( 1 ); // 通道开启
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+* Function Name : SPI1_Recive
|
|
|
+* Description : SPI1的DMA方式接收
|
|
|
+* Input : None
|
|
|
+* Output : SPI1_RX_Buff[SPI1_ReciveBufferSize]
|
|
|
+* Return : None
|
|
|
+* Attention : 必须要先关闭通道2,然后再配置通道2的参数
|
|
|
+*******************************************************************************/
|
|
|
+void SPI2_Recive ( u8 *buff, u32 len )
|
|
|
+{
|
|
|
+ DMA_SPI2_Rx_CHANNLE_CONFIG->CCR &= ~ ( 1 << 0 ); //关闭DMA通道2
|
|
|
+
|
|
|
+ DMA_SPI2_Rx_CHANNLE_CONFIG->CPAR = DMA_SPI2_DR_Addr; //外设地址
|
|
|
+ DMA_SPI2_Rx_CHANNLE_CONFIG->CMAR = ( uint32_t ) buff; //mem地址
|
|
|
+ DMA_SPI2_Rx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
|
|
|
+ DMA_SPI2_Rx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
|
|
|
+ ( 2 << 12 ) | // 通道优先级高
|
|
|
+ ( 0 << 11 ) | // 存储器数据宽度8bit
|
|
|
+ ( 0 << 10 ) | // 存储器数据宽度8bit
|
|
|
+ ( 0 << 9 ) | // 外设数据宽度8bit
|
|
|
+ ( 0 << 8 ) | // 外设数据宽度8bit
|
|
|
+ ( 1 << 7 ) | // 存储器地址增量模式
|
|
|
+ ( 0 << 6 ) | // 外设地址增量模式(不增)
|
|
|
+ ( 0 << 5 ) | // 非循环模式
|
|
|
+ ( 0 << 4 ) | // 传输方向 外设-内存
|
|
|
+ ( 0 << 3 ) | // 允许传输错误中断
|
|
|
+ ( 0 << 2 ) | // 允许半传输中断
|
|
|
+ ( 1 << 1 ) | // 允许传输完成中断
|
|
|
+ ( 1 ); // 通道开启
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|