f407vet6的,有问题,希望大家指证.. 说明: 1.需要我之前发的PORT类支持8 S( M9 m! C1 Z; n0 k: A 2.定义 USART(USART_TypeDef* usart,PORT *rx,PORT *tx,PORT *dir=0,int speed=9600);- @2 \8 s! \. v X- U 这里定义了usart后就知道用哪个tx,rx,是可以省略 rx,tx的,但我的代码没有处理,所以不能省略。 3.dir是用于485设备的输入输出方向。- ~- K$ P/ C8 x; K* Y0 p 4.这串口类是用USART_IT_IDLE状态来判断发送结束。 5.使用方法:( c9 i; s9 _4 o USART usart(USART1,.......); usart.callback=myCallback;回调程序,就是当数据发送完毕后,由哪个程序处理。 5.callother我的类定义了一个这个回调,当callback返回为false的情况下,会调用callother,我的目的是不管从哪个串口发送过来的数据,先由上层处理,如果上层没有处理,则由callother处理,我在callother处理的都是调试类的程序,也就是用户可以通过任意串口用于调试设备,设置参数什么的。 如果是0,就不处理。/ N: f, W: V, M' n! R3 W 6.enableCRC处理。 有这种情况,接收的数据不定长,非常多,开启这个会在接收的同时计算crc。' d: q3 v6 I0 M4 n) ^, w* B3 W 7.缓冲区4096个字节.8 {& ~/ c; [$ j! C8 S* |1 _3 O ==============.h文件3 B/ M. d7 z0 ^ #ifndef __USART__ #define __USART__- h1 R" t3 d- B7 | #include "stm32f4xx.h"# i6 M9 P3 Q( y Q #include "stm32f4xx_gpio.h") M7 ^1 w4 x* o9 I% D! x# x6 w5 L #include "stm32f4xx_rcc.h"8 g y: T3 U1 i0 ^5 W5 L( H #include "stm32f4xx_usart.h" #include "exint.h": [+ i4 P8 t& D u16 getModbusCRC(u8*,u16); class USART {$ a8 H! V1 ~- i- ` public:: _/ x; X9 J2 i2 r% S8 W# G USART(USART_TypeDef* usart,PORT *rx,PORT *tx,PORT *dir=0,int speed=9600);//硬串口+ A5 P" B3 @0 l0 F7 p0 Q USART(PORT *rx,PORT *tx,int);//模拟串口7 V! M1 y6 V. n- ~$ b! G void SendBuf(const u8 *buf,int len,bool=true);+ A9 A8 Q# `* n void SendByte(u8 ch); void SendString(const char * buf,bool=true);* q% n4 R( Y/ J) t void GetByte(u8 ch); bool (*callback)(u8* buf,u16 len);9 r, n% {& B& s bool (*callother)(USART*,u8* buf,u16 len); void setSpeed(u32); void setOutput(); void setInput(); void setEnabledCRC(bool);. A: b& ^& ]: n2 S0 d$ U5 |" ` u16 getCRC();2 h; q5 h* Y* S6 \ void sendStart(); void sendOver();2 W" ?3 z# ?9 h ) X* P8 ]) T" q2 X c! k0 e u8 BUF[4096]; private:& E, M+ t& q. E( Y9 t, z& J8 ]/ d bool isSoft;: B5 S: O( o/ h$ i# ?4 m USART_TypeDef* USARTx; uint16_t Tx;/ ~$ W" d8 ?) y) O4 f uint16_t Rx; u8 usartNO;- f: O" v! P" h- t3 O" W u32 BaudRate;+ s* _" `" j y bool enableCRC;4 i% k( ?$ \6 B2 b; p u16 _CRC;( |: q6 ^% F) [. I1 T0 y; q) j- Q& a ( Q* E, d0 s2 r5 v; C. s void setNo(USART_TypeDef *); void setBBR(u32);. \0 D- I( C7 l% F' S/ a" k void InitUSART(); friend void SysTick_Handler(void ); void usart_release_gpio_init(); void usart_nvic_config(); void usart_para_config();" Y" O; y2 a" ~: n6 R& d u16 reciveCount;! ~/ P0 q7 A. O& F; j* P ; k( ~+ p) h- t u16 BUFNO;5 R, R% @% Z4 g" }+ ~+ p uint64_t syscount;% L v; }4 { N: h& e; q 4 q) @& ]2 n) f: Q3 ? //ɭݾԮࠚԃք6 Z3 ~% }# J- o; \: E1 v$ T int Speed;+ M9 a% b9 m/ ?6 | PORT *DIR; PORT *RX,*TX; EXINT exint; }; #endif9 D. y. x& H; R' j8 i4 B( e ====================.cpp4 M, S5 z5 ]$ q9 C! |9 J4 g ) q! t9 d8 a8 l! k #include "usart.h"& @9 S' z: F `8 z #include "myfun.h" #include "exint.h" /*) [1 ?. Y# O0 v! _ USART1 Tx=A9,Rx=A10" `6 y: w- F% P) z0 L" C2 `: l! y" N USART2 Tx=A2,Rx=A3 UsART3 Tx=B10,Rx=B11 */ extern uint64_t SysCount; USART *_usart[6]; extern "C"{9 f% k/ U" Z2 m void USART1_IRQHandler() {; I1 D" X5 z% \; G% v; u7 Y _usart[0]->GetByte(0);! q' U6 R+ ]1 u' v6 q# H P5 {* g }2 T* \; x$ F8 G) L) j9 E& K void USART2_IRQHandler() { _usart[1]->GetByte(0);0 p% I1 h4 T6 P3 R+ C0 T } void USART3_IRQHandler() { _usart[2]->GetByte(0); }9 C! l9 D9 `4 a% a void UART4_IRQHandler() {; p% ?- y3 Z9 {4 D L _usart[3]->GetByte(0); }4 u" p' W. v$ G8 u9 N void UART5_IRQHandler() { _usart[4]->GetByte(0);! Z$ D0 O' D! G M* E }4 F- i2 n$ `/ R$ }, c5 j z# s/ f' J void USART6_IRQHandler() { _usart[5]->GetByte(0);5 g2 d. W. j8 H } } USART::USART(PORT *tx,PORT *rx,int b) {2 {$ [$ Z6 M/ r8 h- v //float s=(float)b;) v# w$ k/ k! ^( X( v. A BUFNO=0; isSoft=true;5 m6 ^. o8 N1 \8 { 8 k) N# _' @5 S! R8 } BaudRate=b;- p7 k1 M; u* ~" D Speed= 1000000 /b; //可能不准。 RX=rx; TX=tx;. m3 \, h# ]# w TX->setMode(GPIO_Mode_OUT);+ V# ~, T V8 x6 \ P; l TX->High(); RX->setMode(GPIO_Mode_IN); exint.Init(this,*RX,Speed);" g8 p7 n. m8 V% @$ M0 | }9 W3 z. d2 ~3 Y6 M- {. F void USART::setSpeed(u32 s) {, X) {) t4 i2 N) b if (isSoft) { BaudRate=s; Speed=1000000/s;+ w, w* E& X8 q } else {9 b8 J5 w2 J: ^ I) l. X setBBR(s);, l: h5 [7 x4 E } }0 I! C' G& O+ j z void USART::setEnabledCRC(bool c) { enableCRC=c;6 u9 |' ?4 z2 g; ~$ X _CRC=0;$ i8 @6 k8 C9 B } void USART::setBBR(u32 BaudRate) {3 k& t! D: J) U RCC_ClocksTypeDef RCC_ClocksStatus; uint32_t tmpreg = 0x00, apbclock = 0x00; uint32_t integerdivider = 0x00; uint32_t fractionaldivider = 0x00;5 j" z7 e. o' h. r, K /*---------------------------- USART BRR Configuration -----------------------*/6 I1 E5 _8 Z* T+ ^/ ]( H+ E5 m /* Configure the USART Baud Rate */" g n; L$ @# t+ B5 }" n& U RCC_GetClocksFreq(&RCC_ClocksStatus); if ((USARTx == USART1) || (USARTx == USART6))7 s5 K* Z, {' c. X* f' Z1 x {9 M9 [# w7 O; J) a2 L) q# j+ N apbclock = RCC_ClocksStatus.PCLK2_Frequency;0 d6 [1 ~2 v' y3 w! @" u }. }' n! ^/ W. P" ^. m. a else { apbclock = RCC_ClocksStatus.PCLK1_Frequency; } /* Determine the integer part */ if ((USARTx->CR1 & USART_CR1_OVER8) != 0)* {7 f! p, r( |( V7 r. F( @1 N {! F9 V1 s v3 P) x /* Integer part computing in case Oversampling mode is 8 Samples */5 H1 l7 R9 @1 G: F( @ E integerdivider = ((25 * apbclock) / (2 * BaudRate)); } else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ { /* Integer part computing in case Oversampling mode is 16 Samples */ integerdivider = ((25 * apbclock) / (4 * BaudRate)); " r; W( v) Z" U* _! T" { } tmpreg = (integerdivider / 100) << 4; /* Determine the fractional part */ fractionaldivider = integerdivider - (100 * (tmpreg >> 4));! H4 ?" r5 X0 ~+ R /* Implement the fractional part in the register */, L# o: z+ m) r if ((USARTx->CR1 & USART_CR1_OVER8) != 0) { tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); }$ G9 O' a$ l0 y else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ { tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);. n* g+ K) ?, k# M1 q } /* Write to USART BRR register */ USARTx->BRR = (uint16_t)tmpreg;( y; f; E H/ o }0 d+ N5 C" y _/ M/ L USART::USART(USART_TypeDef* u,PORT *tx,PORT *rx,PORT *dir,int speed) {& X! y# _0 i/ Y9 w0 M isSoft=false; BUFNO=0;/ K+ D1 N' G' h if (u==0) return; ' I% E2 K. @/ b% P, w/ _ USARTx=u;( e4 P9 F8 R3 n7 k4 |/ \6 x- _ if (u==USART1) usartNO=0; if (u==USART2) usartNO=1; if (u==USART3) usartNO=2;" i P7 F% j: j5 w+ A if (u==UART4) usartNO=3; if (u==UART5) usartNO=4; if (u==USART6) usartNO=5; BaudRate=speed; ) v3 j* q$ }* d, x+ Y+ o RX=rx;TX=tx;- G" Q0 t" {9 I' b* K4 @ DIR=dir;+ n1 F- g5 z! l' I2 k, r' l& l _usart[usartNO]=this;6 F+ f8 @; X/ r 6 s. i5 ` c d( L8 a callback=0; callother=0;! H' R7 Y% t3 \ k7 @& p3 P' A InitUSART();+ a. _8 K( I: ^, h3 G } void USART::setNo(USART_TypeDef* u) { - p1 ^7 @" y8 x6 L: ]6 Q7 j& K }& k( `% i, W4 k, W void USART::setOutput() { if (DIR!=0) DIR->High(); } void USART::setInput() { if (DIR!=0) DIR->Low(); } void USART::SendBuf(const u8 *buf,int len,bool autoIO){ int i; if (autoIO) setOutput(); for(i=0;i<len;i++) SendByte(buf[i]);& I0 p# L# ~5 |0 E' j' N if (autoIO) setInput(); }! e* z8 M" @1 t$ S( h1 D& h; T# ~9 m void USART::SendString(const char * buf,bool autoIO) { int i=0;% G0 Z1 ]/ E) Y0 X' \: R4 H. \4 X if (autoIO) setOutput();; k' I9 x1 @# ?3 }( k8 x0 U( o. D$ A while(buf[i]!=0) {SendByte(buf[i]);i++;} if (autoIO) setInput();& O, b- @8 b% d* D7 t+ F* `% m1 } }( M' A0 C: b- e) p void USART::SendByte(u8 ch) {# c1 i& u0 q' C if (isSoft) {' P- G: h+ H8 q. U* M# C# C; [ u8 i=8; TX->Low(); delay_us(Speed);, k# j9 w) L3 ~# T& c while(i--) { ch&0x01? TX->High():- }8 v4 X/ x, a) \+ y0 m. M TX->Low();' J/ y+ i& O2 | delay_us(Speed);+ r2 E O, ~/ K! y' f8 G+ O3 y ch>>=1; }5 ~& g# N4 D" A) \3 q TX->High();5 ?+ D4 |+ Y5 e6 V- w2 X5 d- Q delay_us(Speed); } else { while(RESET==USART_GetFlagStatus(USARTx,USART_FLAG_TXE));2 b5 u+ ^/ b. K8 [" M9 L6 o. b USART_SendData(USARTx,ch);! {' k9 ?: z0 r7 ], Z2 @6 ?4 R( n while(RESET==USART_GetFlagStatus(USARTx,USART_FLAG_TC));0 F) I2 j y( A7 S4 [5 @$ V, E, c 9 E7 K. f" y. H; h, t //USART_SendData(USARTx,ch);# ^ b% Z6 A- y k# W1 R5 e" | //while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET); } if (enableCRC) _CRC=getByteCRC(ch,_CRC);4 \1 F) ~9 _+ h: J' h! l }* P( J1 k& U9 v/ Z: ~ u16 USART::getCRC() {- J+ h% W* t0 q( h0 N! Y1 i* e return _CRC; }' b5 ^, \. R' E% ]7 z , {" \" l, ]( Y void USART::GetByte(u8 ret) {3 Y3 {# b F' G% ^ if (isSoft) {6 f6 [7 ~+ v2 X6 c6 r //暂时没处理 } else {+ f( |- Q8 n$ x% r4 l& I if (USART_GetITStatus(USARTx,USART_IT_RXNE)!=RESET) {" V4 T1 U1 C- n+ {4 q, E; } ret=USART_ReceiveData(USARTx); USART_ClearITPendingBit(USARTx,USART_IT_RXNE); $ A. [' ^7 F9 u/ }0 U BUF[BUFNO]=ret;$ ~7 ~ I2 j3 ?* s' J8 J( f, ~0 C BUFNO=(BUFNO+1)%4096;# c/ H, L* x, V$ W if (enableCRC) _CRC=getByteCRC(ret,_CRC); 6 V( s7 a6 k, L+ `$ G s# i } else { if (USART_GetITStatus(USARTx,USART_IT_IDLE)!=RESET) {+ _3 s, R, `0 y5 b int count=BUFNO;4 s! \" d6 x) E+ W. i, ~6 Y& o3 z USART_ClearFlag(USARTx,USART_IT_IDLE); A" O5 |( K: C U4 j& n! K8 `; v7 i BUFNO=0;0 N, X9 e; c% L* _1 F uint8_t clear;4 H9 b% Q8 O, r* G4 I clear=USARTx->SR; clear=USARTx->DR;$ i7 l. O+ g2 D! Z1 {( a9 d' ~ if (callback!=0 && count>0) if (!callback(BUF,count) && callother!=0) callother(this,BUF,count);/ ~7 B' X- g8 J5 u( z: P }0 `- k6 @) p) s }4 z O0 I$ A" \# C( ^ ' \6 H1 `" T+ Q7 N2 h/ V( m$ z2 J$ j( f 0 }1 K5 Q, v% J8 D- [/ B* ~& S } /* BUF[BUFNO]=ret;9 A1 N! c" l/ [4 s/ H; E. a, q, L BUFNO=(BUFNO+1)%4096; syscount=SysCount;$ r+ l8 _8 ~( ]. e 3 M$ A7 Q3 p# Z3 u9 C */ }3 d- s9 V5 j) e) e {4 S+ U9 y) Y/ y, E1 v void USART::InitUSART(){ # d! y, z' V2 W+ G' W RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<TX->ortNo,ENABLE);/ ]7 |, R4 m8 Z. s# q //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD,ENABLE); switch(usartNO) { case 0: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); break;( n: g1 [; C) }3 X; ~2 Y# ~/ T1 B2 U case 1:4 Y# B1 \7 l3 ]' v case 2: case 3:, B! c& s! c+ k* R case 4:4 F" @6 F* P) {7 q) E RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2<<(usartNO-1),ENABLE); break;/ I: J7 k. I% V' E. d case 5:3 s% W, ~: T: \3 l1 B RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE);6 O% Y. R2 U6 Z: k# o+ D break; }, a6 R) t; m6 l switch(usartNO) { case 0: case 1: case 2: GPIO_PinAFConfig(TX->GPIO,GPIO_PinSource0 + (TX->inNo/2) ,GPIO_AF_USART1);( \( v' `$ o* k0 D( I7 ]! V GPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX->inNo/2) ,GPIO_AF_USART1);) o0 S y" h6 }( F$ F break;3 e: H# p S. R# ^, G case 3: case 4:' p1 Z7 e4 V3 l4 u5 }7 A. y case 5: GPIO_PinAFConfig(TX->GPIO,GPIO_PinSource0 + (TX->inNo/2) ,GPIO_AF_UART4);0 L7 U' i1 K3 ?& O GPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX->inNo/2) ,GPIO_AF_UART4); break; ; [6 d1 ~. M! B# s }* s4 h2 L6 ]$ X5 M" @ " P4 m/ i. V. X% n% H 6 O" i# {4 K v /*& f! P! A' O& T! l$ p5 l RX.setMode(GPIO_Mode_AF);5 L. Q! |& B1 A; h. x RX.setType(GPIO_OType_PP); TX.setMode(GPIO_Mode_AF); TX.setType(GPIO_OType_PP);1 `* |" l3 U, W5 Y9 r* Y0 Z. s! y7 n */ 1 h. x0 Z/ S* m) a/ ~ m, ^7 ] Tx=TX->in; Rx=RX->in; ) @! q! _/ ^- o0 y+ g+ [ //3?Ⱥ??e¤??ȲȰy??1 w" G t' S) {: A usart_release_gpio_init(); . z1 c& j6 l% l //????¤??Ȳ?D?? usart_nvic_config();' J1 d4 h9 C5 l9 s, j //????¤??Ȳ?ªȺ?% r/ |+ \: d' u" \& D' L usart_para_config();( I& \4 U2 ] v8 r6 G9 S }& G! u2 a6 Y6 i- v$ { void USART::usart_release_gpio_init() {) f2 f2 o6 f( V3 x GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin=Tx;# Z# r W/ T G# O$ j GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;' Q2 N$ {. b; ]7 I1 \% y GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;4 ^0 L8 e Y( U % ~6 ?/ |* W) Z! G4 m: u GPIO_Init(TX->GPIO,&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin=Rx; /*GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;( w: B% \3 C' v6 w1 D1 X8 o+ D GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;# ?+ n. ~6 W% G2 J8 r/ T+ |- N1 \ GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; */+ `5 d) s& s& V# X+ M* }, ^% q% P0 n GPIO_Init(RX->GPIO,&GPIO_InitStruct); } void USART::usart_nvic_config() { NVIC_InitTypeDef NVIC_InitStruct;. G# E% _. ]' d, y; G- L- U NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 3 w7 z) ~/ ~( f. d switch(usartNO) { case 0:& z1 |/ W) l, r8 l' C$ J1 w& ^ case 1:! V: ]$ ~1 I8 [; S2 _8 _- l case 2:9 \0 Z. d0 i1 D) i4 R, f NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn + usartNO; ]0 y8 V7 @3 c0 w3 K% T break;" o) o9 `/ x# z9 c* o case 3:9 z$ R& P) F. U0 {. E6 u. Q6 M case 4:( `9 L3 }3 g" m6 V3 [ NVIC_InitStruct.NVIC_IRQChannel=UART4_IRQn + (usartNO-3);8 R' k9 J, ]6 C8 K0 ~9 B& ?. f break;, r4 G' G& i+ r case 5: NVIC_InitStruct.NVIC_IRQChannel=USART6_IRQn; break;2 [- a; Q& D* R- N! D6 q } ( o! m5 w; _3 s, h& z: @ . j& M) ~6 A e0 P( l2 j' p& Z NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3;3 t. O$ w# \- `! A NVIC_InitStruct.NVIC_IRQChannelSubPriority=3; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;& n* [+ J+ h! K- q O: |+ t# I NVIC_Init(&NVIC_InitStruct); } void USART::usart_para_config() { USART_InitTypeDef USART_InitStruct; / W b0 W% E0 f4 }: f USART_InitStruct.USART_BaudRate=BaudRate; USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode=USART_Mode_Rx | USART_Mode_Tx; USART_InitStruct.USART_Parity=USART_Parity_No; USART_InitStruct.USART_StopBits=USART_StopBits_1; USART_InitStruct.USART_WordLength=USART_WordLength_8b; K8 _: i0 ~9 a& W3 V USART_Init(USARTx,&USART_InitStruct);" f$ ^+ _4 X; Y& L+ y USART_ClockInitTypeDef usart_clock;: C! E4 I) B: I: f USART_ClockStructInit(&usart_clock);% ?3 g* B8 e4 j2 D/ F5 ?0 R1 k USART_ClockInit(USARTx,&usart_clock);1 A+ x9 s- [5 q" g1 S * U- K7 U& J h" ]$ w) H USART_ClearFlag(USARTx,USART_FLAG_IDLE);8 O3 T( k# Y1 D USART_ClearFlag(USARTx,USART_FLAG_RXNE); USART_ClearITPendingBit(USARTx,USART_IT_RXNE);& d! L- n9 W3 q/ p( M9 E USART_ClearFlag(USARTx,USART_FLAG_TC); T( j7 \; |* z" s USART_ITConfig(USARTx,USART_IT_IDLE,ENABLE); USART_ITConfig(USARTx,USART_IT_RXNE,ENABLE); //USART_ITConfig(USARTx,USART_IT_ORE,ENABLE);8 [ P$ |% e4 R+ ?9 M; M USART_Cmd(USARTx,ENABLE);, R" j$ r9 w. U. u8 r0 A7 R //USART_ITConfig(USARTx,USART_IT_TXE,ENABLE); }( G3 {+ N$ P$ q5 q9 N7 F |