|
f407vet6的, 需要其他我的封装类文件,如果有问题,请大家指证。 使用: SPI spi(SPI1);硬件模式, H. H4 B$ N. a$ r0 `1 e3 Q 或者 SPI spi(new PORT(GPIOA,9)......)软件模式 ) l1 E# i( Y8 \$ N, Z' _! B2 R" m spi.W(0xff) 写1 X, n0 r# G9 L/ h spi.R() 读8 q+ P) `; B: h% F) ]! l: c5 `& ^ ; Y% U! y# P) y' ?0 j5 C 3 l, r( S- }1 O& g1 H2 z- } ============spi.h! Y' }" N/ i* F) t* ~ #ifndef __MYSPI__ #define __MYSPI__/ z! S6 i* Q& v% P* l* S #include <base.h> 4 y: O5 Q3 K3 \: z) _- n' v class SPI {. {9 Z% ~" R# X, u8 i public:0 Z: M; k T6 d. [! l* F. ~' i SPI();3 V9 \9 L; R" R SPI(PORT *MOSI,PORT *MISO,PORT *SDCK,u8 mode=0,u16 sp=0); SPI(SPI_TypeDef* spino,u8 mode=0,u16 sp=SPI_BaudRatePrescaler_2,u8 remap=0);6 }# V& q% W5 b9 `0 o- ? void setMode(u8);5 p1 o& V5 }$ O- c% F' K void setSpeed(u16);9 M" U4 b# g" X$ A% @6 d8 N u8 W(u8=0xff); - E9 [! ?* c8 h5 [ u8 R();9 o3 k# \, k" K0 L0 c$ k. @ 1 f6 z0 k) F5 C u16 speed; SPI_InitTypeDef spiStruct; n7 Y/ ?: G! _: F' n5 J2 _ private : void InitSoft(PORT*,PORT*,PORT*,u16,u8);, d8 U4 _) B& p void InitHard(SPI_TypeDef*,u8,u8,u8 remap); . m& C% w% i; `1 l$ t u8 SRW(u8=0xff); u8 HRW(u8=0xff); u8 Mode; bool isSoft;) X7 E3 H& W3 l & P( C! P" Y3 `+ ^* ^ SPI_TypeDef* spi;3 S4 p/ {; K& n, l z& K PORT *MOSI,*MISO,*SDCK; uint32_t rccspi; uint8_t afspi; void Init(); }; #endif/ x' n0 r6 g" z* }! |9 O& z {# i* ^7 m I0 O* K =========spi.cpp # d: o7 H1 N- B9 ?, P4 ] #include "spi.h" #include "myfun.h" SPI::SPI(){}* R3 L, ]& }. K- N& ^, o SPI::SPI(PORT *MOSI,PORT *MISO,PORT *SDCK,u8 mode,u16 sp) {- w. `; N8 b. s InitSoft(MOSI,MISO,SDCK,sp,mode); } SPI::SPI(SPI_TypeDef* spino,u8 mode,u16 sp,u8 remap) {+ t2 c0 x" O# o# ]; W InitHard(spino,sp,mode,remap); }6 U+ t* b+ \; C. F6 ~ * u7 C3 r7 G5 v7 E# c! z- Z void SPI::InitSoft(PORT *_MOSI,PORT *_MISO,PORT *_sdck,u16 sp,u8 mode){6 O! N/ T6 C' [8 v& Q) D isSoft=true;1 E6 m& |2 x; a Mode=mode; speed=sp;5 o/ f# ^8 W _# Z MOSI=_MOSI,MISO=_MISO,SDCK=_sdck; //MISO->setMode(GPIO_Mode_IN_FLOATING); 7 a3 \: J4 n8 [1 K* J! w1 X MISO->setMode(GPIO_Mode_IN);* E! n% Z+ j( |1 ]3 \+ U: n# t MOSI->setMode(GPIO_Mode_OUT);, l) G: w- x/ ]- } SDCK->setMode(GPIO_Mode_OUT);9 l, T. y% H, v, P , h( I5 I/ P. _" b (mode & 0x2)? SDCK->High():SDCK->Low(); }+ H' |& L/ Z/ Q+ E * A. U d- O) t" J+ f) o void SPI::InitHard(SPI_TypeDef* spino,u8 sp,u8 mode,u8 remap) { isSoft=false; Mode=mode; speed=sp; spi=spino;& u& w: O- L" k# I0 n+ H ) e$ |8 M6 z! ` 7 |$ Z- W8 J7 w% g if (spi==SPI1) {1 O3 ?4 X6 A8 }1 e/ `+ n afspi=GPIO_AF_SPI1;) T3 ~6 H+ W# C7 k5 l$ [# ?1 ?) s rccspi=RCC_APB2Periph_SPI1; if (remap==0) { MOSI=new PORT(GPIOA,7,GPIO_Mode_AF); MISO=new PORT(GPIOA,6,GPIO_Mode_AF);; [# Q% l' G0 N* G/ P! S' q SDCK=new PORT(GPIOA,5,GPIO_Mode_AF); } else { MOSI=new PORT(GPIOB,5,GPIO_Mode_AF); MISO=new PORT(GPIOB,4,GPIO_Mode_AF); SDCK=new PORT(GPIOB,3,GPIO_Mode_AF); }/ t' v6 r$ e4 Q+ m6 X8 J6 v } if (spi==SPI2) { afspi=GPIO_AF_SPI2;$ y, N# S: q- p* H2 F; P3 G rccspi=RCC_APB1Periph_SPI2; if (remap==0) {2 N) `5 n1 @) k MOSI=new PORT(GPIOB,15,GPIO_Mode_AF);% W. l' k# r5 S f$ O* ^ MISO=new PORT(GPIOB,14,GPIO_Mode_AF); SDCK=new PORT(GPIOB,10,GPIO_Mode_AF);7 x/ q( b |, X( i! U }$ [, S5 i5 |: v1 a1 Z3 G if (remap==1) {* k# ~/ ~, T( [- H MOSI=new PORT(GPIOC,3,GPIO_Mode_AF);2 A% a8 Z) J+ U8 ~5 R. h& c MISO=new PORT(GPIOC,2,GPIO_Mode_AF); SDCK=new PORT(GPIOB,13,GPIO_Mode_AF);; r7 s5 l3 [+ @8 a% C2 M# {& t }( i4 s# P$ p a3 [1 }4 W2 t. C( w! A2 @ if (remap==2) {& F2 _$ D" z! J" v* ?/ K2 G& ^" M MOSI=new PORT(GPIOI,3,GPIO_Mode_AF); MISO=new PORT(GPIOI,2,GPIO_Mode_AF);* d: D I9 |5 s6 F5 P SDCK=new PORT(GPIOD,3,GPIO_Mode_AF);0 r/ u) s; j0 V6 ] }; X' l5 g. s3 V1 X* B) m8 L }! d" T! Q% X* `1 V: L ) `$ {# _$ W+ v. V) D8 Q if (spi==SPI3) { afspi=GPIO_AF_SPI3;0 |) J' J+ d0 G( k/ V rccspi=RCC_APB1Periph_SPI3; if (remap==0) {8 u, {7 W7 r5 ]4 n+ V MOSI=new PORT(GPIOB,5,GPIO_Mode_AF);: X& B: |) X$ s: p MISO=new PORT(GPIOB,4,GPIO_Mode_AF); SDCK=new PORT(GPIOB,3,GPIO_Mode_AF); } if (remap==1) { MOSI=new PORT(GPIOC,12,GPIO_Mode_AF);; [6 [! a7 x9 V" N MISO=new PORT(GPIOC,11,GPIO_Mode_AF);8 y. \# Y# J4 G/ z# S SDCK=new PORT(GPIOC,10,GPIO_Mode_AF); } } if (spi==SPI4) { afspi=GPIO_AF_SPI4; rccspi=RCC_APB2Periph_SPI4; if (remap==0) { MOSI=new PORT(GPIOE,6,GPIO_Mode_AF);* R/ t4 o, N4 s. F- H' c o# c8 y MISO=new PORT(GPIOE,7,GPIO_Mode_AF);( ?7 a$ N0 b4 _( B! P SDCK=new PORT(GPIOE,2,GPIO_Mode_AF); }3 x; ]; g7 Q1 i6 G6 A) Z if (remap==1) {# u5 L. \. Z5 F3 \) ~3 q) B* h/ v% S, T' g MOSI=new PORT(GPIOE,14,GPIO_Mode_AF); MISO=new PORT(GPIOE,13,GPIO_Mode_AF);0 b, _3 W2 l/ ]7 f+ O+ X SDCK=new PORT(GPIOE,12,GPIO_Mode_AF); } } if (spi==SPI5) {; x" {/ L# H9 \( T- V- K afspi=GPIO_AF_SPI5; rccspi=RCC_APB2Periph_SPI5;8 }" `. v9 m! {! Q6 m, A% L; M% r0 Y' I if (remap==0) {( ~# Y- U M7 z) h. C! M7 P MOSI=new PORT(GPIOF,9,GPIO_Mode_AF); MISO=new PORT(GPIOF,8,GPIO_Mode_AF);" e- L8 m2 i: p SDCK=new PORT(GPIOF,7,GPIO_Mode_AF);6 C& G8 m0 h" a0 ~- H+ r }1 [$ x1 a a9 K9 C9 Z9 D if (remap==1) {! I4 C/ Y1 E5 u/ }2 b MOSI=new PORT(GPIOF,11,GPIO_Mode_AF); MISO=new PORT(GPIOH,7,GPIO_Mode_AF); SDCK=new PORT(GPIOH,6,GPIO_Mode_AF); } }! n% [: i' O1 |! p if (spi==SPI6) { afspi=GPIO_AF_SPI6; rccspi=RCC_APB2Periph_SPI6;8 u, r! _ e8 t d1 F MOSI=new PORT(GPIOG,14,GPIO_Mode_AF); MISO=new PORT(GPIOG,12,GPIO_Mode_AF); SDCK=new PORT(GPIOG,13,GPIO_Mode_AF); }% ?7 W3 ^# h% ~ Init();3 F; M1 ?$ G8 ~$ r } % H7 c6 n( b( h! c7 d( @. j void SPI::Init()" d2 e$ w, E2 @ r { SPI_InitTypeDef SPI_InitStructure;8 O1 b8 ^ ]; @3 o" X( ^+ u ; i0 M2 R% K9 G) ?% i1 J3 h6 ?# \0 _ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<SDCK->PortNo, ENABLE);//使能GPIOA时钟! }$ K3 r: O) q+ I5 V! u; F5 R RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<MOSI->PortNo, ENABLE);//使能GPIOA时钟- K$ W t- T8 H, ]3 p6 A RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<MISO->PortNo, ENABLE);//使能GPIOA时钟 , X' f4 ^; v0 {# H b 0 F- u- C. S4 C/ W" h' q* r5 k if (spi==SPI2 || spi==SPI3) { RCC_APB1PeriphClockCmd(rccspi, ENABLE);//使能SPI23时钟0 K% ?! r. W4 ]: h9 Q } else { RCC_APB2PeriphClockCmd(rccspi, ENABLE);//使能SPI1时钟 }* O: ~( r- F; p, u O GPIO_PinAFConfig(SDCK->GPIO,GPIO_PinSource0 +(SDCK->PinNo/2),afspi); //PB3复用为 SPI1 GPIO_PinAFConfig(MOSI->GPIO,GPIO_PinSource0+(MOSI->PinNo/2),afspi); //PB4复用为 SPI1 GPIO_PinAFConfig(MISO->GPIO,GPIO_PinSource0+(MISO->PinNo/2),afspi); //PB5复用为 SPI1 //这里只针对SPI口初始化6 R) _" D; ^+ ^% E$ [ //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);//复位SPI1: P( a$ r2 t2 I: q. b. p //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);//停止复位SPI1% K* T" F& c! m7 P + h# S9 O+ C$ l$ h3 w SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工+ U1 L- a& a5 i1 G& ]# }/ j0 g8 c/ t SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI' t7 I( z$ g/ A0 P SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL =Mode &0x2;// SPI_CPOL_High; //串行同步时钟的空闲状态为高电平6 t6 B# K5 F4 X' |' A2 W SPI_InitStructure.SPI_CPHA =Mode &0x1 ;// SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样$ ^2 c0 V/ @& U) c SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制, _7 H& q. r0 | f6 }* D SPI_InitStructure.SPI_BaudRatePrescaler =speed;// SPI_BaudRatePrescaler_4; //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 e7 P. @# Q' m) O+ i& n- | SPI_Init(spi, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器5 x$ V% T( x+ Q* d! j% d ! O0 X9 i2 q5 x' E8 e' k2 b3 {' W SPI_Cmd(spi, ENABLE); //使能SPI外设$ u$ v# t/ O6 S$ B1 { _. H 0 \+ a' G+ F) X: U) f. h* @ } & |5 i4 Y2 V9 S! K, O9 y u8 SPI::W(u8 d) { return isSoft?SRW(d):HRW(d);5 b! [8 B' D8 b& R } 2 D/ t8 U6 [1 i) x0 A u8 SPI::R() {% {! \4 ^/ M( c. K0 W) U3 r return isSoft?SRW():HRW();9 K7 @. h) o; l/ k- ^6 ~" \ } u8 SPI::HRW(u8 d) {+ D2 b- z! I4 w$ S , j3 G$ o% J& h! P: C u8 retry=0; ' h+ _" k4 l2 x1 ?4 Q; K while (SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位+ [. f* ]$ ]7 Y' [+ U, y" t {, H* X5 z* ^$ f; @2 @ retry++; if(retry>200)return 0; } 2 G1 ?9 Y, R3 M5 o SPI_I2S_SendData(spi, d); //通过外设SPIx发送一个数据: o6 _3 f% V9 _0 n: p9 r+ ? retry=0;3 o& r2 i8 U7 ^1 \0 t# e" k, k ( M* v& M, F% D. T4 o while (SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_RXNE) == RESET)//检查指定的SPI标志位设置与否:接受缓存非空标志位 {# f ^2 U+ q6 k; q7 I' N3 K7 z retry++; if(retry>200)return 0;4 A q% \; M+ P4 F } 7 S+ g, v9 L% Y* V return SPI_I2S_ReceiveData(spi); //返回通过SPIx最近接收的数据 } void SPI::setMode(u8 mode) { if (isSoft) Mode=mode; else {7 K" Y: a4 u0 U# `" N& Z8 r- g u16 r=spi->CR1 & 0xfffc;; \: Y6 q$ J- Q8 I spi->CR1=r | mode; }# v4 R& U2 u m. i } : }8 g5 O% ]& s. c; C, k8 r void SPI::setSpeed(u16 sp) {+ w0 i& k; A' c* A1 y* T if (isSoft) { speed=sp; }else{ spi->CR1 &=0xffc7;% a l# f: t8 l7 ~* R spi->CR1 |=sp; L3 q2 _, N9 O7 k$ {& B SPI_Cmd(spi,ENABLE); } }. |- i8 ?- e1 h9 k u8 SPI::SRW(u8 d) {" X. l x) ]7 E ~ u8 i=8; u8 r=0; switch(Mode) { case 0: //CPOL=0 ,CPHA=0 while(i--) {% ]( `8 F4 v$ v* `3 N r<<=1;" [& I! Z( @( c if (MISO->Read()) r++; (d & 0x80)? MOSI->High():MOSI->Low();4 o9 P" f) d! z. U% p' Y% v* {8 O SDCK->High(); delay_nop(speed); d<<=1;* G% J# u/ f2 c6 Z X+ h7 E SDCK->Low();. o$ A3 n& E r+ H delay_nop(speed);+ G/ n6 {6 N& `$ z+ n2 {" R+ w }/ F/ _- f1 E$ m% {- Q break;;/ {: E6 k' Z2 h9 C3 `# A4 x) | case 2://CPOL=1,CPHA=02 N' O" Y; N2 s while(i--) {- }1 c5 O' g8 n r<<=1;: h: I; M. O2 R9 a0 d if (MISO->Read()) r++; (d & 0x80) ?MOSI->High():MOSI->Low();* A8 {4 T. v( \, q' y" w! S SDCK->Low();! o: P) ^7 \* ^: Q0 w d<<=1;3 s( D! v' t& i2 f5 t. X" m SDCK->High(); } break; case 1: //CPOL=0,CPHA=1: }. O6 y$ N' b" h while(i--) {$ r7 ?% K5 q4 B1 } SDCK->High(); r<<=1;& @) X( _3 \4 ~# Y, l, t( C5 K' d! I if (MISO->Read()) r++; (d & 0x80) ?MOSI->High():MOSI->Low(); SDCK->Low();, H) g k; ~+ | d<<=1; } break;6 g4 m' n0 T9 f- P0 L8 a) E) x6 x. o case 3: //CPOL=1,CPHA=1 while(i--) { r<<=1; (d & 0x80)?MOSI->High():MOSI->Low();+ d5 |5 `" E: y$ h delay_nop(speed); SDCK->Low(); delay_nop(speed);# \* X9 O5 g4 h! [ SDCK->High(); if (MISO->Read()) r++;2 o" @( |3 C0 m: B+ P" z% { d<<=1; } break; } return r;1 ]8 g) b- P- B0 i; C3 I- a }) Z# `& ~2 |. Y9 v4 n |
| 学习了,用类和对象操作 |
| 你的SPI名称空间怎么不发出来啊 |
| 我是复制的代码,没有设置名称空间。 |
微信公众号
手机版