特别注意NSS引脚的配置,见代码。 B, \# y+ _+ H" c, F
1.GPIO的配置与103系列的不同;
6 y, g1 A* ] I1 [' I$ s' a C8 t2.SPI功能更强大,比如支持CRC校验,配置与103系列不同;6 g# N% }9 v2 {+ w
其他特性请参考datasheet.
8 J5 j) x& c: }- ~9 o: s- /*******************************************************************************
, K K0 S9 E! e- `, D - //STM32F207VGT6 FOR ENC28J60
1 a. p/ f3 i' e6 k6 F0 m - //SPI2初始化/IO初始化等
; g9 d. F7 `* R# C5 K2 S4 a6 o& R - //SPI configuration
) r$ ?) J. x2 q - @@ JUST FOR STM32F2XX1 b/ z1 o5 r4 A# a
- *******************************************************************************/2 V0 z: d/ s- n ]
- void ENC28J60_SPI2_Init(void)
# s) L* C3 z2 t4 {6 V - {) Q$ W' F9 K1 j. L
- SPI_InitTypeDef SPI_InitStructure;
' Q9 m, j/ b4 s& T. |% t - GPIO_InitTypeDef GPIO_InitStructure;
" I' n4 p f# B. F% K4 H
6 b. d$ D3 F7 F6 U; ]3 W7 Q- c+ G- /*!< Enable the SPI2 clock */ 6 [6 W, j" @9 J2 {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
B9 _" @. {- x3 ]0 P$ H S5 m$ d6 |/ O - ) I0 \5 S5 g- O! D0 f
- /*!< Enable GPIO clocks */2 z n5 j; K$ F7 M3 ~$ w" m
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);& |0 P+ }& L9 R$ o) |
- /*!< SPI2 pins configuration */
5 w6 x4 s$ _! f# U6 W+ ?% | J -
/ J* G# p# e F6 i; Q - /* Configure SPI2 pins as alternate function (No need to
. B8 ~ k; f3 `- { - configure PB12 since NSS will be managed by software) */
/ j- h4 E0 g0 ~, j - GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI2); //nss 4 c* P- ]% v) r# C& [$ e$ j8 C
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); //sck( K9 K* n( H+ y& L7 s
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2); //miso
- H1 A& [2 b. w+ I! d- c - GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2); //mosi
4 T. ?( E0 ~# V -
* S9 D0 K8 A, k3 m' I - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
" \- f( k; F' u' K. ^" G5 H9 I! i6 f: K - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // also 100Mhz) k0 j/ C' F2 \* H
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
" s/ j5 ?2 @( [7 ]# y - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // GPIO_PuPd_DOWN
( i6 h8 X7 o) i% U* Z - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;% T6 M( I2 E+ }- C6 u( a
- GPIO_Init(GPIOB, &GPIO_InitStructure);// PB13/14/15-SCK,MISO,MOSI
& {" J+ e2 |. i* q) W" v - : F) l# p5 |9 M, c L1 T- s
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; , q/ c! k% Y( r5 P
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;' e3 f4 l/ }9 }3 K9 x( w9 w' d
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;: g4 Z7 j+ D, a8 X
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; 3 N5 j+ z' \5 e) T0 I6 X" o
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_12; // RESRT and CS for enc28j60
4 |* J+ H; Y3 w) O# b9 A8 j/ y - GPIO_Init(GPIOB, &GPIO_InitStructure);
/ f. O% |7 p1 Y5 T6 @1 r -
. [. h3 X; j- h1 }" _4 S% j L: H - /*!< Configure enc28j60 interrupt pin in PullUp mode ********************/% i5 K# ~# Q3 c- \" {- O
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;' G4 @9 w5 g! g. A9 Q# ^) `6 ^
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;! E3 o1 l( B) v; w% c3 E
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
4 \, b; K! F* V9 K - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;2 V v: z* r, H; w Y/ d9 y; x+ B) r3 R
- /*!< SPI2 pin configuration */
3 o7 o; |- g9 T* O9 d" o - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //INT
! W% R. ^. p. P7 j8 r; S - GPIO_Init(GPIOB, &GPIO_InitStructure);4 K# g: F8 D& p- b" g
+ u) n5 O8 z3 s( e4 z- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI设置为双线双向全双工
' s+ I& L9 e X1 g5 a - SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为主SPI, p, q; {1 d" M$ e& r* S" { T
- SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//设置SPI的数据大小:SPI发送接收8位帧结构1 B ]8 S4 |. T( r8 b8 r$ Y
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//选择了串行时钟的稳态:时钟悬空高
3 S; A4 R8 F: N, ` - SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//数据捕获于第二个时钟沿% j2 `; ^% ?3 F _" ]
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//(SPI_NSS_Soft)此时NSS引脚可以配置成普通GPIO去控制从设备
( g d& \! n* b# h( P8 B1 t" E! m - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//Fclk/2
% k& D i3 [- K' _ G6 H; e - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; /* Initialize the SPI_FirstBit member */" b, T8 W2 o$ `
- SPI_InitStructure.SPI_CRCPolynomial=7;
4 A! U$ f% n; Z2 Y" m - SPI_Init(SPI2, &SPI_InitStructure);9 H; C P# P' [; a* v
- SPI_Cmd(SPI2, ENABLE);
- y$ x3 G: b+ ]7 D- d1 V; Y - 2 K; E; H. u1 ?/ P4 i
- }
, C; A0 r* @8 g1 J* b) t6 A
/ A. r# O; f; x! E- /*******************************************************************************
( v' G1 L* G" s* ?4 W - * Function Name : SPI_ReadWriteByte. J3 @+ E& [$ I$ _1 @
- * Description : SPI读写一个字节(发送完成后返回本次通讯读取的数据)
( D6 I* E t# A; I5 b* Q& l - * Input : unsigned char TxData
. o: F7 P1 K6 ~. i) c: p$ Y - * Output : None/ N D0 U# k# w. U7 S# Q
- * Return : unsigned char RxData | L0 f# e2 d1 e0 x- n/ E' I2 D ?
- *******************************************************************************// Z W! }9 K! o" K2 s8 r
- unsigned char SPI2_ReadWriteByte(unsigned char TxData)
/ {4 v p% G9 r - {
/ G) C2 a- P/ C- S$ |! D - unsigned char RxData = 0;, v) \" H% X1 [( F$ d0 w, C
- /* Wait till Transmit buffer is empty */ 1 D- n8 h" a0 V$ G' u. _' e
- while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
) |# p6 |$ L5 T' k6 ` - /* Send A data */ / X% ^% h( }" K7 c5 P
- SPI_I2S_SendData(SPI2, TxData);
: B/ B7 c% X$ `' f @% _* Q) c - // while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);
, B2 M! z0 g" ~9 U - //等待数据接收- [% U! f9 i3 f
- while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);; ?$ v$ z' D' l$ E
- //取数据
# a0 f n: X- C4 ] - RxData = SPI_I2S_ReceiveData(SPI2);
5 z2 E! B0 W, q( M x* _ - return (unsigned char)RxData;; ~! V8 J5 Y8 s4 s% I1 N
- }! i0 N0 N& Z; A! J# J7 L; x
- ! | Z6 C/ R3 e& y
- % {" {# H! d- ^6 B
复制代码 ) j) `) K1 \9 f3 L: M9 ^$ s4 h
/ @' ~8 A, m) e* L |