
本帖最后由 wjandsq 于 2015-6-25 14:12 编辑 /* * spi2.c * * Created on: 2015年6月22日 * Author: WJ */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_conf.h" #define SPI_Flash_CS_Low() {GPIO_ResetBits(GPIOC, GPIO_Pin_13);} #define SPI_Flash_CS_High() {GPIO_SetBits(GPIOC, GPIO_Pin_13);} uint8_t SPI2_Rx_Buf[4096]; uint8_t SPI2_Tx_Buf[4096]; extern uint16_t Flag_DMA_Rxd_Finished; extern uint8_t SPI2_Byte_Read_Write(uint8_t SPI_Byte); /** * @brief Configures the SPI2 Peripheral. * @param None * @retval None */ void SPI2_Config(void){ GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Forces or releases High Speed APB (APB2) peripheral reset --------------*/ RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, DISABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); /* Peripheral Clock Enable -------------------------------------------------*/ /* DMA1 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, DISABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Enable GPIO clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); /* SPI GPIO Configuration --------------------------------------------------*/ /* * PB13 --> SPI1 SCK Mode: GPIO_Mode_AF_PP * PB15 --> SPI1 MOSI Write Mode: GPIO_Mode_AF_PP * PB14 --> SPI1 MISO Read Mode: GPIO_Mode_IPU * PC13 --> SPI1 CS */ GPIO_DeInit(GPIOB); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB, GPIO_Pin_15); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_DeInit(GPIOC); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_SetBits(GPIOC, GPIO_Pin_13); SPI_Cmd(SPI2, 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_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI2, &SPI_InitStructure); if(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) != RESET){ SPI_I2S_ReceiveData(SPI2); SPI_I2S_ClearFlag(SPI2, SPI_FLAG_CRCERR); } /* DMA1 Channel4 Configures for SPIS Receive */ DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI2->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI2_Rx_Buf; 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_Channel4, &DMA_InitStructure); if(DMA_GetITStatus(DMA1_IT_TC4)!= RESET){ DMA_ClearITPendingBit(DMA1_IT_TC4); } DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE); /* Enable DMA1 Channel4 SPI2_RX */ DMA_Cmd(DMA1_Channel4, DISABLE); /* DMA1 Channel5 Configures for SPI2 Send */ DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI2->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI2_Tx_Buf; 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_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_Channel5, &DMA_InitStructure); if(DMA_GetITStatus(DMA1_IT_TC5)!= RESET){ DMA_ClearITPendingBit(DMA1_IT_TC5); } DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); /* Enable DMA1 Channel5 SPI1_TX */ DMA_Cmd(DMA1_Channel5, DISABLE); /* Enable the DMA1_Channel4、DMA1_Channel5 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn; NVIC_Init(&NVIC_InitStructure); /* Enable SPI2 */ SPI_Cmd(SPI2, ENABLE); } /** * @brief SPI1_DMA_Start * @param len <= 4096 * @retval None */ void SPI2_DMA_Read_Write(uint16_t len) { SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE); DMA1_Channel4->CMAR = (uint32_t)SPI2_Rx_Buf; DMA1_Channel5->CMAR = (uint32_t)SPI2_Tx_Buf; DMA1_Channel4->CNDTR = len; DMA1_Channel5->CNDTR = len; DMA_Cmd(DMA1_Channel4, ENABLE); DMA_Cmd(DMA1_Channel5, ENABLE); SPI_Cmd(SPI2, ENABLE); } /** * @brief SPI2_Set_Speed * @param SPI2 CR1 bit 9 8 7 * SPI_BaudRatePrescaler_2 ---> 000 * SPI_BaudRatePrescaler_4 ---> 001 * SPI_BaudRatePrescaler_8 ---> 010 * SPI_BaudRatePrescaler_16 ---> 011 * SPI_BaudRatePrescaler_32 ---> 100 * SPI_BaudRatePrescaler_64 ---> 101 * SPI_BaudRatePrescaler_128 ---> 110 * SPI_BaudRatePrescaler_256 ---> 111 * @retval None */ void SPI2_Set_Speed(uint8_t BaudRatePrescaler) { SPI2->CR1 &= 0xFFC7; /* Clear BaudRatePrescaler Value (bit 9 8 7) */ SPI2->CR1 |= BaudRatePrescaler; SPI_Cmd(SPI2,ENABLE); } /** * @brief SPI1_Byte_Read_Write * @param None * @retval None */ uint8_t SPI2_Byte_Read_Write(uint8_t SPI_Byte) { // 发送一字节 while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET); SPI2->DR = SPI_Byte; // 接收一字节 while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET); return(SPI2->DR); } /* * Function Name : DMA1_Channel4_IRQHandler * Description : None * Input : None * Output : None * Return : None */ void DMA1_Channel4_IRQHandler(void) { if (DMA_GetITStatus(DMA1_IT_TC4)) { SPI_Flash_CS_High(); DMA_Cmd(DMA1_Channel4, DISABLE); DMA_ClearITPendingBit(DMA1_IT_TC4); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE); Flag_DMA_Rxd_Finished = 1; } } /* * Function Name : DMA1_Channel5_IRQHandler * Description : None * Input : None * Output : None * Return : None */ void DMA1_Channel5_IRQHandler(void) { if (DMA_GetITStatus(DMA1_IT_TC5)) { DMA_Cmd(DMA1_Channel5, DISABLE); DMA_ClearITPendingBit(DMA1_IT_TC5); } } |
命令字节发送和接收, 可以使用SPI2_Byte_Read_Write, 也可以使用SPI2_DMA_Read_Write,
这里使用SPI2读写SPI_Flash, SPI2_DMA_Read_Write 可以按照下面的方法使用:
SP2_Tx_Buf_load(); // 数据装入发送缓冲
SPI2_Flash_CS_Low(); // 片选使能
SPI2_DMA_Read_Write(6); // 启动发送和接收, 在DMA传输完毕中断里片选关闭
while(Flag_DMA_Rxd_Finished==0) {
// 使用DMA连续收发时, 可以利用这个空闲做一些事情
// 如果是用SPI2_Byte_Read_Write, 单字节收发就没有多少空闲时间了
;
}
Flag_DMA_Rxd_Finished = 0; // DMA收发完毕,标志清0
研究,研究