本帖最后由 wjandsq 于 2015-6-25 14:12 编辑 * W6 [% G9 Y0 B) y. m ; n* X7 [% D* P# t. M R8 q /* * spi2.c ** I+ P9 |. f2 l+ o0 { * Created on: 2015年6月22日 * Author: WJ- h" L4 G" w6 B */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_conf.h" q4 p# J5 q/ @ i4 j# k& ^3 }6 [9 a / u4 w# W0 X; y+ C #define SPI_Flash_CS_Low() {GPIO_ResetBits(GPIOC, GPIO_Pin_13);} #define SPI_Flash_CS_High() {GPIO_SetBits(GPIOC, GPIO_Pin_13);}$ k0 I0 ?" I$ Y3 q9 I uint8_t SPI2_Rx_Buf[4096]; uint8_t SPI2_Tx_Buf[4096]; 8 a1 Y/ @# \8 f ? extern uint16_t Flag_DMA_Rxd_Finished; ( e; k% ]0 d/ ]- C extern uint8_t SPI2_Byte_Read_Write(uint8_t SPI_Byte);, l; g) V; g2 t( g) Y, ^# B5 F 7 N& V+ z$ p) b# d" |8 v! r% [7 S7 u /**) s/ e5 _' e+ X! S( ` * @brief Configures the SPI2 Peripheral.; Z! P% F$ ]* X. f* s i. ` * @param None * @retval None) E# g) P/ J* U* j. ~ */ void SPI2_Config(void){1 a8 t( g8 L* i# @9 | GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure;: z' U2 H" X! k- Z3 z- b DMA_InitTypeDef DMA_InitStructure; S# C ]; }( Y+ }' n NVIC_InitTypeDef NVIC_InitStructure; /* Forces or releases High Speed APB (APB2) peripheral reset --------------*/ RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, ENABLE);+ p9 }- T0 {1 [2 N, x. h/ I RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE); 2 f4 x# A1 e; \( {8 q: O RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE);% S- O3 \& u6 W* z H+ X6 }; ? ( r- E6 I9 w! u# F RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE);4 J& b% m) j. W" j# `1 B1 p RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE);3 L+ H( K8 f, |4 D - J5 R, m' i" u' X1 X0 E RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, DISABLE); 3 J) g$ B- R3 M+ t7 v8 E. h RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); /* Peripheral Clock Enable -------------------------------------------------*/. [6 k3 ?1 o! @5 ` /* DMA1 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, DISABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);; _% [6 p# J7 j8 ?3 R: J* G* i4 ^ /* Enable GPIO clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);; A$ k4 b: _8 K8 S/ L RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);4 F$ @7 b1 \" B; e5 U" a8 q+ V RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);. u1 j- F4 x: H& w0 S RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);, y2 b+ A$ z. G# e0 r4 t /* SPI GPIO Configuration --------------------------------------------------*/ /*/ ?( m+ F" k" }1 Q' q8 \7 i * PB13 --> SPI1 SCK Mode: GPIO_Mode_AF_PP; U: x }* i$ M* K* m3 J * PB15 --> SPI1 MOSI Write Mode: GPIO_Mode_AF_PP- }7 L( J+ P1 S. [0 v * PB14 --> SPI1 MISO Read Mode: GPIO_Mode_IPU * PC13 --> SPI1 CS */ H. y1 S$ m; i# i# u& v) }: F2 C GPIO_DeInit(GPIOB);- _4 b1 C$ b0 Y# n, a5 @" v GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;. `, X" t% V$ R. H7 j GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;+ c2 X+ r B3 ` ]2 U+ b# s4 @ GPIO_Init(GPIOB, &GPIO_InitStructure);6 D: I: O0 `7 @9 G GPIO_SetBits(GPIOB, GPIO_Pin_15);9 `' S# x$ R4 L3 ^- {* Q 7 {3 ]( T8 u/ i, f& P; W GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;* N% _6 n0 q v |2 {+ [" C5 Z5 a" R# G 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); a) N0 c+ e% I0 b9 B t 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;3 G, W$ D5 ]- r+ v 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);6 a- |6 {( }& X1 J4 r if(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) != RESET){0 |" M( P" p4 E- `: t$ q T SPI_I2S_ReceiveData(SPI2); SPI_I2S_ClearFlag(SPI2, SPI_FLAG_CRCERR);0 h0 N; }$ ~: s } /* DMA1 Channel4 Configures for SPIS Receive */ DMA_DeInit(DMA1_Channel4);9 H; V- ~; f8 [4 l DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI2->DR);( q# l2 S% ~5 }* S% [( ^% k DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI2_Rx_Buf; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;3 }+ A- q9 [' x" _2 N' F DMA_InitStructure.DMA_BufferSize = 0; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;, o4 R E8 _5 P0 a4 w. } DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;' b# l* G- e) w- [0 y DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;( S7 l% d# A( B# g" Z6 m DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;; ^* W) {+ W; z, y DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;0 c$ t. ^+ d0 P DMA_Init(DMA1_Channel4, &DMA_InitStructure); ~* `5 b3 n2 R% _0 k $ M3 f# f+ m6 x" P; h if(DMA_GetITStatus(DMA1_IT_TC4)!= RESET){ DMA_ClearITPendingBit(DMA1_IT_TC4);2 d& a. _# Q: V0 I$ _* h } DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE); /* Enable DMA1 Channel4 SPI2_RX */8 }& H& b1 {$ h DMA_Cmd(DMA1_Channel4, DISABLE);* q* j- J& v5 _$ P8 s- j4 M 8 \: r( V( ^# q7 ] /* DMA1 Channel5 Configures for SPI2 Send */3 c; G- o9 I3 g) c" M3 e0 s! S* l$ H DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI2->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI2_Tx_Buf;. Y9 ~+ \3 l8 E1 Q3 Z2 n+ y DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;8 k1 \% G& E% a# V4 m! i( e DMA_InitStructure.DMA_BufferSize = 0;4 {: A! @0 K: O+ `! J) Z5 A DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;# E3 w; G) ]+ D: I4 |. ` DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;9 z M0 L3 O) I: F9 t; t DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;" u6 ~4 `9 w6 Z: P2 n: u% V DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); ! q3 y5 X2 n3 j9 J if(DMA_GetITStatus(DMA1_IT_TC5)!= RESET){# P9 i' C' L# j( H+ C5 ^) A DMA_ClearITPendingBit(DMA1_IT_TC5);2 Q. j% k. n5 f } DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);( n8 C: {5 B8 U$ d6 z6 q8 d / ]2 @- a n: Q: a) X /* Enable DMA1 Channel5 SPI1_TX */ DMA_Cmd(DMA1_Channel5, DISABLE);+ t. \4 @4 y+ C3 s7 Q / B; |( G4 N' ]+ z/ g /* Enable the DMA1_Channel4、DMA1_Channel5 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;- [) ^8 q2 E% P7 |9 P D% x NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;& K; j* q0 \* N) _! V/ M2 u NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);" h/ r0 n& z2 b- K, ~ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;" r& _0 s9 [- D+ d; u NVIC_Init(&NVIC_InitStructure); /* Enable SPI2 */ SPI_Cmd(SPI2, ENABLE); }$ Q+ B0 i$ I/ `* P5 p; f- p4 M5 ]2 L /**# p* @5 E' x: W3 _! D" _& i * @brief SPI1_DMA_Start * @param len <= 40965 B# d4 F; Q M$ a7 r1 P * @retval None1 ?% `+ t/ m+ W1 u */* S A" s: }7 v0 ], y 8 L& ]( G) {1 N2 l7 o void SPI2_DMA_Read_Write(uint16_t len) { SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);0 }7 f' i0 z% j5 Q SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);" k0 W5 @" ?$ O) e DMA1_Channel4->CMAR = (uint32_t)SPI2_Rx_Buf;* E+ e5 o8 X1 z" H9 x7 U DMA1_Channel5->CMAR = (uint32_t)SPI2_Tx_Buf; DMA1_Channel4->CNDTR = len;7 G9 N- R4 f# O4 _8 O! p DMA1_Channel5->CNDTR = len; DMA_Cmd(DMA1_Channel4, ENABLE);& H' G7 o& V, c8 I: Y+ A3 t7 Y DMA_Cmd(DMA1_Channel5, ENABLE);3 I V9 ~- }( b3 L1 s. Q; @: f' x* p SPI_Cmd(SPI2, ENABLE); }6 S6 Y# T6 g9 D: A0 N3 { # e& C5 k6 b3 a, l4 M( Q( p; y) O /**% c: A; p7 V+ }3 M% _2 ^6 q. s * @brief SPI2_Set_Speed * @param SPI2 CR1 bit 9 8 7, W' X8 w* A8 i6 x! M: e * SPI_BaudRatePrescaler_2 ---> 000 * SPI_BaudRatePrescaler_4 ---> 001# ~$ I/ d' c" l2 W7 k4 [' A * SPI_BaudRatePrescaler_8 ---> 0109 l4 f: s& U( ]9 Y4 c * SPI_BaudRatePrescaler_16 ---> 011 * SPI_BaudRatePrescaler_32 ---> 100 * SPI_BaudRatePrescaler_64 ---> 101 * SPI_BaudRatePrescaler_128 ---> 110 * SPI_BaudRatePrescaler_256 ---> 111 * @retval None5 w3 l5 l/ S) I& }7 [ T% ?/ w/ f */* a% r: s- s* c" n2 ^ F8 H' T / g/ @- X W; o0 \/ C$ r void SPI2_Set_Speed(uint8_t BaudRatePrescaler) {1 T( _6 x$ B4 W1 ? SPI2->CR1 &= 0xFFC7; /* Clear BaudRatePrescaler Value (bit 9 8 7) */* Q- F1 z, m4 i1 S- | SPI2->CR1 |= BaudRatePrescaler; SPI_Cmd(SPI2,ENABLE); }" p( q8 l5 g+ U: P+ I* i" {5 _3 o + s: f& Q1 {* P4 X0 b; L /**: W8 G$ ?7 V/ D$ H! n * @brief SPI1_Byte_Read_Write * @param None * @retval None */% ?* n6 n+ d7 Q) I5 K uint8_t SPI2_Byte_Read_Write(uint8_t SPI_Byte) {) I8 D* ? C0 D$ G) k // 发送一字节7 r) B: h& E3 S; v$ A9 Q while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);. G2 i) w, k9 Q m3 w% P SPI2->DR = SPI_Byte;; W/ o L% n4 Z6 ~' d: ^5 R$ ? // 接收一字节8 F- q, Q4 x. a; R/ n while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET); return(SPI2->DR);. C1 V0 C; Y+ R2 {; [" N8 ^ } /*" H" Q) }) A) H! m/ p+ E2 E * Function Name : DMA1_Channel4_IRQHandler; F; ?$ J# L3 h% a* R * Description : None9 ]% N# M6 K! |3 c. t; V; V * Input : None, O- M: Z/ h- U * Output : None/ s9 p7 ~; P' ?/ x3 U! G& E * Return : None *// q, A, n6 u0 Q* ^4 | void DMA1_Channel4_IRQHandler(void) { if (DMA_GetITStatus(DMA1_IT_TC4)) {( W- F8 Y7 H3 d0 b$ a SPI_Flash_CS_High(); DMA_Cmd(DMA1_Channel4, DISABLE);$ \1 X7 u4 U9 M% r DMA_ClearITPendingBit(DMA1_IT_TC4);; _4 a3 T9 ?& h SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE);) P5 E/ H u% F. b8 F SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE);5 {+ e1 o( D0 |& ~' ]/ f0 ?6 q1 K Flag_DMA_Rxd_Finished = 1; }# b$ H, r6 U! W% \, c1 O( D+ ]) N0 i }) x0 n8 B7 f& p- X /*8 z8 j& b8 I$ w. \# n) w * Function Name : DMA1_Channel5_IRQHandler. K6 d# l7 W O5 ~! q8 y * Description : None * Input : None * Output : None+ S) ^3 D8 T) o* ]9 w5 j * Return : None' ~' {/ P: C8 A6 e5 E, T( I; @( a */ void DMA1_Channel5_IRQHandler(void) {, Q; W6 k8 g# y, |; T# S; f if (DMA_GetITStatus(DMA1_IT_TC5)) {9 W9 D6 Y0 z& m+ h- q DMA_Cmd(DMA1_Channel5, DISABLE);# s; Q( |' h, y& }( ~8 D DMA_ClearITPendingBit(DMA1_IT_TC5); }! ]7 A8 v$ T3 i! Q4 A1 w }8 T6 Y: b3 f1 v) h0 ?! F% o8 v. e 3 A4 a. X9 U) a$ I( p+ W4 I 8 A! W4 ~+ s# g! l |
UDS诊断服务
使用Nano板验证驱动SPI串口屏的颜色显示
使用STM32F103制作的无线下载器
小马哥STM32F103开源小四轴RoboFly全部资料大放送
STM32F103移植LittlevGUI代码
【MCU实战经验】+自制MP3使用STM32F103ZET6和ch375读取u盘,vs1003解码,音质超棒
串口通信波特率异常的解决办法
【MCU实战经验】+STM32F103的uCOSII详细移植
游名科技:STM32F103+TMC2160:86步进电机和驱动一体原理图/PCB...
在高容量 STM32F103xx 微控制器中实现 ADPCM 算法
命令字节发送和接收, 可以使用SPI2_Byte_Read_Write, 也可以使用SPI2_DMA_Read_Write,5 D1 x: S" ~' ^: M
这里使用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) {4 T3 i0 E+ ]4 ]: B1 C
// 使用DMA连续收发时, 可以利用这个空闲做一些事情
// 如果是用SPI2_Byte_Read_Write, 单字节收发就没有多少空闲时间了
;
}
Flag_DMA_Rxd_Finished = 0; // DMA收发完毕,标志清0. S0 x. ^+ p! u# t" ]9 E/ u4 @1 S
+ L* Q& @) V! G; [) |+ H2 m7 e# S1 e3 r
; T4 ?' F+ B- O$ H! F
9 ^2 G+ R) k4 J1 s# g5 K. R5 R
N# ~! ]) d! J7 \7 Y! L
研究,研究