spi.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include "spi.h"
  2. uint8_t spi1_rec_buf[SPI1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
  3. uint8_t spi1_tx_buf[SPI1_TX_LEN]; // 发送缓冲区
  4. uint8_t spi1_rec_cnt;
  5. uint8_t spi1_rec_flag = 0; // spi1接收标志位
  6. void SPI1DMA_Enable(DMA_Stream_TypeDef *DMA_Streamx, uint16_t count)
  7. {
  8. DMA_Cmd(DMA_Streamx, DISABLE); //关闭DMA传输
  9. while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE)
  10. {
  11. } //确保DMA可以被设置
  12. DMA_SetCurrDataCounter(DMA_Streamx, count); //数据传输量
  13. DMA_Cmd(DMA_Streamx, ENABLE); //开启DMA传输
  14. }
  15. void spi1_config(void)
  16. {
  17. /* 硬件SPI */
  18. SPI_InitTypeDef SPI_InitStructure;
  19. /* 配置SPI硬件参数*/
  20. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // 2线全双工
  21. SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主机模式
  22. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 8位
  23. SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // 时钟上升沿采样数据
  24. SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // 时钟的第2个边沿采样数据
  25. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // 片选控制方式 软件控制
  26. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // 设置波特率预分频系数 实测SCK周期800ns 12.5MHz
  27. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 数据位传输次序 高位先传
  28. SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC多项式寄存器 本例不用
  29. SPI_Init(SPI1, &SPI_InitStructure);
  30. SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
  31. SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
  32. }
  33. void spi1_dma_config(void)
  34. {
  35. DMA_InitTypeDef DMA_InitStructure;
  36. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA2时钟使能
  37. DMA_DeInit(SPI1_DMA_TXCH);
  38. while (DMA_GetCmdStatus(SPI1_DMA_TXCH) != DISABLE)
  39. ; //等待DMA可配置
  40. /* 配置 DMA Stream */
  41. DMA_InitStructure.DMA_Channel = SPI1_DMA; //通道选择
  42. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR; // DMA外设地址
  43. DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)spi1_tx_buf; // DMA 存储器0地址
  44. DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //存储器到外设模式
  45. DMA_InitStructure.DMA_BufferSize = SPI1_TX_LEN; //数据传输量
  46. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式
  47. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式
  48. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
  49. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位
  50. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 使用普通模式
  51. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级6
  52. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  53. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  54. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
  55. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
  56. DMA_Init(SPI1_DMA_TXCH, &DMA_InitStructure); //初始化DMA Stream
  57. DMA_DeInit(SPI1_DMA_RXCH);
  58. while (DMA_GetCmdStatus(SPI1_DMA_RXCH) != DISABLE)
  59. ; //等待DMA可配置
  60. /* 配置 DMA Stream */
  61. DMA_InitStructure.DMA_Channel = SPI1_DMA; //通道选择
  62. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR; // DMA外设地址
  63. DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)spi1_rec_buf; // DMA 存储器0地址
  64. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到存储器模式
  65. DMA_InitStructure.DMA_BufferSize = SPI1_REC_LEN; //数据传输量
  66. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式
  67. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式
  68. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
  69. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位
  70. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 使用循环模式
  71. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级
  72. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  73. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  74. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
  75. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
  76. DMA_Init(SPI1_DMA_RXCH, &DMA_InitStructure); //初始化DMA Stream
  77. }
  78. void spi1_init(void)
  79. {
  80. spi1_config();
  81. spi1_dma_config();
  82. SPI_Cmd(SPI1, ENABLE); // 使能SPI
  83. SPI_I2S_ClearITPendingBit(SPI1, SPI_I2S_IT_RXNE);
  84. }
  85. void SPI1DMA_Trans(const uint8_t *data, uint16_t count)
  86. {
  87. DMA_Cmd(SPI1_DMA_RXCH, DISABLE);
  88. DMA_Cmd(SPI1_DMA_TXCH, DISABLE);
  89. DMA_SetCurrDataCounter(SPI1_DMA_RXCH, count);
  90. DMA_SetCurrDataCounter(SPI1_DMA_TXCH, count);
  91. SPI1->DR;
  92. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
  93. ;
  94. DMA_Cmd(SPI1_DMA_RXCH, ENABLE);
  95. DMA_Cmd(SPI1_DMA_TXCH, ENABLE);
  96. while (DMA_GetFlagStatus(SPI1_DMA_RXCH, DMA_FLAG_TCIF2) != RESET)
  97. ;
  98. while (DMA_GetFlagStatus(SPI1_DMA_TXCH, DMA_FLAG_TCIF3) != RESET)
  99. ;
  100. DMA_Cmd(SPI1_DMA_RXCH, DISABLE);
  101. DMA_Cmd(SPI1_DMA_TXCH, DISABLE);
  102. DMA_ClearFlag(SPI1_DMA_RXCH, DMA_FLAG_TCIF2);
  103. DMA_ClearFlag(SPI1_DMA_TXCH, DMA_FLAG_TCIF3);
  104. }