本帖最后由 wjandsq 于 2015-6-25 14:12 编辑 1 U, }; u7 b) M+ c$ Z$ p* b ) ] }# X9 ^' g1 q /*8 I' }, c4 Q2 o * spi2.c * * Created on: 2015年6月22日 * Author: WJ */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_conf.h" ! z! o6 n! L/ R #define SPI_Flash_CS_Low() {GPIO_ResetBits(GPIOC, GPIO_Pin_13);}7 G9 B" Q$ }5 ~. |% U2 }3 h #define SPI_Flash_CS_High() {GPIO_SetBits(GPIOC, GPIO_Pin_13);}8 q! s* C1 Y% u ; i, p$ b0 W/ K# j, c uint8_t SPI2_Rx_Buf[4096]; uint8_t SPI2_Tx_Buf[4096];+ _( p' E7 V |4 G" T' Q, l" d extern uint16_t Flag_DMA_Rxd_Finished;4 V' ]6 k7 M! W/ P! P3 s * \4 N- h, u% z0 [0 V8 \ extern uint8_t SPI2_Byte_Read_Write(uint8_t SPI_Byte); % g2 H+ ^* F3 m2 N /**- ~, m2 D$ L0 | * @brief Configures the SPI2 Peripheral. * @param None u) g, Y$ E5 H# {4 z- u/ @ * @retval None- y9 ]3 _! S6 g2 {5 ~5 p, v& k */3 Z z. B/ S# h% w, c$ R* R% h void SPI2_Config(void){3 q. W4 }7 o, i, O" F7 j B: S GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; 9 S' N' A2 f: M3 g /* Forces or releases High Speed APB (APB2) peripheral reset --------------*/ RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE); 4 S2 m1 \5 s- p2 E RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE);9 ]3 l: L* A$ ^4 ~/ v# Z A RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE);! f2 ^3 v$ W6 r4 m RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE);( I+ o; _6 c$ _! t+ y' b# B$ H/ { 1 {/ J+ f; {0 n RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, DISABLE);9 u) w% }6 z2 t # h( j; z2 Z6 a- f! @( B4 T3 a' O" H RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);* Y2 ?2 x( f9 s% L" d% Q! u RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);* V* U R6 z5 t /* Peripheral Clock Enable -------------------------------------------------*/! O7 t. ^! W! U! T; A0 g /* DMA1 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, DISABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);8 ]$ o' i4 O7 Y* S* z7 @: K /* Enable GPIO clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);# o5 p/ c6 U/ f+ `% \ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);% _: C, a6 ~) S7 b: d RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);/ N: M/ P5 p3 _& I & [4 V/ L2 Z. E: f0 I RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);9 G: x" @4 z) g3 A+ C RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);$ l- I# g. T2 s5 b /* SPI GPIO Configuration --------------------------------------------------*/ /* * PB13 --> SPI1 SCK Mode: GPIO_Mode_AF_PP* |! y8 G$ A5 J1 u; R* Z+ _ * PB15 --> SPI1 MOSI Write Mode: GPIO_Mode_AF_PP% S6 l, K5 E W! d5 A * PB14 --> SPI1 MISO Read Mode: GPIO_Mode_IPU2 Z) Q0 E5 |/ r$ `4 d; m * PC13 --> SPI1 CS) r; [; i$ _' w& n) P: m3 O. O1 i */ GPIO_DeInit(GPIOB);" |5 J0 d' R& |/ N0 o GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;" \% _( y' Q3 Q( R, d: t9 V- j" ^ 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);# T0 l8 n4 I2 L GPIO_SetBits(GPIOB, GPIO_Pin_14);. [7 Q' N% K6 O! _6 u' x - _5 T. }; {7 W. c; j Z2 b3 p GPIO_DeInit(GPIOC);. [, E6 p7 w" e# ~ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;/ D/ m: l1 W& l7 B1 U$ |' S GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure);# a( f" U4 Q* D0 o GPIO_SetBits(GPIOC, GPIO_Pin_13);; K" t; m2 v+ q- i: K4 ^ * O# I$ \1 K- y& c5 ^ SPI_Cmd(SPI2, DISABLE);! J$ \! T; h u# q# n SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master;" a) Z. m0 \' H; @8 s# ] SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;) i( i: G4 N; f& ? SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;! o& @; t# j O G) k2 N SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;/ u/ U' h' W) Z* g) w0 o1 z 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){/ `* B% a9 |) b SPI_I2S_ReceiveData(SPI2); SPI_I2S_ClearFlag(SPI2, SPI_FLAG_CRCERR); }' d1 g3 g$ n2 Q' ]7 p( z% J /* DMA1 Channel4 Configures for SPIS Receive */* [& ^5 `0 }3 t7 M9 Y6 O' R 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;$ C1 a; q5 B% P DMA_InitStructure.DMA_BufferSize = 0; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;& X W7 f7 v7 E% }! t$ c% {9 S- d DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;: B- |1 f+ ^. V' n/ n$ G- R5 k0 M8 A* a DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;+ n9 a0 k+ B/ l0 ^ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;! S7 _$ C$ N% L" } DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;7 s" g, T3 u; g S7 `4 c9 T9 j DMA_Init(DMA1_Channel4, &DMA_InitStructure); if(DMA_GetITStatus(DMA1_IT_TC4)!= RESET){8 ^6 l( O. Y7 _+ X4 {% V! O, g4 V' p0 X DMA_ClearITPendingBit(DMA1_IT_TC4);; Q D4 H: Q0 ]1 d$ { }5 L8 u; S. N. B( O: U DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);# {1 k! i* \+ }" A$ B SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE); /* Enable DMA1 Channel4 SPI2_RX */# g+ Y6 M& j1 `: C5 X& p DMA_Cmd(DMA1_Channel4, DISABLE); /* DMA1 Channel5 Configures for SPI2 Send */ Z) t3 Z7 { y8 B P% z DMA_DeInit(DMA1_Channel5);% n: U) z2 \" r3 f. @& Y- z/ ^( s DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI2->DR);9 k, ~5 k8 J* k$ r' D& P! t- w( ? DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI2_Tx_Buf;+ |' c# Z W3 @1 p3 R DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 0; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;; {/ O# Y' R; u' f DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;9 g2 I* @) }. s DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;9 [( I$ X* }9 z# A3 s0 E DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;& x" E" a7 i1 @8 o8 t; E DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;0 ]: I) G' M' z" a" q2 s DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;, q1 Y/ C" h/ V& ]: k* j2 n DMA_Init(DMA1_Channel5, &DMA_InitStructure); ! ~9 r8 z f9 D9 n9 n if(DMA_GetITStatus(DMA1_IT_TC5)!= RESET){ DMA_ClearITPendingBit(DMA1_IT_TC5); }9 |! ^4 Y5 k- F- {+ R1 \, \ DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);" g( t( \9 `! @" W SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);; t8 ~+ ?( g1 K* o. h9 F ) B, M* N! q; r9 F3 z /* Enable DMA1 Channel5 SPI1_TX */2 ~ h7 J" T/ @4 ?' v DMA_Cmd(DMA1_Channel5, DISABLE); # z- c5 y3 k7 Q" A" [ /* Enable the DMA1_Channel4、DMA1_Channel5 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;/ n2 I! {- M1 B9 m* e& m0 J NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;. k$ d- f# b# e( a L NVIC_Init(&NVIC_InitStructure); # E: W4 ]' V6 A: W NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;, B& \+ p- G' |$ g+ Z2 Z NVIC_Init(&NVIC_InitStructure);7 y# C( M* R, @& F 0 |1 d2 c; ?, m7 y) u& { /* Enable SPI2 */9 F l; w' `' ^4 H6 x# R* P) W SPI_Cmd(SPI2, ENABLE);* X2 V) E" D u" p8 m }# I+ i* s& y8 U' ] /**+ @; E( ]* i9 Z# e O# X * @brief SPI1_DMA_Start * @param len <= 4096 * @retval None */ , G' }* ]* G2 n void SPI2_DMA_Read_Write(uint16_t len) { SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);( Q; C% E4 w% S- Q5 O SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE); DMA1_Channel4->CMAR = (uint32_t)SPI2_Rx_Buf;9 N# k$ ]8 Y/ [' A3 C( @" g DMA1_Channel5->CMAR = (uint32_t)SPI2_Tx_Buf;! L% |" p' O& A! z DMA1_Channel4->CNDTR = len;) f% ^) R( {# v2 H$ z DMA1_Channel5->CNDTR = len;, D; z+ c; h7 Z+ R DMA_Cmd(DMA1_Channel4, ENABLE);4 W3 X" @( w# t/ n$ c/ ]3 j DMA_Cmd(DMA1_Channel5, ENABLE); SPI_Cmd(SPI2, ENABLE);4 q# H' N. c* `6 [" b, t } /** * @brief SPI2_Set_Speed * @param SPI2 CR1 bit 9 8 7 * SPI_BaudRatePrescaler_2 ---> 000" N* }" a- l/ Q5 b * SPI_BaudRatePrescaler_4 ---> 001 * SPI_BaudRatePrescaler_8 ---> 010$ t3 U4 T9 @% ?! f( e* p( x * SPI_BaudRatePrescaler_16 ---> 0116 _" }" R) n& l8 t+ `- f * SPI_BaudRatePrescaler_32 ---> 100 * SPI_BaudRatePrescaler_64 ---> 101 * SPI_BaudRatePrescaler_128 ---> 110. n$ I6 b( S2 | * SPI_BaudRatePrescaler_256 ---> 111 * @retval None */ void SPI2_Set_Speed(uint8_t BaudRatePrescaler) { SPI2->CR1 &= 0xFFC7; /* Clear BaudRatePrescaler Value (bit 9 8 7) */" I- J/ f7 y0 o. |9 [: k SPI2->CR1 |= BaudRatePrescaler;3 M u! A) `- ~' l% P/ R, N SPI_Cmd(SPI2,ENABLE);( a! G3 X4 J; G) W3 f! f$ L! Q, _ }* v/ L" h( Y$ B. F# Y9 v! Z1 K+ w2 v 8 @6 r6 Q( q) H9 @ /** * @brief SPI1_Byte_Read_Write% ]2 b% x2 r; e$ @$ I) Y/ |( f ? * @param None q. P5 J" \. O * @retval None */ uint8_t SPI2_Byte_Read_Write(uint8_t SPI_Byte) { // 发送一字节( _. O5 p4 i9 s9 U4 Z+ F# h+ f while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET); SPI2->DR = SPI_Byte; // 接收一字节 while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET); return(SPI2->DR); } /*; J* V; }3 S: P; P7 j5 E5 ^ * Function Name : DMA1_Channel4_IRQHandler( }; ^! v/ z Z+ F * Description : None3 h$ s* u# x! t( H2 t" o. w * Input : None * Output : None9 l0 F0 l, e. Z, Y; E * Return : None7 Y" L: x' Y, ~% f */; Y) t3 }7 O; O \ void DMA1_Channel4_IRQHandler(void) {% o$ G* `/ E' D2 g' s: m6 { if (DMA_GetITStatus(DMA1_IT_TC4)) { SPI_Flash_CS_High();: Q' X, |6 n1 l& U. `, O DMA_Cmd(DMA1_Channel4, DISABLE);9 ?# u& O1 s p$ o* }- [ |, e DMA_ClearITPendingBit(DMA1_IT_TC4);; y) S- A+ e' j. A( x* n8 G# h SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE); Flag_DMA_Rxd_Finished = 1;! m* M9 C$ O7 j3 g6 l }) V }1 m2 }% t; V) {! k5 e* p7 Z9 {6 W } /* * Function Name : DMA1_Channel5_IRQHandler * Description : None! ?4 Y3 Y- M& n$ e- U' N * Input : None; a1 n; Y: j! U$ r0 A/ T * Output : None$ k2 ^6 Z- W u * Return : None D& o( s' X: b: i# A. c+ r4 ~ */# d) N/ e7 a# N ?0 ]1 d( D. y0 t void DMA1_Channel5_IRQHandler(void) { if (DMA_GetITStatus(DMA1_IT_TC5)) { DMA_Cmd(DMA1_Channel5, DISABLE);* A% ?0 K* M. R# v6 { DMA_ClearITPendingBit(DMA1_IT_TC5);: R' O& H& }" j" S) q' t0 e F }, B$ ^. v/ p. y R/ H } ( h3 I, _; t! B- C |
【MCU实战经验】+STM32F103的uCOSII详细移植
STM32固件库分享,超全系列整理
【源代码】STM32F103C8T6最小板搞定CMSIS-DAP和SWO功能
【福利】用STM32库的朋友有福了:STM32F10x_StdPeriph_Lib_V3.5.0chm...
基于STM32F103做CAN的收发通信经验分享
小马哥STM32F103开源小四轴RoboFly全部资料大放送
【管管推荐】STM32经验分享篇
【MCU实战经验】+STM32F107的USB使用
基于STM32F103两轮平衡小车设计(开源)
STM32F107VCT6官方原理图和PCB
命令字节发送和接收, 可以使用SPI2_Byte_Read_Write, 也可以使用SPI2_DMA_Read_Write,
这里使用SPI2读写SPI_Flash, SPI2_DMA_Read_Write 可以按照下面的方法使用:; M" m& W' g. ~: \' M8 v8 l
2 L. g7 ?7 G" L) O2 b! B
SP2_Tx_Buf_load(); // 数据装入发送缓冲
SPI2_Flash_CS_Low(); // 片选使能
SPI2_DMA_Read_Write(6); // 启动发送和接收, 在DMA传输完毕中断里片选关闭
while(Flag_DMA_Rxd_Finished==0) {
// 使用DMA连续收发时, 可以利用这个空闲做一些事情5 Y5 X% t' S9 ~
// 如果是用SPI2_Byte_Read_Write, 单字节收发就没有多少空闲时间了* h, |1 z: s& \+ w* I
;: f8 Q$ b6 t+ v. s* t, G7 G- G1 l
}! r1 }* d9 n& y6 N1 C
Flag_DMA_Rxd_Finished = 0; // DMA收发完毕,标志清0! m& B# ]5 A' \! x& m9 c: u
! \% P W1 r" z! L* |0 W5 Q* e
研究,研究