123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- #include "spi.h"
- u8 spi1_rec_buf[SPI1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
- u8 spi1_tx_buf[SPI1_TX_LEN]; // 发送缓冲区
- u8 spi1_rec_cnt;
- u8 spi1_rec_flag = 0; // spi1接收标志位
- void SPI1DMA_Enable(DMA_Stream_TypeDef *DMA_Streamx, u16 count)
- {
- DMA_Cmd(DMA_Streamx, DISABLE); //关闭DMA传输
- while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE)
- {
- } //确保DMA可以被设置
- DMA_SetCurrDataCounter(DMA_Streamx, count); //数据传输量
- DMA_Cmd(DMA_Streamx, ENABLE); //开启DMA传输
- }
- void spi1_config(void)
- {
- /* 硬件SPI */
- SPI_InitTypeDef SPI_InitStructure;
- /* 配置SPI硬件参数*/
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // 2线全双工
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主机模式
- SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 8位
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // 时钟上升沿采样数据
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // 时钟的第2个边沿采样数据
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // 片选控制方式 软件控制
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // 设置波特率预分频系数 实测SCK周期800ns 12.5MHz
- SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 数据位传输次序 高位先传
- SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC多项式寄存器 本例不用
- SPI_Init(SPI1, &SPI_InitStructure);
- SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
- SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
- }
- void spi1_dma_config(void)
- {
- DMA_InitTypeDef DMA_InitStructure;
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA2时钟使能
- DMA_DeInit(SPI1_DMA_TXCH);
- while (DMA_GetCmdStatus(SPI1_DMA_TXCH) != DISABLE)
- ; //等待DMA可配置
- /* 配置 DMA Stream */
- DMA_InitStructure.DMA_Channel = SPI1_DMA; //通道选择
- DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR; // DMA外设地址
- DMA_InitStructure.DMA_Memory0BaseAddr = (u32)spi1_tx_buf; // DMA 存储器0地址
- DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //存储器到外设模式
- DMA_InitStructure.DMA_BufferSize = SPI1_TX_LEN; //数据传输量
- 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; //中等优先级6
- DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
- DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
- DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
- DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
- DMA_Init(SPI1_DMA_TXCH, &DMA_InitStructure); //初始化DMA Stream
- DMA_DeInit(SPI1_DMA_RXCH);
- while (DMA_GetCmdStatus(SPI1_DMA_RXCH) != DISABLE)
- ; //等待DMA可配置
- /* 配置 DMA Stream */
- DMA_InitStructure.DMA_Channel = SPI1_DMA; //通道选择
- DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR; // DMA外设地址
- DMA_InitStructure.DMA_Memory0BaseAddr = (u32)spi1_rec_buf; // DMA 存储器0地址
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到存储器模式
- DMA_InitStructure.DMA_BufferSize = SPI1_REC_LEN; //数据传输量
- 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_Circular; // 使用循环模式
- DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级
- DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
- DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
- DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
- DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
- DMA_Init(SPI1_DMA_RXCH, &DMA_InitStructure); //初始化DMA Stream
- }
- void spi1_init(void)
- {
- spi1_config();
- spi1_dma_config();
- SPI_Cmd(SPI1, ENABLE); // 使能SPI
- SPI_I2S_ClearITPendingBit(SPI1, SPI_I2S_IT_RXNE);
- }
- void SPI1DMA_Trans(const u8 *data, u16 count)
- {
- DMA_Cmd(SPI1_DMA_RXCH, DISABLE);
- DMA_Cmd(SPI1_DMA_TXCH, DISABLE);
- DMA_SetCurrDataCounter(SPI1_DMA_RXCH, count);
- DMA_SetCurrDataCounter(SPI1_DMA_TXCH, count);
- SPI1->DR;
- while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
- ;
- DMA_Cmd(SPI1_DMA_RXCH, ENABLE);
- DMA_Cmd(SPI1_DMA_TXCH, ENABLE);
- while (DMA_GetFlagStatus(SPI1_DMA_RXCH, DMA_FLAG_TCIF2) != RESET)
- ;
- while (DMA_GetFlagStatus(SPI1_DMA_TXCH, DMA_FLAG_TCIF3) != RESET)
- ;
- DMA_Cmd(SPI1_DMA_RXCH, DISABLE);
- DMA_Cmd(SPI1_DMA_TXCH, DISABLE);
- DMA_ClearFlag(SPI1_DMA_RXCH, DMA_FLAG_TCIF2);
- DMA_ClearFlag(SPI1_DMA_TXCH, DMA_FLAG_TCIF3);
- }
|