SPI_DMA.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. #include "SPI_DMA.h"
  2. u8 RxCounterSpi1;
  3. u8 TxCounterSpi1;
  4. u8 RxCounterSpi2;
  5. u8 TxCounterSpi2;
  6. u8 SPI1_TX_Buff[BufferSize] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  7. 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
  8. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  9. 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20
  10. };
  11. u8 SPI1_RX_Buff[BufferSize+4];
  12. u8 SPI2_TX_Buff[BufferSize] = {0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
  13. 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60,
  14. 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
  15. 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70
  16. };
  17. u8 SPI2_RX_Buff[BufferSize+4];
  18. bool SPI1_data_come = false;
  19. bool SPI2_data_come = false;
  20. /******************************SPI1 配置************************************/
  21. void SPI1_GPIO_Configuration ( void )
  22. {
  23. #if SPI1_DMA_SD_def
  24. GPIO_InitTypeDef GPIO_InitStructure;
  25. SPI_InitTypeDef SPI_InitStructure;
  26. //启动GPIO/AFIO
  27. SPI1_RCC_GPIO_CONFIG();
  28. //启动SPI1
  29. SPI1_RCC_CONFIG();
  30. /* Configure SPI1 pins: SCK, MISO and MOSI */
  31. GPIO_InitStructure.GPIO_Pin = SPI1_PIN_AF_CONFIG;
  32. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  33. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  34. GPIO_Init ( SPI1_PORT_CONFIG, &GPIO_InitStructure );
  35. /* Configure I/O for EEPROM Chip select */
  36. GPIO_InitStructure.GPIO_Pin = SPI1_PIN_CS_CONFIG;
  37. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  38. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  39. GPIO_Init ( SPI1_PORT_CONFIG, &GPIO_InitStructure );
  40. SPI_EEPROM_CS_HIGH();
  41. /* SPI1 configuration */
  42. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI1设置为两线全双工
  43. SPI_InitStructure.SPI_Mode = SPI1_Mode_CONFIG; //设置SPI1为主模式
  44. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI发送接收8位帧结构
  45. SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行时钟在不操作时,时钟为1电平
  46. SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第2个时钟沿开始采样数据
  47. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件(使用SSI位)管理
  48. SPI_InitStructure.SPI_BaudRatePrescaler = SPI1_Baud_CONFIG; //定义波特率预分频的值:波特率预分频值为8
  49. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
  50. SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
  51. SPI_Init(SPI1_CONFIG, &SPI_InitStructure);
  52. /* SPI CRC */
  53. SPI_CalculateCRC(SPI1_CONFIG, ENABLE);
  54. //SPI中断
  55. //SPI_I2S_ITConfig ( SPI1_CONFIG, SPI_I2S_IT_RXNE, ENABLE );
  56. //SPI_I2S_ITConfig(SPI1_CONFIG, SPI_I2S_IT_IDLE,ENABLE);
  57. /* Enable SPI1 */
  58. SPI_Cmd(SPI1_CONFIG, ENABLE);
  59. #endif
  60. }
  61. void SPI1_NVIC_Configuration ( void )
  62. {
  63. #if SPI1_DMA_SD_def
  64. NVIC_InitTypeDef NVIC_InitStructure;
  65. /* 1 bit for pre-emption priority, 3 bits for subpriority */
  66. NVIC_PriorityGroupConfig ( SPI1_NVIC_Group );
  67. /* Configure and enable SPI1 interrupt -------------------------------------*/
  68. NVIC_InitStructure.NVIC_IRQChannel = SPI1_NVIC_Interrupt;
  69. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SPI1_NVIC_Pre;
  70. NVIC_InitStructure.NVIC_IRQChannelSubPriority = SPI1_NVIC_Sub;
  71. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  72. NVIC_Init ( &NVIC_InitStructure );
  73. #endif
  74. }
  75. /*******************************************************************************
  76. * Function Name : SPI1_DMA_Configuration
  77. * Description : 配置SPI1_RX的DMA通道2,SPI1_TX的DMA通道3
  78. * Input : None
  79. * Output : None
  80. * Return : None
  81. * Attention :
  82. *******************************************************************************/
  83. void DMA1_SPI1_Configuration ( void )
  84. {
  85. #if SPI1_DMA_SD_def
  86. DMA_InitTypeDef DMA_InitStructure;
  87. //启动DMA时钟
  88. RCC_AHBPeriphClockCmd ( DMA_SPI1_RCC_CONFIG, ENABLE );
  89. /* DMA1 Channel2 (triggered by SPI1 Rx event) Config */
  90. DMA_DeInit ( DMA_SPI1_Rx_CHANNLE_CONFIG );
  91. DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI1_DR_Addr; //设置 SPI1 发送外设(0x4001300C) 地址(目的地址)
  92. DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI1_Rx_ADDR_CONFIG; //设置 SRAM 存储地址(目的地址)
  93. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传输方向 外设-内存
  94. DMA_InitStructure.DMA_BufferSize = BufferSize+1; //设置 SPI1 发送长度
  95. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  96. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  97. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  98. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  99. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA_Mode_Normal
  100. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  101. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  102. DMA_Init ( DMA_SPI1_Rx_CHANNLE_CONFIG, &DMA_InitStructure );
  103. /* DMA1 Channel3 (triggered by SPI1 Tx event) Config */
  104. DMA_DeInit ( DMA_SPI1_Tx_CHANNLE_CONFIG );
  105. DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI1_DR_Addr; //设置 接收外设(0x4001300C) 地址(源地址)
  106. DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI1_Tx_ADDR_CONFIG; //设置 SRAM 存储地址(源地址)
  107. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //传输方向 内存-外设
  108. DMA_InitStructure.DMA_BufferSize = BufferSize; //设置 SPI1 接收长度
  109. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  110. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  111. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  112. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  113. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  114. DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
  115. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  116. DMA_Init ( DMA_SPI1_Tx_CHANNLE_CONFIG, &DMA_InitStructure );
  117. /* 中断标志*/
  118. DMA_ITConfig(DMA_SPI1_Rx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
  119. DMA_ITConfig(DMA_SPI1_Rx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);
  120. DMA_ITConfig(DMA_SPI1_Tx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
  121. DMA_ITConfig(DMA_SPI1_Tx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);
  122. /* Enable SPI1 DMA Tx/Rx request */
  123. SPI_I2S_DMACmd(SPI1_CONFIG, SPI_I2S_DMAReq_Tx, ENABLE);
  124. SPI_I2S_DMACmd(SPI1_CONFIG, SPI_I2S_DMAReq_Rx, ENABLE);
  125. /* Enable channe2 and channel3 */
  126. DMA_Cmd(DMA_SPI1_Rx_CHANNLE_CONFIG, ENABLE); //开接收
  127. DMA_Cmd(DMA_SPI1_Tx_CHANNLE_CONFIG, DISABLE); //关发送
  128. #endif
  129. }
  130. void DMA1_SPI1_NVIC_Configuration ( void )
  131. {
  132. #if SPI1_DMA_SD_def
  133. NVIC_InitTypeDef NVIC_InitStructure;
  134. /* 1 bit for pre-emption priority, 3 bits for subpriority */
  135. NVIC_PriorityGroupConfig ( DMA_SPI1_NVIC_Group );
  136. /* Configure and enable DMA1 interrupt -------------------------------------*/
  137. NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI1_NVIC_Rx_Interrupt;
  138. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI1_NVIC_Rx_Pre;
  139. NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI1_NVIC_Rx_Sub;
  140. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  141. NVIC_Init ( &NVIC_InitStructure );
  142. /* Configure and enable DMA1 interrupt -------------------------------------*/
  143. NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI1_NVIC_Tx_Interrupt;
  144. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI1_NVIC_Tx_Pre;
  145. NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI1_NVIC_Tx_Sub;
  146. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  147. NVIC_Init ( &NVIC_InitStructure );
  148. #endif
  149. }
  150. //SPIx 读写一个字节
  151. //返回值:读取到的字节
  152. u8 SPIx_ReadWriteByte(u8 byte)
  153. {
  154. /* Loop while DR register in not emplty */
  155. while(SPI_I2S_GetFlagStatus(SPI1_CONFIG, SPI_I2S_FLAG_TXE) == RESET);
  156. /* Send byte through the SPI2 peripheral */
  157. SPI_I2S_SendData(SPI1_CONFIG, byte);
  158. /* Wait to receive a byte */
  159. while(SPI_I2S_GetFlagStatus(SPI1_CONFIG, SPI_I2S_FLAG_RXNE) == RESET);
  160. /* Return the byte read from the SPI bus */
  161. return SPI_I2S_ReceiveData(SPI1_CONFIG);
  162. }
  163. /*******************************************************************************
  164. * Function Name : SPI1_Send
  165. * Description : SPI1的DMA方式发送
  166. * Input : SPI1_TX_Buff[SPI1_SendBufferSize]
  167. * Output : None
  168. * Return : None
  169. * Attention : 关闭DMA通道3之前必须等待TXE为1,等待忙标志为0
  170. *******************************************************************************/
  171. void SPI1_Send ( u8 *buff, u32 len )
  172. {
  173. DMA_SPI1_Tx_CHANNLE_CONFIG->CPAR = DMA_SPI1_DR_Addr; //外设地址
  174. DMA_SPI1_Tx_CHANNLE_CONFIG->CMAR = ( u32 ) buff; //mem地址
  175. DMA_SPI1_Tx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
  176. DMA_SPI1_Tx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
  177. ( 2 << 12 ) | // 通道优先级高
  178. ( 0 << 11 ) | // 存储器数据宽度8bit
  179. ( 0 << 10 ) | // 存储器数据宽度8bit
  180. ( 0 << 9 ) | // 外设数据宽度8bit
  181. ( 0 << 8 ) | // 外设数据宽度8bit
  182. ( 1 << 7 ) | // 存储器地址增量模式
  183. ( 0 << 6 ) | // 外设地址增量模式(不增)
  184. ( 0 << 5 ) | // 非循环模式
  185. ( 1 << 4 ) | // 从存储器读
  186. ( 1 << 3 ) | // 允许传输错误中断
  187. ( 0 << 2 ) | // 允许半传输中断
  188. ( 1 << 1 ) | // 允许传输完成中断
  189. ( 1 ); // 通道开启
  190. }
  191. /*******************************************************************************
  192. * Function Name : SPI1_Recive
  193. * Description : SPI1的DMA方式接收
  194. * Input : None
  195. * Output : SPI1_RX_Buff[SPI1_ReciveBufferSize]
  196. * Return : None
  197. * Attention : 必须要先关闭通道2,然后再配置通道2的参数
  198. *******************************************************************************/
  199. void SPI1_Recive ( u8 *buff, u32 len )
  200. {
  201. DMA_SPI1_Rx_CHANNLE_CONFIG->CCR &= ~ ( 1 << 0 ); //关闭DMA通道2
  202. DMA_SPI1_Rx_CHANNLE_CONFIG->CPAR = DMA_SPI1_DR_Addr; //外设地址
  203. DMA_SPI1_Rx_CHANNLE_CONFIG->CMAR = ( uint32_t ) buff; //mem地址
  204. DMA_SPI1_Rx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
  205. DMA_SPI1_Rx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
  206. ( 2 << 12 ) | // 通道优先级高
  207. ( 0 << 11 ) | // 存储器数据宽度8bit
  208. ( 0 << 10 ) | // 存储器数据宽度8bit
  209. ( 0 << 9 ) | // 外设数据宽度8bit
  210. ( 0 << 8 ) | // 外设数据宽度8bit
  211. ( 1 << 7 ) | // 存储器地址增量模式
  212. ( 0 << 6 ) | // 外设地址增量模式(不增)
  213. ( 0 << 5 ) | // 非循环模式
  214. ( 0 << 4 ) | // 传输方向 外设-内存
  215. ( 0 << 3 ) | // 允许传输错误中断
  216. ( 0 << 2 ) | // 允许半传输中断
  217. ( 1 << 1 ) | // 允许传输完成中断
  218. ( 1 ); // 通道开启
  219. }
  220. /******************************SPI2 配置************************************/
  221. void SPI2_GPIO_Configuration ( void )
  222. {
  223. #if SPI2_DMA_SD_def
  224. GPIO_InitTypeDef GPIO_InitStructure;
  225. SPI_InitTypeDef SPI_InitStructure;
  226. //启动GPIO/AFIO
  227. SPI2_RCC_GPIO_CONFIG();
  228. //启动SPI2
  229. SPI2_RCC_CONFIG();
  230. /* Configure SPI1 pins: SCK, MISO and MOSI */
  231. GPIO_InitStructure.GPIO_Pin = SPI2_PIN_AF_CONFIG;
  232. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  233. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  234. GPIO_Init ( SPI2_PORT_CONFIG, &GPIO_InitStructure );
  235. #if 1 //副的接收cs
  236. /* Configure I/O for EEPROM Chip select */
  237. GPIO_InitStructure.GPIO_Pin = SPI2_PIN_CS_CONFIG;
  238. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  239. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  240. GPIO_Init ( SPI2_PORT_CONFIG, &GPIO_InitStructure );
  241. //SPI_EEPROM_CS_HIGH();
  242. #endif
  243. /* SPI2 configuration */
  244. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI1设置为两线全双工
  245. SPI_InitStructure.SPI_Mode = SPI2_Mode_CONFIG; //设置SPI1为主模式
  246. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI发送接收8位帧结构
  247. SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行时钟在不操作时,时钟为1电平
  248. SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第2个时钟沿开始采样数据
  249. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件(使用SSI位)管理
  250. SPI_InitStructure.SPI_BaudRatePrescaler = SPI2_Baud_CONFIG; //定义波特率预分频的值:波特率预分频值为8
  251. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
  252. SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
  253. SPI_Init(SPI2_CONFIG, &SPI_InitStructure);
  254. /* SPI CRC */
  255. SPI_CalculateCRC(SPI2_CONFIG, ENABLE);
  256. //SPI中断
  257. //SPI_I2S_ITConfig ( SPI2_CONFIG, SPI_I2S_IT_RXNE, ENABLE );
  258. // SPI_I2S_ITConfig(SPI1_CONFIG, SPI_I2S_IT_IDLE,ENABLE);
  259. /* Enable SPI1 */
  260. SPI_Cmd(SPI2_CONFIG, ENABLE);
  261. #endif
  262. }
  263. void SPI2_NVIC_Configuration ( void )
  264. {
  265. #if SPI1_DMA_SD_def
  266. NVIC_InitTypeDef NVIC_InitStructure;
  267. /* 1 bit for pre-emption priority, 3 bits for subpriority */
  268. NVIC_PriorityGroupConfig ( SPI2_NVIC_Group );
  269. /* Configure and enable SPI1 interrupt -------------------------------------*/
  270. NVIC_InitStructure.NVIC_IRQChannel = SPI2_NVIC_Interrupt;
  271. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SPI2_NVIC_Pre;
  272. NVIC_InitStructure.NVIC_IRQChannelSubPriority = SPI2_NVIC_Sub;
  273. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  274. NVIC_Init ( &NVIC_InitStructure );
  275. #endif
  276. }
  277. /*******************************************************************************
  278. * Function Name : SPI1_DMA_Configuration
  279. * Description : 配置SPI1_RX的DMA通道2,SPI1_TX的DMA通道3
  280. * Input : None
  281. * Output : None
  282. * Return : None
  283. * Attention :
  284. *******************************************************************************/
  285. void DMA1_SPI2_Configuration ( void )
  286. {
  287. #if SPI2_DMA_SD_def
  288. DMA_InitTypeDef DMA_InitStructure;
  289. //启动DMA时钟
  290. RCC_AHBPeriphClockCmd ( DMA_SPI2_RCC_CONFIG, ENABLE );
  291. /* DMA1 Channel2 (triggered by SPI1 Rx event) Config */
  292. DMA_DeInit ( DMA_SPI2_Rx_CHANNLE_CONFIG );
  293. DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI2_DR_Addr; //设置 SPI1 发送外设(0x4001300C) 地址(目的地址)
  294. DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI2_Rx_ADDR_CONFIG; //设置 SRAM 存储地址(目的地址)
  295. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传输方向 外设-内存
  296. DMA_InitStructure.DMA_BufferSize = BufferSize+1; //设置 SPI1 发送长度
  297. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  298. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  299. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  300. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  301. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA_Mode_Normal
  302. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  303. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  304. DMA_Init ( DMA_SPI2_Rx_CHANNLE_CONFIG, &DMA_InitStructure );
  305. /* DMA1 Channel3 (triggered by SPI1 Tx event) Config */
  306. DMA_DeInit ( DMA_SPI2_Tx_CHANNLE_CONFIG );
  307. DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI2_DR_Addr; //设置 接收外设(0x4001300C) 地址(源地址)
  308. DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI2_Tx_ADDR_CONFIG; //设置 SRAM 存储地址(源地址)
  309. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //传输方向 内存-外设
  310. DMA_InitStructure.DMA_BufferSize = BufferSize; //设置 SPI1 接收长度
  311. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  312. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  313. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  314. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  315. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  316. DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
  317. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  318. DMA_Init ( DMA_SPI2_Tx_CHANNLE_CONFIG, &DMA_InitStructure );
  319. /* 中断标志*/
  320. DMA_ITConfig(DMA_SPI2_Rx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
  321. DMA_ITConfig(DMA_SPI2_Rx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);
  322. DMA_ITConfig(DMA_SPI2_Tx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
  323. DMA_ITConfig(DMA_SPI2_Tx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);
  324. /* Enable SPI1 DMA Tx/Rx request */
  325. SPI_I2S_DMACmd(SPI2_CONFIG, SPI_I2S_DMAReq_Tx, ENABLE);
  326. SPI_I2S_DMACmd(SPI2_CONFIG, SPI_I2S_DMAReq_Rx, ENABLE);
  327. /* Enable channe2 and channel3 */
  328. DMA_Cmd(DMA_SPI2_Rx_CHANNLE_CONFIG, ENABLE); //开接收
  329. DMA_Cmd(DMA_SPI2_Tx_CHANNLE_CONFIG, DISABLE); //关发送
  330. #endif
  331. }
  332. void DMA1_SPI2_NVIC_Configuration ( void )
  333. {
  334. #if SPI2_DMA_SD_def
  335. NVIC_InitTypeDef NVIC_InitStructure;
  336. /* 1 bit for pre-emption priority, 3 bits for subpriority */
  337. NVIC_PriorityGroupConfig ( DMA_SPI2_NVIC_Group );
  338. /* Configure and enable DMA1 interrupt -------------------------------------*/
  339. NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI2_NVIC_Rx_Interrupt;
  340. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI2_NVIC_Rx_Pre;
  341. NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI2_NVIC_Rx_Sub;
  342. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  343. NVIC_Init ( &NVIC_InitStructure );
  344. /* Configure and enable DMA1 interrupt -------------------------------------*/
  345. NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI2_NVIC_Tx_Interrupt;
  346. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI1_NVIC_Tx_Pre;
  347. NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI2_NVIC_Tx_Sub;
  348. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  349. NVIC_Init ( &NVIC_InitStructure );
  350. #endif
  351. }
  352. //SPIx 读写一个字节
  353. //返回值:读取到的字节
  354. u8 SPI2_ReadWriteByte(u8 byte)
  355. {
  356. /* Loop while DR register in not emplty */
  357. while(SPI_I2S_GetFlagStatus(SPI2_CONFIG, SPI_I2S_FLAG_TXE) == RESET);
  358. /* Send byte through the SPI2 peripheral */
  359. SPI_I2S_SendData(SPI2_CONFIG, byte);
  360. /* Wait to receive a byte */
  361. while(SPI_I2S_GetFlagStatus(SPI2_CONFIG, SPI_I2S_FLAG_RXNE) == RESET);
  362. /* Return the byte read from the SPI bus */
  363. return SPI_I2S_ReceiveData(SPI2_CONFIG);
  364. }
  365. /*******************************************************************************
  366. * Function Name : SPI1_Send
  367. * Description : SPI1的DMA方式发送
  368. * Input : SPI1_TX_Buff[SPI1_SendBufferSize]
  369. * Output : None
  370. * Return : None
  371. * Attention : 关闭DMA通道3之前必须等待TXE为1,等待忙标志为0
  372. *******************************************************************************/
  373. void SPI2_Send ( u8 *buff, u32 len )
  374. {
  375. DMA_SPI2_Tx_CHANNLE_CONFIG->CPAR = DMA_SPI2_DR_Addr; //外设地址
  376. DMA_SPI2_Tx_CHANNLE_CONFIG->CMAR = ( u32 ) buff; //mem地址
  377. DMA_SPI2_Tx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
  378. DMA_SPI2_Tx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
  379. ( 2 << 12 ) | // 通道优先级高
  380. ( 0 << 11 ) | // 存储器数据宽度8bit
  381. ( 0 << 10 ) | // 存储器数据宽度8bit
  382. ( 0 << 9 ) | // 外设数据宽度8bit
  383. ( 0 << 8 ) | // 外设数据宽度8bit
  384. ( 1 << 7 ) | // 存储器地址增量模式
  385. ( 0 << 6 ) | // 外设地址增量模式(不增)
  386. ( 0 << 5 ) | // 非循环模式
  387. ( 1 << 4 ) | // 从存储器读
  388. ( 1 << 3 ) | // 允许传输错误中断
  389. ( 0 << 2 ) | // 允许半传输中断
  390. ( 1 << 1 ) | // 允许传输完成中断
  391. ( 1 ); // 通道开启
  392. }
  393. /*******************************************************************************
  394. * Function Name : SPI1_Recive
  395. * Description : SPI1的DMA方式接收
  396. * Input : None
  397. * Output : SPI1_RX_Buff[SPI1_ReciveBufferSize]
  398. * Return : None
  399. * Attention : 必须要先关闭通道2,然后再配置通道2的参数
  400. *******************************************************************************/
  401. void SPI2_Recive ( u8 *buff, u32 len )
  402. {
  403. DMA_SPI2_Rx_CHANNLE_CONFIG->CCR &= ~ ( 1 << 0 ); //关闭DMA通道2
  404. DMA_SPI2_Rx_CHANNLE_CONFIG->CPAR = DMA_SPI2_DR_Addr; //外设地址
  405. DMA_SPI2_Rx_CHANNLE_CONFIG->CMAR = ( uint32_t ) buff; //mem地址
  406. DMA_SPI2_Rx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
  407. DMA_SPI2_Rx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
  408. ( 2 << 12 ) | // 通道优先级高
  409. ( 0 << 11 ) | // 存储器数据宽度8bit
  410. ( 0 << 10 ) | // 存储器数据宽度8bit
  411. ( 0 << 9 ) | // 外设数据宽度8bit
  412. ( 0 << 8 ) | // 外设数据宽度8bit
  413. ( 1 << 7 ) | // 存储器地址增量模式
  414. ( 0 << 6 ) | // 外设地址增量模式(不增)
  415. ( 0 << 5 ) | // 非循环模式
  416. ( 0 << 4 ) | // 传输方向 外设-内存
  417. ( 0 << 3 ) | // 允许传输错误中断
  418. ( 0 << 2 ) | // 允许半传输中断
  419. ( 1 << 1 ) | // 允许传输完成中断
  420. ( 1 ); // 通道开启
  421. }