|
本帖最后由 wjandsq 于 2015-6-25 14:12 编辑 * k* {& K0 h; O% |; K /* * spi2.c *; O+ h' ?) j F( K8 ? * Created on: 2015年6月22日% M: C5 e) }1 r5 ~ * Author: WJ */ 3 n% q- t1 e1 d 5 `6 w( v1 f+ t7 v! a& ? /* Includes ------------------------------------------------------------------*/* n1 Q9 V, U: f #include "stm32f10x_conf.h"- m6 e: U/ D# X. b; f$ p #define SPI_Flash_CS_Low() {GPIO_ResetBits(GPIOC, GPIO_Pin_13);}" [' Z3 B. k% V- j+ p3 v/ z4 K1 r( U/ [ #define SPI_Flash_CS_High() {GPIO_SetBits(GPIOC, GPIO_Pin_13);} uint8_t SPI2_Rx_Buf[4096];& Y' l# W A" z+ r% J uint8_t SPI2_Tx_Buf[4096];# a$ U3 h; q7 q0 k- I* S1 ^" J/ J! K+ G 0 _& s+ T a( H/ B4 o- r, w& `4 y extern uint16_t Flag_DMA_Rxd_Finished;8 N) X1 R& Z9 C4 K8 \$ Y' {1 l - ^* X4 a% A R7 T7 H extern uint8_t SPI2_Byte_Read_Write(uint8_t SPI_Byte); /** * @brief Configures the SPI2 Peripheral.( B" j3 p% E5 w! { * @param None- }$ ~, ?* K2 y' C * @retval None. S/ v. h7 {$ ] */ @# F, e1 o/ u- p7 t8 Z1 O void SPI2_Config(void){7 C/ Y9 E7 Y$ j; X0 Z4 L7 k GPIO_InitTypeDef GPIO_InitStructure; m! H' b, C9 A' A, k- |" H7 y! c SPI_InitTypeDef SPI_InitStructure; DMA_InitTypeDef DMA_InitStructure;/ A" f! x8 b0 ^1 g# A4 f+ [! W9 d* k NVIC_InitTypeDef NVIC_InitStructure;1 o! {3 ?2 g, g + E" p& ^9 ~% r& A, ^ /* Forces or releases High Speed APB (APB2) peripheral reset --------------*/ RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, ENABLE);- {4 \$ C9 {3 t/ v/ p" I RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE); % ^+ d9 L( g; \; h4 K RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE);, O, B/ I: A' J2 c6 K RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE);; I# D% Z1 Q& q* P) U RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE);8 d C6 ]( J4 V RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE);8 l5 v; l; g! }$ h! S RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, ENABLE);- d X( [% ?1 q, u6 F RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, DISABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);6 m6 m/ o1 b. x" y RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);1 r0 y; U5 w8 W /* Peripheral Clock Enable -------------------------------------------------*/2 h0 C+ l9 S0 {( _3 \ /* DMA1 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, DISABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);$ U/ d4 q v5 r( v l /* Enable GPIO clocks */, Q% O! K5 E) j) W- N RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);4 A' z5 K& B; y7 U1 V, @8 j RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);8 L. e7 L3 [" L" g" n& B* _ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);* f7 Y; u# w1 V /* SPI GPIO Configuration --------------------------------------------------*/ /* * PB13 --> SPI1 SCK Mode: GPIO_Mode_AF_PP * PB15 --> SPI1 MOSI Write Mode: GPIO_Mode_AF_PP * PB14 --> SPI1 MISO Read Mode: GPIO_Mode_IPU- }: R5 p9 d( i3 D) i * PC13 --> SPI1 CS */. C/ w2 x9 `; U/ b% W" d# F 9 A/ ]: ?' @; ]* q7 M0 x GPIO_DeInit(GPIOB); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;) Z! n8 F, T; X' i GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;& E( e8 G; T% o) b& `( y GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;& C6 ^) d: I& D( ]% n$ v4 Q9 I GPIO_Init(GPIOB, &GPIO_InitStructure);3 \' G2 a( L* O9 J8 F0 A5 u GPIO_SetBits(GPIOB, GPIO_Pin_15); 4 L+ ~" a3 m* C7 A7 U) V- p GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;7 u" a* v$ j U" g* E1 e, t; P GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB, GPIO_Pin_14);# k; M0 L ?5 ]7 ]9 k# A # H. d. Y) z# W; u, c$ e GPIO_DeInit(GPIOC); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); l/ \9 K+ o4 _; w6 ~2 [7 d) v3 B GPIO_SetBits(GPIOC, GPIO_Pin_13);8 ?1 p- p* [* K; ~, s & ]8 `+ {" `2 q4 n3 E SPI_Cmd(SPI2, DISABLE);- a/ G9 L4 o! }; i# C7 m& U5 C9 i SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; c7 R8 _5 p8 F- K SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;0 `7 v) X, Y' u" u! t SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;7 L$ w3 N5 ~/ C( d SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;- T7 R5 a3 d: P! f* M7 f SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;9 u% {7 D' z, O5 v6 ]7 j# B SPI_InitStructure.SPI_CRCPolynomial = 7;4 V$ ^) m3 l, Q# x. @" W SPI_Init(SPI2, &SPI_InitStructure); if(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) != RESET){ SPI_I2S_ReceiveData(SPI2);8 L" c: ~ {6 d+ t' [. {& p SPI_I2S_ClearFlag(SPI2, SPI_FLAG_CRCERR); K( N' p2 B+ |5 g7 W9 {1 m* {" { }5 [/ Q" `! Y' R+ I% T8 h$ w, z- q /* DMA1 Channel4 Configures for SPIS Receive */% f2 M& G' Q- d DMA_DeInit(DMA1_Channel4);, d2 f @2 g0 x1 X0 b: c1 p' ]! ]% \ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI2->DR);' D M e. G, f5 _$ S8 v( l DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI2_Rx_Buf;5 U" O5 a6 B: o. g5 | k6 S DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;( G( I( r' `5 A( ^ DMA_InitStructure.DMA_BufferSize = 0;# f- Z( ~* L( [3 z DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;' I, t1 G' B# `3 a3 _3 j9 ` DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;# \( C y" ^+ i- M3 p DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure); if(DMA_GetITStatus(DMA1_IT_TC4)!= RESET){ DMA_ClearITPendingBit(DMA1_IT_TC4); }# L7 e- l2 z6 d, ~: P$ W' j DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);* K3 O. [4 e/ |( \- j6 E3 F m SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE); /* Enable DMA1 Channel4 SPI2_RX */. j( x, m" C8 a o* _7 k4 z DMA_Cmd(DMA1_Channel4, DISABLE); /* DMA1 Channel5 Configures for SPI2 Send */ DMA_DeInit(DMA1_Channel5);4 H6 E* o1 L( [+ V8 f DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI2->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI2_Tx_Buf; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 0; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;2 ~5 i% \8 y7 {/ P: V DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;; b- Q E! o* S! v" C* F0 [( ] DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;- K4 C+ P0 C2 N8 T; K8 y) a. m DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;' A; S8 V# {5 F1 K DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); if(DMA_GetITStatus(DMA1_IT_TC5)!= RESET){/ k5 n" D0 {( X l: f6 T8 c( y DMA_ClearITPendingBit(DMA1_IT_TC5); } D# Z) j6 T) P3 N+ D) ? DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);, W8 ~! @; E8 ]0 z& H 5 `( }+ m. {5 O- b. H) n /* Enable DMA1 Channel5 SPI1_TX */ DMA_Cmd(DMA1_Channel5, DISABLE); # k7 w0 e# F9 L: r" m3 g2 p- U /* Enable the DMA1_Channel4、DMA1_Channel5 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;! o/ G3 n, M9 r0 _; ^- F: g NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;! H3 C, P$ y4 H" q* i% o, W7 h5 n NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;% {% ~ E4 a, i8 X5 F NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn; NVIC_Init(&NVIC_InitStructure); /* Enable SPI2 */ SPI_Cmd(SPI2, ENABLE); } /**9 I! W$ g+ w% N$ w% d0 x * @brief SPI1_DMA_Start * @param len <= 4096 * @retval None */. K3 a2 e8 j ?' C9 g# c5 k - q7 b; Z E; D, b: j8 n9 | void SPI2_DMA_Read_Write(uint16_t len) { SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);; J7 L0 |- G8 u$ e; M" i+ l$ H DMA1_Channel4->CMAR = (uint32_t)SPI2_Rx_Buf;% a( k! }- B' R/ P b; ?# E2 ?9 h DMA1_Channel5->CMAR = (uint32_t)SPI2_Tx_Buf;4 y* i1 a0 q+ L- J6 | DMA1_Channel4->CNDTR = len; DMA1_Channel5->CNDTR = len;! w3 \& r. f& _* i J DMA_Cmd(DMA1_Channel4, ENABLE);' A. U- p4 c: n7 o. [/ v" D4 ~ DMA_Cmd(DMA1_Channel5, ENABLE); SPI_Cmd(SPI2, ENABLE); }6 {& A* l- w. v! i' e" H * B: N. K/ w. ]+ J7 ?( b /**& K* h3 N. G, ]2 f2 L1 d * @brief SPI2_Set_Speed * @param SPI2 CR1 bit 9 8 72 }7 L2 Q Q' l1 x$ J * SPI_BaudRatePrescaler_2 ---> 000! S. U" Q1 [: q * SPI_BaudRatePrescaler_4 ---> 0018 F4 _+ M0 F7 P) l7 g! d6 ^ * SPI_BaudRatePrescaler_8 ---> 010: @) }" V' I+ f; e" T& E1 I5 y * SPI_BaudRatePrescaler_16 ---> 011 * SPI_BaudRatePrescaler_32 ---> 100- m5 p, `' R9 A. \. x# ?, {2 c& k * SPI_BaudRatePrescaler_64 ---> 101 * SPI_BaudRatePrescaler_128 ---> 110 * SPI_BaudRatePrescaler_256 ---> 111 * @retval None */ * n5 F# A) ^ d2 E1 ?0 c void SPI2_Set_Speed(uint8_t BaudRatePrescaler) {, k5 ^* `6 g1 X SPI2->CR1 &= 0xFFC7; /* Clear BaudRatePrescaler Value (bit 9 8 7) */8 p7 H p. u0 n8 j: ?2 q% U- t$ l SPI2->CR1 |= BaudRatePrescaler;. }6 a: |) _' s6 `1 L4 r1 ~ SPI_Cmd(SPI2,ENABLE); }* n! O7 ]* q y- p' H4 [( e /**. L0 R2 s* j0 B * @brief SPI1_Byte_Read_Write% D, Y: g3 o, ^) Q. r2 }# l: | * @param None% ?7 ~5 e% _, n; b6 d * @retval None */+ B1 H$ Z8 e, C7 c W uint8_t SPI2_Byte_Read_Write(uint8_t SPI_Byte) {) T5 ^ o# D( N // 发送一字节 while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET); SPI2->DR = SPI_Byte; // 接收一字节4 P9 D% e" n, z8 d while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET); return(SPI2->DR); }! G' N5 N' f% a; i 3 H$ p. B1 }% l9 s! x; q /* * Function Name : DMA1_Channel4_IRQHandler. ^) g8 U; D/ p1 v. h7 B5 u3 E) Z * Description : None4 m v" G2 G* L+ I * Input : None$ S& ~/ }. k- I! m, T * Output : None4 v! N% m8 L9 }4 a; V * Return : None */3 j: ]; y% W" V void DMA1_Channel4_IRQHandler(void) { if (DMA_GetITStatus(DMA1_IT_TC4)) {! c8 ?' ~& h# @! X& S) ]" S SPI_Flash_CS_High(); DMA_Cmd(DMA1_Channel4, DISABLE); DMA_ClearITPendingBit(DMA1_IT_TC4);! j: X) b" l- |8 @! t) c$ z SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE);9 U0 s" q+ x% m1 h SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE);2 I7 \1 B) T& M8 n Flag_DMA_Rxd_Finished = 1; } } /* * Function Name : DMA1_Channel5_IRQHandler * Description : None * Input : None * Output : None * Return : None */' R5 m0 Z) v2 G) E& @! h void DMA1_Channel5_IRQHandler(void) { if (DMA_GetITStatus(DMA1_IT_TC5)) { DMA_Cmd(DMA1_Channel5, DISABLE);/ R" Z( X+ k2 T e! @# z* n* N/ t DMA_ClearITPendingBit(DMA1_IT_TC5);: J0 y- m; @# Q6 b' J: F }$ b- {; T& l1 |% D: s w } ' S, N3 M7 F4 E: v* Y u |
DMA 原理从 0 到 1:为什么它能解放 CPU?一文讲透 DMA 的工作流程
【福利三:雨露均沾·逢7狂欢】之五:STM32系统时钟PLL故障排除1例
【福利三:雨露均沾·逢7狂欢】之三:AI帮我查BUG
福利三:雨露均沾·逢7狂欢】之二:STM32F407VG串口通信乱码故障的排除
基于STM32F103的I2C主从机通信
OpenBLT移植到STM32F103战舰开发板上适用于所有STM32F103系列的Bootloader
TFT LCD 与 FSMC 的硬件连接大容量 STM32F10xxx FSMC 接口
单片机:初学者该了解的STM32F103基础知识
2025软件工具兔哥知道
STM32之继电器模块
微信公众号
手机版
) V+ x% N2 |& P( k6 j0 i
命令字节发送和接收, 可以使用SPI2_Byte_Read_Write, 也可以使用SPI2_DMA_Read_Write,9 `3 [6 T5 r' K4 E! u K) M8 ^4 U
这里使用SPI2读写SPI_Flash, SPI2_DMA_Read_Write 可以按照下面的方法使用:2 H* S1 B: U* B$ `
SP2_Tx_Buf_load(); // 数据装入发送缓冲
SPI2_Flash_CS_Low(); // 片选使能 Z& q/ a& x9 A0 B" M0 M- H6 S1 ?
SPI2_DMA_Read_Write(6); // 启动发送和接收, 在DMA传输完毕中断里片选关闭
while(Flag_DMA_Rxd_Finished==0) {
// 使用DMA连续收发时, 可以利用这个空闲做一些事情
// 如果是用SPI2_Byte_Read_Write, 单字节收发就没有多少空闲时间了& i- @" Q0 M, X! _( Z0 A1 y8 k
;
}% ^0 W1 Q6 E4 [- ^
Flag_DMA_Rxd_Finished = 0; // DMA收发完毕,标志清0, [ J8 u- l7 z' e
$ ]- b: ?$ g7 E. n _: `
+ H( s& t j4 |# W1 N6 b8 e
研究,研究