f407vet6的,有问题,希望大家指证.. 说明: 1.需要我之前发的PORT类支持 2.定义 USART(USART_TypeDef* usart,PORT *rx,PORT *tx,PORT *dir=0,int speed=9600); 这里定义了usart后就知道用哪个tx,rx,是可以省略 rx,tx的,但我的代码没有处理,所以不能省略。 M U, ~% n( X1 R" A5 j+ W, Y 3.dir是用于485设备的输入输出方向。 R: Z( k. | S 4.这串口类是用USART_IT_IDLE状态来判断发送结束。1 s. F0 S) }8 W 5.使用方法: USART usart(USART1,.......);" }# h% B3 w, y) \# g( N usart.callback=myCallback;回调程序,就是当数据发送完毕后,由哪个程序处理。! B' A9 l C0 v3 c 5.callother我的类定义了一个这个回调,当callback返回为false的情况下,会调用callother,我的目的是不管从哪个串口发送过来的数据,先由上层处理,如果上层没有处理,则由callother处理,我在callother处理的都是调试类的程序,也就是用户可以通过任意串口用于调试设备,设置参数什么的。& ]9 {1 s8 E% S% J; d9 I# } 如果是0,就不处理。% l2 ?5 H) E" o/ C5 [4 ` 6.enableCRC处理。' Q; i3 _" x% f K" r7 d. p 有这种情况,接收的数据不定长,非常多,开启这个会在接收的同时计算crc。& ~8 c9 `# O: g 7.缓冲区4096个字节., K0 F; E4 A; J; O; b7 L% T% S ==============.h文件7 T2 y, G2 T! H3 f, l #ifndef __USART__ #define __USART__ #include "stm32f4xx.h" #include "stm32f4xx_gpio.h"% b% M3 C! p+ Z #include "stm32f4xx_rcc.h" #include "stm32f4xx_usart.h" #include "exint.h" ; }7 D% _) S4 W! M7 R u16 getModbusCRC(u8*,u16);/ R) s! p) m- {0 G7 I/ l+ w' Q5 P class USART {* H9 S' g% W* w b0 J public: USART(USART_TypeDef* usart,PORT *rx,PORT *tx,PORT *dir=0,int speed=9600);//硬串口 USART(PORT *rx,PORT *tx,int);//模拟串口: o2 V5 e2 A* t void SendBuf(const u8 *buf,int len,bool=true); void SendByte(u8 ch); void SendString(const char * buf,bool=true); void GetByte(u8 ch); bool (*callback)(u8* buf,u16 len); bool (*callother)(USART*,u8* buf,u16 len);! X) p3 ~6 t& @: F, x void setSpeed(u32);0 N U. P8 Z8 i9 C( n- O! q; s1 ~' _ void setOutput();* C2 q3 l% f P( W5 v2 y( {; R void setInput(); void setEnabledCRC(bool); u16 getCRC(); void sendStart();% `, h. z+ a. a" n( Y. T# s void sendOver();5 u$ \* U8 Y7 T8 V% _ o1 x u8 BUF[4096];: B8 z8 o$ |* ?5 A$ J0 o. G6 \& q private:7 e+ P; r0 F9 v bool isSoft;6 A- W/ W! l M USART_TypeDef* USARTx;) S% C0 Q9 w; B uint16_t Tx;+ M9 N* u* y4 P# G. j }" \ uint16_t Rx;: i/ E+ X, h" _3 Q7 k u8 usartNO; u32 BaudRate; bool enableCRC; u16 _CRC;& g! {6 _- i/ a6 r 1 W. `+ j5 w8 q6 s/ m void setNo(USART_TypeDef *);6 X0 g9 U# Z+ D( T9 {2 u' @: Q1 h1 N void setBBR(u32); void InitUSART();8 c; ]) z" e) S0 |5 [0 R+ S friend void SysTick_Handler(void ); void usart_release_gpio_init(); void usart_nvic_config(); void usart_para_config();- t/ z8 m7 r5 b0 d5 I' e- N. v% e, T u16 reciveCount; u16 BUFNO; uint64_t syscount; //ɭݾԮࠚԃք0 p% l6 U; V, y) { int Speed;" C1 ?4 M$ ^; c2 e PORT *DIR; PORT *RX,*TX; EXINT exint;3 `$ t# e! B& {" z8 a+ @6 f };3 I" [8 U0 L: H: N2 g: { #endif, W! e: S& I, U2 E A& E: Q/ [ ====================.cpp #include "usart.h"1 d; j* R0 `- g8 Y. U #include "myfun.h" #include "exint.h" /* Q4 F" z7 q0 b( p+ _- U USART1 Tx=A9,Rx=A10$ l" h$ \+ o1 Y4 J5 }1 D1 z USART2 Tx=A2,Rx=A3 UsART3 Tx=B10,Rx=B11 */' G {5 q+ \$ i% {# K extern uint64_t SysCount;$ m+ A/ k- b, t$ o1 A USART *_usart[6];3 E& l. q+ i3 \ extern "C"{$ N4 l2 i3 G3 K) A, b5 m void USART1_IRQHandler() { _usart[0]->GetByte(0); }3 w6 A5 q$ X( O1 O& [- l void USART2_IRQHandler() { }* x6 o E% \' p _usart[1]->GetByte(0);5 c8 ~6 ` Z J1 [( p& d } void USART3_IRQHandler() {8 ?+ E5 I+ H6 B' ^8 ~6 N: o: ] _usart[2]->GetByte(0);( R5 E# L/ h( z u }- B, i) V. z( U) t$ k! R/ _' N6 w void UART4_IRQHandler() { _usart[3]->GetByte(0); }+ D* Y4 K3 @5 y/ e3 G, O void UART5_IRQHandler() { _usart[4]->GetByte(0); } void USART6_IRQHandler() {3 E2 p8 z- e' Q8 N: g( b- t8 e/ o7 f; i4 I _usart[5]->GetByte(0); }" O2 o( j$ Z, O& T }+ h. N9 K! C6 W; a( B) a USART::USART(PORT *tx,PORT *rx,int b) { //float s=(float)b;% X: U0 N4 s4 d, G BUFNO=0; isSoft=true; 7 h& Y* t+ Q4 [% U BaudRate=b;' v# x1 D# o3 R3 ? c, Q- t: r0 n E3 O 8 l; \ z+ O; C: ]5 |; S( j Speed= 1000000 /b; //可能不准。& \9 Z& {% E, y& f! F( Z+ } A RX=rx; TX=tx;, j! L; j7 ]; w5 Z) c- [ : u% @8 @2 J6 F1 c" Z TX->setMode(GPIO_Mode_OUT); TX->High(); RX->setMode(GPIO_Mode_IN); exint.Init(this,*RX,Speed); } void USART::setSpeed(u32 s) {# @' h/ T7 C) f* o R6 P7 B if (isSoft) { BaudRate=s;: d+ V* L9 O- c2 d, J: `% u Speed=1000000/s; } else { setBBR(s);# k* ]" A# p$ T! F: D0 y } }/ P, x; v2 A5 D7 ~1 u8 Q void USART::setEnabledCRC(bool c) {5 K3 T; D, w5 |% b enableCRC=c; _CRC=0;7 W, {0 ]9 G5 D- M n$ C% V7 l } void USART::setBBR(u32 BaudRate) { RCC_ClocksTypeDef RCC_ClocksStatus;. J4 F( n, i" O# W0 {9 e+ s. } uint32_t tmpreg = 0x00, apbclock = 0x00;- v3 m& g- c& W uint32_t integerdivider = 0x00; uint32_t fractionaldivider = 0x00;) B5 K1 t) {5 l; B% f /*---------------------------- USART BRR Configuration -----------------------*/ /* Configure the USART Baud Rate */ RCC_GetClocksFreq(&RCC_ClocksStatus);2 H2 G/ z0 t1 `' L x- k if ((USARTx == USART1) || (USARTx == USART6))" ^+ J- u# i, T { apbclock = RCC_ClocksStatus.PCLK2_Frequency; } else {" p4 O2 Y& Y! c: \* @ apbclock = RCC_ClocksStatus.PCLK1_Frequency;$ r' j. D2 j2 U* _+ a, F M } ' g U4 O' t5 n* @! x /* Determine the integer part */: {; e4 e3 E& e2 J% Z5 J2 U if ((USARTx->CR1 & USART_CR1_OVER8) != 0); Y8 l. W- o6 M8 Z0 v! n" t- L {1 Q3 ]9 ]7 _! i2 R) C /* Integer part computing in case Oversampling mode is 8 Samples */, H1 z2 R% D4 d0 I$ v integerdivider = ((25 * apbclock) / (2 * BaudRate)); }/ Q+ N \1 M$ z) K0 N5 H+ N else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ { /* Integer part computing in case Oversampling mode is 16 Samples */8 Q3 }: O( t& f integerdivider = ((25 * apbclock) / (4 * BaudRate)); 1 l+ V+ K2 v {3 z. E) H } tmpreg = (integerdivider / 100) << 4; /* Determine the fractional part */ fractionaldivider = integerdivider - (100 * (tmpreg >> 4));; W+ t+ K9 Y9 Y0 i/ s; Z/ j" L /* Implement the fractional part in the register */$ F3 K- p& Q4 t7 b8 I, B: }# J if ((USARTx->CR1 & USART_CR1_OVER8) != 0)/ u1 P) }! s' O) J1 u% ? { tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);) L4 ?8 t) \. @/ ~8 s- ?9 \* i } a" C( p3 v0 K) R" p8 g else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */# I g4 @ o) |4 P: n: y" ? { tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F); } 9 b6 L& E. |& c I: ?! c/ M /* Write to USART BRR register */ USARTx->BRR = (uint16_t)tmpreg;( f) ~( ?) @& `; Z }7 F# Q' p& B: e USART::USART(USART_TypeDef* u,PORT *tx,PORT *rx,PORT *dir,int speed) { isSoft=false;2 R P6 X( S* H' Q BUFNO=0;/ o* a- a% B" E8 }1 z1 r' ? if (u==0) return; USARTx=u; if (u==USART1) usartNO=0; if (u==USART2) usartNO=1;* |' K# Q, e2 M J: j if (u==USART3) usartNO=2;, @6 G0 G* E2 `, ^; t9 E' } if (u==UART4) usartNO=3; if (u==UART5) usartNO=4;9 P5 G! E% L9 {- u- C } if (u==USART6) usartNO=5; BaudRate=speed; * M) R! O/ i. ?8 Z% @! v8 A. q RX=rx;TX=tx; DIR=dir; & i7 \5 J7 [9 m _usart[usartNO]=this; callback=0;+ W c |, A- K% m( w' f1 E" R* _# W6 ` callother=0;; f; r' C% h5 p9 G& l InitUSART();# e) y4 H0 K! R } void USART::setNo(USART_TypeDef* u) { } void USART::setOutput() { if (DIR!=0) DIR->High(); } void USART::setInput() {2 }- i5 \8 B$ X- Y: t4 b if (DIR!=0) DIR->Low(); } void USART::SendBuf(const u8 *buf,int len,bool autoIO){0 x3 f5 d% R9 F& y4 y% F int i; if (autoIO) setOutput(); for(i=0;i<len;i++) SendByte(buf[i]);1 M9 O' A, C \$ K if (autoIO) setInput(); } void USART::SendString(const char * buf,bool autoIO) {: \. ^3 A& }6 N- Y# P* [ int i=0; if (autoIO) setOutput(); while(buf[i]!=0) {SendByte(buf[i]);i++;} if (autoIO) setInput();2 O. c. a& Q4 Q- w3 W } void USART::SendByte(u8 ch) {+ g! G; Q" Y7 b4 B; s) X" Q if (isSoft) {% \* q ^6 L+ z8 H+ X% u% X" e" i u8 i=8;, ]) S, i4 J4 {, m7 z TX->Low();' @5 O4 J4 X! b; F delay_us(Speed);0 ^9 V; _' X5 U; t, U while(i--) {7 ^4 D& N- v# W8 k; ~ ch&0x01?+ c3 l0 \; B) j0 D" K TX->High(): TX->Low(); delay_us(Speed);3 }% c# i+ t# R0 Q- K+ p+ }% U ch>>=1;4 N1 ?3 s d+ ?# [; w J } TX->High(); delay_us(Speed);* i g8 K$ a- l( p( `% X } else {/ g+ E1 ^9 J: T4 t' W6 Q while(RESET==USART_GetFlagStatus(USARTx,USART_FLAG_TXE)); USART_SendData(USARTx,ch); while(RESET==USART_GetFlagStatus(USARTx,USART_FLAG_TC)); //USART_SendData(USARTx,ch); //while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET); } if (enableCRC) _CRC=getByteCRC(ch,_CRC); }5 n) u1 r) p r; e2 X' h0 m8 w" j u16 USART::getCRC() { return _CRC;) j X( ~7 O, z8 n } . N8 \& W. t" K9 P# @' V 0 S9 K) ^1 `5 F7 q z, ?; _ c void USART::GetByte(u8 ret) {8 r7 P9 N0 L# f( x' n if (isSoft) { //暂时没处理 } else {+ f! B& k0 Z. b7 t8 m) i8 K if (USART_GetITStatus(USARTx,USART_IT_RXNE)!=RESET) { ret=USART_ReceiveData(USARTx);2 M) s- \7 B% R( R! g d$ D/ w' @- j USART_ClearITPendingBit(USARTx,USART_IT_RXNE); BUF[BUFNO]=ret; BUFNO=(BUFNO+1)%4096;; j: Z/ I5 i4 b. w/ G if (enableCRC) _CRC=getByteCRC(ret,_CRC); } else { if (USART_GetITStatus(USARTx,USART_IT_IDLE)!=RESET) { int count=BUFNO; USART_ClearFlag(USARTx,USART_IT_IDLE);2 q6 o2 F1 o. _ BUFNO=0; uint8_t clear;8 L/ G2 Q: Z, f1 p' |; R+ b: v clear=USARTx->SR;& I% [" }3 {' v! ?7 |% \$ n3 R clear=USARTx->DR;3 x7 E8 R3 g, o" q( Y( f! z if (callback!=0 && count>0) ! Z1 j) j4 P) D! w if (!callback(BUF,count) && callother!=0) callother(this,BUF,count);% j5 Q+ C- y4 Z2 E/ D }9 \. t/ Y+ _ v0 S }3 l- ]9 w0 C. o/ G8 z1 I }8 w" X, {4 S1 N0 S3 b9 } /* m: c# ?; m u3 O! G- h0 Z BUF[BUFNO]=ret; BUFNO=(BUFNO+1)%4096; syscount=SysCount; */ } void USART::InitUSART(){+ u+ v3 ~- l. {' P- X : o7 |4 `4 _, ?. E7 [" K RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<TX->ortNo,ENABLE); //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD,ENABLE);" \6 b* j& Z; U0 x% t- W" w 8 I6 X. |4 B$ @8 i" ~( @ switch(usartNO) { case 0:/ C+ r+ c4 f8 B0 G& U# O RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); break; case 1: case 2: case 3:% Q. A, Y! x. Z9 Z# N+ `; ^ case 4: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2<<(usartNO-1),ENABLE); break; case 5:! g. Q; T% b+ E3 Q0 ` RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE); break; }! ~" G0 I- J" a 6 U* o' W. A W: O- [! F( M0 f switch(usartNO) {* \) N0 J2 E8 T. M3 t# m' U case 0: case 1: case 2: GPIO_PinAFConfig(TX->GPIO,GPIO_PinSource0 + (TX->inNo/2) ,GPIO_AF_USART1); GPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX->inNo/2) ,GPIO_AF_USART1); break;- n3 i5 J* u9 @& ?" f/ ~+ ]. h! q case 3:) }- b' j6 i) C. M; M: M1 R case 4:2 @& z0 S. I5 `& j case 5: GPIO_PinAFConfig(TX->GPIO,GPIO_PinSource0 + (TX->inNo/2) ,GPIO_AF_UART4);; K0 `9 X7 N( u5 I GPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX->inNo/2) ,GPIO_AF_UART4);! W* j. t- i" B G3 ^, `9 _ break; } 7 a; G1 F4 U# |6 K; B /* RX.setMode(GPIO_Mode_AF);7 q$ b7 O4 H( C" {3 a- Z7 v RX.setType(GPIO_OType_PP); TX.setMode(GPIO_Mode_AF);1 X1 q' I: k% h# _3 W7 S6 g TX.setType(GPIO_OType_PP); */# ~! `( f+ E+ g2 @+ g& x% ]3 d2 B; ^ 8 _( s$ {( |0 o L8 g) K Tx=TX->in; Rx=RX->in;* n5 m) N# C$ ?. J ' n# m/ A1 k* u1 `6 v; k. a //3?Ⱥ??e¤??ȲȰy?? usart_release_gpio_init(); 8 c+ I3 |; n1 n4 M4 B0 h) b/ A //????¤??Ȳ?D?? usart_nvic_config();7 \9 b. x+ C, T( u& x //????¤??Ȳ?ªȺ? usart_para_config();6 K3 Y/ {7 x2 T } void USART::usart_release_gpio_init() {! t! s5 A: q- T2 h# U0 @% P* b GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin=Tx;. k$ t3 o7 v* `3 n: \2 _2 G GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;, \. h# \4 ?0 z8 }% u' D5 r9 L GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;: I5 l1 v; k! s/ [2 e9 i% s GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;' j; g- f; ?! i0 F: p # p8 J( b: _4 Q7 p! a3 M! p3 B4 _4 P GPIO_Init(TX->GPIO,&GPIO_InitStruct); & Z4 Q% W: j& [6 ^" U! w GPIO_InitStruct.GPIO_Pin=Rx;7 e, s" c5 D- e; Q+ Q% f1 j4 E /*GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;. h2 l# m' C$ P- X2 t GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; */ & S* s& e2 F2 r* e GPIO_Init(RX->GPIO,&GPIO_InitStruct); } void USART::usart_nvic_config() { NVIC_InitTypeDef NVIC_InitStruct;) G1 ~7 Z' G+ P& Z NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); * R4 o) _# M$ w3 C switch(usartNO) {2 u5 Z4 G7 B4 X7 o9 | case 0: case 1: case 2:3 c* R$ L, G3 e1 X NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn + usartNO; break; case 3: case 4: NVIC_InitStruct.NVIC_IRQChannel=UART4_IRQn + (usartNO-3); break; case 5:/ z2 ` k7 X1 k8 s+ n* P* F6 G NVIC_InitStruct.NVIC_IRQChannel=USART6_IRQn; break;0 L* u7 `$ p8 c; X; h: x/ P; e } ) q0 Q m; k+ A* R0 M- S1 G$ C ! R- m1 A+ P* V# n NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3; NVIC_InitStruct.NVIC_IRQChannelSubPriority=3; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStruct); }6 R: K; c4 ~' \8 a void USART::usart_para_config() {( Q1 F9 S' X) h% v3 w) f1 r# n) d$ ~; l USART_InitTypeDef USART_InitStruct; ' _. e- a( J9 ? USART_InitStruct.USART_BaudRate=BaudRate; USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;9 Z! H+ ^% E# K; \% f USART_InitStruct.USART_Parity=USART_Parity_No;; v A- ~4 a5 l8 j3 \4 j USART_InitStruct.USART_StopBits=USART_StopBits_1;! j1 `* U. l& d! \, w' u USART_InitStruct.USART_WordLength=USART_WordLength_8b; USART_Init(USARTx,&USART_InitStruct); USART_ClockInitTypeDef usart_clock; USART_ClockStructInit(&usart_clock);6 q2 b+ n& F% ?6 { USART_ClockInit(USARTx,&usart_clock); USART_ClearFlag(USARTx,USART_FLAG_IDLE);+ J: T! H6 D$ g# J) t6 Q; p) W" f USART_ClearFlag(USARTx,USART_FLAG_RXNE);* x8 E0 |8 ]% R" } USART_ClearITPendingBit(USARTx,USART_IT_RXNE);: t: `4 O) S7 u USART_ClearFlag(USARTx,USART_FLAG_TC);: T% s# r. a2 E0 |: u+ D P USART_ITConfig(USARTx,USART_IT_IDLE,ENABLE); USART_ITConfig(USARTx,USART_IT_RXNE,ENABLE);" G/ I* P+ |* l7 F //USART_ITConfig(USARTx,USART_IT_ORE,ENABLE); USART_Cmd(USARTx,ENABLE);" p1 b, b+ S. x5 J4 P( ^ //USART_ITConfig(USARTx,USART_IT_TXE,ENABLE);4 o! t! q) O I, O4 L }7 P# c( p- u' P |