特别注意NSS引脚的配置,见代码。
- z$ v" S7 k6 G1.GPIO的配置与103系列的不同;7 p3 W+ {0 t. i5 d6 S5 ?
2.SPI功能更强大,比如支持CRC校验,配置与103系列不同;, F7 W# }) }4 |, \) s$ f
其他特性请参考datasheet.3 ~; K- P2 f- B3 h) _: M1 A H, W
- /*******************************************************************************
9 g7 p5 k" m4 u - //STM32F207VGT6 FOR ENC28J60
8 X$ H N0 p6 e- z) C: J5 M# J Y2 f - //SPI2初始化/IO初始化等3 G F" c1 z, d
- //SPI configuration
8 l8 ?$ D/ ^. z- o; D) p. L - @@ JUST FOR STM32F2XX9 \6 g: f( [! z9 L0 a
- *******************************************************************************/
/ v* ^; n7 F% t; [& p# h - void ENC28J60_SPI2_Init(void)
* P& R1 a8 o9 b. W$ I, d. t - {
1 |+ U# e3 l; B9 `- u3 q! J* v% V - SPI_InitTypeDef SPI_InitStructure;
1 i. s: K4 _# u- [) B( P; p) J - GPIO_InitTypeDef GPIO_InitStructure;
: n0 `/ ~ Y5 U6 H1 @ - 9 \1 {$ p% \! N( l! l5 W
- /*!< Enable the SPI2 clock */
7 B* O. C+ d* a& c+ r, S. ^9 k: E - RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
, S3 s. H% d# ?: s - / B' [- R! }1 s
- /*!< Enable GPIO clocks */
$ B6 d, m: e& @# z; I - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
- ^4 _6 @4 L8 O6 r - /*!< SPI2 pins configuration */
: G! F/ k$ a. O; P - + o* j- R- s7 D& N
- /* Configure SPI2 pins as alternate function (No need to " h9 y7 o0 \+ a. {
- configure PB12 since NSS will be managed by software) */ 7 K; j8 L2 c p2 b# ^1 P
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI2); //nss d2 v% k: p o6 E! o. w
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); //sck
% }& ?. Z6 E9 o( E1 i - GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2); //miso! [/ ^, Z" K- Y- [2 y+ G' ~
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2); //mosi
5 C) \8 \0 w' G -
7 O3 n* \' Y3 r1 S9 J/ S6 l7 N - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;' o v! ^7 U) x) C6 q
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // also 100Mhz
6 L6 k, A, { @6 [, a3 b - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;/ s6 ]3 I, `* s0 V _
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // GPIO_PuPd_DOWN
: u7 t: ]7 Y! Y - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;! w, ~1 {2 a; h
- GPIO_Init(GPIOB, &GPIO_InitStructure);// PB13/14/15-SCK,MISO,MOSI
: z, n' i1 ?/ t -
- I9 w& J" ]% F6 I. A - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 4 y5 t0 M: k8 g4 i2 `( `
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
! Y- c1 i3 r4 x+ z - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
) x% D) P; m4 r* I* v) G3 {' X - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
- a+ n+ t; A2 J - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_12; // RESRT and CS for enc28j60
( d' r- U* A8 h* @0 t8 c( } - GPIO_Init(GPIOB, &GPIO_InitStructure);. g4 }& l& g9 e, Q4 i
-
5 o) k. u( \8 F B - /*!< Configure enc28j60 interrupt pin in PullUp mode ********************/% ?0 I7 n# j, ^. A1 |2 P- Q& K
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;3 o" g, i9 ^; t' q) I) T
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
8 v4 o0 W) ?+ d8 N - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;: `0 A0 U0 u! e+ a- X
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- D% ~; U" U h& N- ~ - /*!< SPI2 pin configuration */2 p) i" C) p* n9 u) V+ x
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //INT' |$ D/ P! M" J4 r# j
- GPIO_Init(GPIOB, &GPIO_InitStructure);
s; s7 S; ~9 P5 j( s( [ - % y0 G5 f; _3 P! b
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI设置为双线双向全双工( }' D" G* O! J) c
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为主SPI
8 t: B+ [6 L4 } G - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//设置SPI的数据大小:SPI发送接收8位帧结构
4 H/ j' F5 Q! s7 d. U4 l+ u - SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//选择了串行时钟的稳态:时钟悬空高
) ~6 h' h& ~' D3 Z U - SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//数据捕获于第二个时钟沿
1 C; m( R" N! X& H# j - SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//(SPI_NSS_Soft)此时NSS引脚可以配置成普通GPIO去控制从设备1 J" ^2 s9 a8 y% d4 y8 h5 @! U
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//Fclk/2
9 o: x# v9 e' o- I* v0 u6 [ - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; /* Initialize the SPI_FirstBit member */
Q6 ]" ~" G. _! C - SPI_InitStructure.SPI_CRCPolynomial=7;
4 u# P3 A( M' S+ H* b% E3 S8 I, a - SPI_Init(SPI2, &SPI_InitStructure);
+ O4 e1 O- m1 ~* a u8 g+ a) f8 H - SPI_Cmd(SPI2, ENABLE);
. ?* _8 @6 I0 a* u - # o/ H! m8 P4 Y% Z, h+ S% Q* ?
- }
5 z# j6 H7 R* K
- L3 m0 q" \- Z7 i p: G- /*******************************************************************************
9 i$ V; d2 L V9 l I }+ S - * Function Name : SPI_ReadWriteByte
( k, h) Y4 u+ L$ D+ o - * Description : SPI读写一个字节(发送完成后返回本次通讯读取的数据)# g9 `' F- e. G, W$ M+ y7 X, f2 N
- * Input : unsigned char TxData
4 ?5 \, ?' E! n" |& [) H - * Output : None
9 w0 l& s. N. O/ t2 S. v - * Return : unsigned char RxData
" g8 L- q* k. d- S- [! R - *******************************************************************************/$ m+ V1 J A3 W' T% p7 S' A' t
- unsigned char SPI2_ReadWriteByte(unsigned char TxData)
/ ~; E1 W% x) W# U - {* [- g1 C$ N% M' ]2 h) {/ _) o
- unsigned char RxData = 0;
3 A3 J6 _' ]1 Q4 G' F - /* Wait till Transmit buffer is empty */
8 }6 _ ]9 b( y1 j$ j' {: t - while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);* K9 O% i% l1 ?
- /* Send A data */ + S+ E( J A- U9 K; O
- SPI_I2S_SendData(SPI2, TxData);
8 g0 u6 M$ W4 d1 i7 Y - // while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);
8 H# `; O# S+ {( ^5 M8 I' P - //等待数据接收$ E$ l5 g( v. N7 }5 | u
- while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
' `7 Y( d1 ?+ `# ]) ?4 [ - //取数据
# p* m0 _, N L8 e - RxData = SPI_I2S_ReceiveData(SPI2);4 X/ H0 G+ T- t k. Z' ]
- return (unsigned char)RxData;' ?& j6 c+ [% |! \, m. t) g( ]4 ?
- }
8 U- m6 d* Q) Z6 x& g
+ S) j) y, r1 y! E" @
8 b, K5 h- c) N! m6 K+ A
复制代码 " z9 C+ U$ M" M# Z
! D8 L1 J* q, P% a. B: }4 U |