|
f407vet6的,有问题,希望大家指证.. 说明: - ~+ y2 t% \0 ?8 W 1.需要我之前发的PORT类支持 2.定义 USART(USART_TypeDef* usart,PORT *rx,PORT *tx,PORT *dir=0,int speed=9600); 这里定义了usart后就知道用哪个tx,rx,是可以省略 rx,tx的,但我的代码没有处理,所以不能省略。) [1 p. M; b* C3 d( m# t, P 3.dir是用于485设备的输入输出方向。 4.这串口类是用USART_IT_IDLE状态来判断发送结束。 5.使用方法: USART usart(USART1,.......);0 w& M2 u5 n) E usart.callback=myCallback;回调程序,就是当数据发送完毕后,由哪个程序处理。- h& T& k/ {: B4 {$ Z' `% r$ e 5.callother我的类定义了一个这个回调,当callback返回为false的情况下,会调用callother,我的目的是不管从哪个串口发送过来的数据,先由上层处理,如果上层没有处理,则由callother处理,我在callother处理的都是调试类的程序,也就是用户可以通过任意串口用于调试设备,设置参数什么的。" W5 p+ S( t3 K7 C1 U& a 如果是0,就不处理。1 C0 Z8 z6 i/ v. G/ a+ N 6.enableCRC处理。( r9 I+ d* I) l7 W/ J* d* N" c 有这种情况,接收的数据不定长,非常多,开启这个会在接收的同时计算crc。/ ?7 B" _! w& _" e% O 7.缓冲区4096个字节.( R8 P6 A1 z7 x+ X ==============.h文件 #ifndef __USART__ #define __USART__ #include "stm32f4xx.h"4 e9 t; J$ Y+ X8 i #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h"* L$ J; N8 @+ f P1 R9 ]# P #include "stm32f4xx_usart.h"" `9 _* _& ^- v2 N #include "exint.h": R _" Q( u5 O4 T2 c * Q5 ]; j" b* ~3 K: F% M u16 getModbusCRC(u8*,u16); class USART {. Q T/ F/ |5 o; h9 f W9 k$ U( i public: USART(USART_TypeDef* usart,PORT *rx,PORT *tx,PORT *dir=0,int speed=9600);//硬串口6 k1 b& p& \/ x* p/ Q: j% \ USART(PORT *rx,PORT *tx,int);//模拟串口( G G: ?% f- Y: L4 @ void SendBuf(const u8 *buf,int len,bool=true); void SendByte(u8 ch);$ \& r# ]. d% y+ A4 N0 I& F void SendString(const char * buf,bool=true); void GetByte(u8 ch); bool (*callback)(u8* buf,u16 len);) v9 Z" j5 B+ K) q/ d% p bool (*callother)(USART*,u8* buf,u16 len);5 M; G' t0 R0 k* V |6 n void setSpeed(u32);0 O. O3 D2 g, ]9 `9 o: { void setOutput(); void setInput();8 I G/ I s4 X( U+ W6 v8 H void setEnabledCRC(bool);" t6 ^1 p+ E2 p! O q u16 getCRC(); void sendStart();, p* {! M5 Y+ g void sendOver(); * j0 r6 d. {% D: c: S! P" u: C ) A$ f/ w6 q5 s u8 BUF[4096];) l q$ n q; N2 u$ ]5 E& e+ O7 b private:" E. u6 W$ z$ ~3 G. R bool isSoft; USART_TypeDef* USARTx;( v8 l( \3 ~7 t, C: o. Z uint16_t Tx;& t* g0 F5 y8 q+ C uint16_t Rx;: \( c L2 t5 Z, I& J4 ?+ w u8 usartNO;3 Q( D7 o$ T4 `6 x8 f u32 BaudRate;5 t# ^ B/ p' f2 F: F% Z . V' z& v( H. ?6 |; Q; K$ G bool enableCRC;0 Y8 ?% C2 e/ R4 s u16 _CRC;2 C+ X1 ~! Q9 @ void setNo(USART_TypeDef *); void setBBR(u32); void InitUSART();/ V3 C* i5 q' J/ ?1 J friend void SysTick_Handler(void ); void usart_release_gpio_init(); E% {, C" \) }2 N' t. x void usart_nvic_config();( p8 ]( ^! m T9 i4 n4 U void usart_para_config(); u16 reciveCount; / r4 W* x! C* K# z# { u16 BUFNO;& @+ F$ \. N4 q uint64_t syscount; ( h+ X6 N' P: A! \9 {) [ //ɭݾԮࠚԃք' D8 [9 g* A" h+ ~1 Q% S0 o+ [% Q int Speed;- K7 {4 X" C8 T2 x. @6 D% l PORT *DIR;( q, A6 U( _" `$ T4 U PORT *RX,*TX;8 r- a$ P" `- `1 R5 f( j/ ~ EXINT exint;3 Z: P+ @' f1 N" F+ l% b0 [ };' d0 p8 A" p8 m2 q #endif/ P: f8 o7 H/ X# x ====================.cpp$ q2 M; F7 y6 @% @, x & |) p2 T& e1 Q/ } #include "usart.h" #include "myfun.h", D3 O0 T% q& h #include "exint.h" /* USART1 Tx=A9,Rx=A10 USART2 Tx=A2,Rx=A3; `6 s( R. L" ?/ S7 W UsART3 Tx=B10,Rx=B114 M* m0 V* Y; @3 R" _$ p */- L, |' {5 D6 P, t extern uint64_t SysCount;$ [ @& I( S# d3 D7 I( r USART *_usart[6];3 i0 d1 f9 G" t' E2 v extern "C"{/ M' [4 e+ o# T8 S% q# Q: ] void USART1_IRQHandler() {# \1 B$ U' b7 n _usart[0]->GetByte(0);5 B. v+ b' ?0 M4 ^$ v+ T8 w }- a7 d# Y+ w3 ]2 g% V" S void USART2_IRQHandler() {7 j1 ?" \/ y! p5 ]0 s) \ y _usart[1]->GetByte(0); }7 r7 K3 ~# F/ r1 D7 ~$ O void USART3_IRQHandler() { _usart[2]->GetByte(0); } void UART4_IRQHandler() { _usart[3]->GetByte(0);% ~( G+ L; g+ M; E- S: Z }' y+ x# |4 u( `/ M/ D) L% H void UART5_IRQHandler() {0 V( m5 y3 s! D; C _usart[4]->GetByte(0); }0 U, D. j- G- ~5 V7 o2 b k0 e6 I. J: k2 | void USART6_IRQHandler() { _usart[5]->GetByte(0);' n' \4 ~/ r Y1 q- {3 n% O& A } } USART::USART(PORT *tx,PORT *rx,int b) { //float s=(float)b; BUFNO=0; isSoft=true;8 v" |7 s# J; q8 D5 d ! X, H' }. T/ c3 c 0 H# \* s4 b, C" ~. S# d BaudRate=b; u9 q( C9 o0 |2 ~) @ Speed= 1000000 /b; //可能不准。 RX=rx;1 _; g" d S4 i+ M" t% p TX=tx; TX->setMode(GPIO_Mode_OUT); TX->High();' N8 f5 @; [( R4 ~$ w) r1 J RX->setMode(GPIO_Mode_IN); exint.Init(this,*RX,Speed); } void USART::setSpeed(u32 s) {5 ~% y7 [8 e7 \- }9 a/ ^, ` if (isSoft) { BaudRate=s;! b# \0 O/ q1 ]. \8 D8 a7 n Speed=1000000/s;2 ]0 _: i/ l1 g8 i9 R } else {+ n- O6 N0 e% w3 m setBBR(s); } } void USART::setEnabledCRC(bool c) {6 l" z. l$ J3 J! C7 p9 O enableCRC=c;) }6 i! C- X4 P0 @! L7 ~ _CRC=0; } void USART::setBBR(u32 BaudRate) {& S5 N& {' B4 l/ L+ R4 _) { RCC_ClocksTypeDef RCC_ClocksStatus;0 q- t0 v C% ?/ F$ I- L" C uint32_t tmpreg = 0x00, apbclock = 0x00; uint32_t integerdivider = 0x00;: W9 X9 C& `5 l) G; E( c+ u- R uint32_t fractionaldivider = 0x00;1 K' @ `; ?/ y: G : B9 L6 R3 U* S /*---------------------------- USART BRR Configuration -----------------------*/$ U& w u6 E1 t8 B' \ /* Configure the USART Baud Rate */4 [* m3 g/ `% Q( G6 u) o RCC_GetClocksFreq(&RCC_ClocksStatus); if ((USARTx == USART1) || (USARTx == USART6)) {9 V" s: h: W1 P; } s j/ [0 ] apbclock = RCC_ClocksStatus.PCLK2_Frequency;3 e; W% F' t$ ^, y+ t" R2 j }+ O% ~. L2 l3 k6 m else+ @' G5 _/ B& J6 A {% Z4 } }5 A3 V9 [- i apbclock = RCC_ClocksStatus.PCLK1_Frequency;' i) x3 {& ]2 {. f$ c. |' [ } : r# m4 c& m- R2 [, C# H/ J( e: \ /* Determine the integer part */4 c; W6 d+ L' B6 ~0 b& B Q if ((USARTx->CR1 & USART_CR1_OVER8) != 0) {9 _1 H9 L2 o; E# n /* Integer part computing in case Oversampling mode is 8 Samples */8 o$ Q: g: t2 _, S6 o5 i9 B0 D integerdivider = ((25 * apbclock) / (2 * BaudRate)); }0 J8 [* `. r* [$ m9 q4 s2 [ else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ q$ H/ w2 N. P5 G. R/ e! `4 A. y { /* Integer part computing in case Oversampling mode is 16 Samples */ G' v( g. o- d% E integerdivider = ((25 * apbclock) / (4 * BaudRate)); }% U A$ z% J0 s; O& t tmpreg = (integerdivider / 100) << 4; /* Determine the fractional part */3 j" a* v# n: \1 ?, S# P fractionaldivider = integerdivider - (100 * (tmpreg >> 4)); /* Implement the fractional part in the register */ K6 q. r2 w1 ^. @7 {! Q% H if ((USARTx->CR1 & USART_CR1_OVER8) != 0)- S5 L* t. h- l" M {6 L* T) C5 g ]0 o' Q tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);) I) r9 L9 ]" K } else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */2 U) [# Z- z2 P0 ~3 [ {" q# e1 a) p! f tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);* [2 d2 U/ u! L9 Y- k1 i- X }* S* Y+ C+ M. [3 b7 z$ t /* Write to USART BRR register */ USARTx->BRR = (uint16_t)tmpreg; }" K, r! L. w2 F6 V& D USART::USART(USART_TypeDef* u,PORT *tx,PORT *rx,PORT *dir,int speed) {/ Q" @6 J2 f, p. I5 r5 |: l isSoft=false;3 v! d3 @6 W& A; z2 X7 K+ _. e BUFNO=0;' Y( ]( h: A- s9 U$ ]) ~9 B if (u==0) return;5 H% k' U0 c" d 0 v1 I6 ]' _1 _% h- m USARTx=u;, D5 T; ?" t5 f6 a if (u==USART1) usartNO=0; if (u==USART2) usartNO=1; if (u==USART3) usartNO=2;3 u, O8 X/ E; X R. X7 I8 P if (u==UART4) usartNO=3;0 r+ d$ A9 D3 |% y if (u==UART5) usartNO=4;8 V' N/ Z% L, ?8 {; ^: Z8 G0 R5 C if (u==USART6) usartNO=5; BaudRate=speed; 3 E/ |% h# s* \& H3 E RX=rx;TX=tx; DIR=dir; " `" H) N7 ~3 A f0 i3 o) w _usart[usartNO]=this;3 f0 c+ M+ D2 h/ C/ M9 F; \ & J5 u# s5 I' O8 b callback=0; callother=0; InitUSART(); }; c6 X8 p: n6 ^ void USART::setNo(USART_TypeDef* u) {0 n( `) j- u5 W: Z g }/ g% H6 M5 K9 L. ^* i% e2 [/ d void USART::setOutput() { if (DIR!=0) DIR->High();( g( m/ Z- G8 X3 U; k } void USART::setInput() { if (DIR!=0) DIR->Low();- y4 H; D! d1 h. B2 ~2 f }5 M ?- l5 X7 [# ^1 G7 ` void USART::SendBuf(const u8 *buf,int len,bool autoIO){ int i; if (autoIO) setOutput();2 Q# \: f7 O) z; q9 y: I2 Q- S; Y7 ^ for(i=0;i<len;i++); C# |$ \( t/ D/ n4 c; }% k SendByte(buf[i]); if (autoIO) setInput(); } void USART::SendString(const char * buf,bool autoIO) { int i=0;9 ~9 f! a1 c- Y% I! V7 j% F if (autoIO) setOutput();1 n+ w8 k! y5 h* ~9 H+ P+ q while(buf[i]!=0) {SendByte(buf[i]);i++;} if (autoIO) setInput();# [: n1 r0 D5 p9 A& A! U } void USART::SendByte(u8 ch) { if (isSoft) {' Y' m, L, W( I8 W: b u8 i=8;2 B' G, `$ N( S TX->Low();( m: _/ L% F9 G* ^ delay_us(Speed); while(i--) { ch&0x01? TX->High():0 m1 h t2 k/ g G B TX->Low(); t* q& e, f' L) y" U delay_us(Speed);& }1 L. w' k C$ O5 I9 ]' L$ w7 Q8 Z ch>>=1;! l% @6 o" d) Z, x0 N2 ?0 H } TX->High(); delay_us(Speed); } else { while(RESET==USART_GetFlagStatus(USARTx,USART_FLAG_TXE));* P7 g! ? M3 Q7 I USART_SendData(USARTx,ch);7 t8 S; L% y! T while(RESET==USART_GetFlagStatus(USARTx,USART_FLAG_TC)); //USART_SendData(USARTx,ch);& u/ k4 @1 S* Q7 |; U2 i1 D //while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET);3 [, H ^9 F3 }$ a }/ ^2 W: _- H9 L, G& z+ s1 Y, Q2 e& W if (enableCRC) _CRC=getByteCRC(ch,_CRC);, l/ z. I% u* Q } u16 USART::getCRC() { return _CRC;5 |1 B+ Z: y1 K% `, [6 ] }1 e" ?9 T' I$ Y4 D 1 [& w3 @5 e6 Q$ {0 ?( H) z2 F void USART::GetByte(u8 ret) { if (isSoft) {0 _& H8 A1 a/ {1 `8 f: r //暂时没处理 } else { if (USART_GetITStatus(USARTx,USART_IT_RXNE)!=RESET) {- }2 a9 a; W2 K0 J7 ~' @ ret=USART_ReceiveData(USARTx);* ^: B' h2 L$ y; n. r- ^ USART_ClearITPendingBit(USARTx,USART_IT_RXNE); 5 b, e$ I% L9 B$ g' |+ f" X5 @ BUF[BUFNO]=ret; BUFNO=(BUFNO+1)%4096; if (enableCRC) _CRC=getByteCRC(ret,_CRC); } else { if (USART_GetITStatus(USARTx,USART_IT_IDLE)!=RESET) {$ s0 q! f& b# D5 y) f- v int count=BUFNO; USART_ClearFlag(USARTx,USART_IT_IDLE); BUFNO=0; uint8_t clear; clear=USARTx->SR; clear=USARTx->DR; if (callback!=0 && count>0) / h L- S. t# q) P4 R" I if (!callback(BUF,count) && callother!=0) callother(this,BUF,count); }8 S- V% w, {; v }7 q8 d* i0 I% X& V- e J . w5 p/ Q& J1 s- P3 u% f$ V }: t/ t% J" }$ o6 b- c5 ] /*9 j. h3 n4 H6 d ~* t3 _4 f9 G BUF[BUFNO]=ret;6 q1 a; q' G2 M, v BUFNO=(BUFNO+1)%4096;; E% m5 q0 y- K* Z. q7 W/ z syscount=SysCount;/ u+ w; K' A" j" _ 7 Z' Y1 M5 U5 f2 H5 m% s7 f */- U0 T, P( b. a* u3 O2 S" V } void USART::InitUSART(){ ' B% ^6 V; P& D! W RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<TX-> ortNo,ENABLE);2 E; i( D+ l- S5 z/ Q//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD,ENABLE);+ o, X3 j3 i# h' B2 U# X/ x6 \ switch(usartNO) {$ [; x2 T6 z8 } case 0:9 J- S# i$ c. ~" P+ P# p1 l, \ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);1 Q8 S6 P( v l1 { break;( @% Z& L! X9 `$ \ case 1:& e# o w2 }% L9 x/ m5 a case 2:7 a5 m& A+ q- t! k case 3: case 4:! x* D$ Z. x. _ w- ^. G/ Z RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2<<(usartNO-1),ENABLE); break; case 5:" _/ S5 w. [* |/ A) y& y RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE);: ^% o4 I7 U; x2 z# T/ u* P: A | break; }9 _( u' D4 _% |: o2 W% d% y* o switch(usartNO) { case 0: case 1:. E: t4 u2 @% A2 Q% | 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);- Q# j1 w$ ~( ], g3 K! A. a6 t% Pbreak; case 3: case 4:3 o$ X! t& }" c5 X+ T, o case 5: GPIO_PinAFConfig(TX->GPIO,GPIO_PinSource0 + (TX-> inNo/2) ,GPIO_AF_UART4);, `) {. g C) s6 w2 O" @( p6 oGPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX-> inNo/2) ,GPIO_AF_UART4);break; }6 N! v' v' c" h' i5 ? 2 t+ Y1 g4 K4 D! Z9 Y) w( @ /* RX.setMode(GPIO_Mode_AF);2 T' q" W6 m# M- U5 {" Y' \% R RX.setType(GPIO_OType_PP); TX.setMode(GPIO_Mode_AF);2 A9 k# O& ~, s2 F. w% u7 B ? TX.setType(GPIO_OType_PP); */# X% r. K6 \; @1 V + x0 c( X! P/ f7 q" i3 m Tx=TX-> in;' f. q ~ g9 _9 u2 S; ~2 P. yRx=RX-> in;0 j3 {" P; D$ p2 A# w7 m9 U4 a: \" z4 l6 l$ ?/ i0 `" @- N //3?Ⱥ??e¤??ȲȰy?? usart_release_gpio_init(); 7 l* m3 t0 y4 j* l: \+ P3 @9 s //????¤??Ȳ?D??$ o+ y* c% b; l+ s s) f$ [ usart_nvic_config();" } Y* A1 e6 l4 n- `7 X" r //????¤??Ȳ?ªȺ? usart_para_config();1 t4 {' v. U; w+ r1 f + n; B$ L. {0 r2 o0 t/ [1 _( J- ? } void USART::usart_release_gpio_init() {% q/ u+ x0 N' s. e9 B: n GPIO_InitTypeDef GPIO_InitStruct;' o p# \6 b J8 E, E' h7 D! D* ` GPIO_InitStruct.GPIO_Pin=Tx; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;5 X5 O! R. Y, l: p9 U& m( G GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;! x6 x0 f$ X% f; U7 B& n4 e/ w+ N GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; / \# F* g; ?. c U GPIO_Init(TX->GPIO,&GPIO_InitStruct); . Y6 n) B. M- ?+ ? GPIO_InitStruct.GPIO_Pin=Rx; /*GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;# h4 J1 y c/ v9 P GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;! ?* e! ~+ J8 I8 r9 K */ GPIO_Init(RX->GPIO,&GPIO_InitStruct); }/ Q/ f- D" z# q' {5 ]; D' ` void USART::usart_nvic_config() {/ }8 a1 ^# q6 p H# N9 i NVIC_InitTypeDef NVIC_InitStruct;8 Z. h8 l( ]' s) D6 `" Q NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);1 m- v' J x2 K5 o$ f% N switch(usartNO) { case 0: case 1:. m4 U+ f" N/ I9 J case 2:* `* S: o/ \, t i NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn + usartNO; break; case 3:1 @! I% C# h0 _, P" |* n; J3 G case 4: NVIC_InitStruct.NVIC_IRQChannel=UART4_IRQn + (usartNO-3);: E8 b4 L) ?0 ]9 h% f break; case 5:, w( y) d) I- F5 Y NVIC_InitStruct.NVIC_IRQChannel=USART6_IRQn; break; } 1 B( d, D& ^: l, k+ v( s$ a NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3; NVIC_InitStruct.NVIC_IRQChannelSubPriority=3;9 B( o- _( {0 E/ h7 n NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;8 L$ b+ b# I8 e) p2 V9 J, ^ NVIC_Init(&NVIC_InitStruct); } void USART::usart_para_config() { USART_InitTypeDef USART_InitStruct; USART_InitStruct.USART_BaudRate=BaudRate; USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;! L8 _+ A* e8 @5 a+ Z USART_InitStruct.USART_Parity=USART_Parity_No;, @, o+ z4 v, A# Y P L9 ^0 N% H USART_InitStruct.USART_StopBits=USART_StopBits_1; USART_InitStruct.USART_WordLength=USART_WordLength_8b; USART_Init(USARTx,&USART_InitStruct);; @5 {; e2 Y+ O: J" F / x, _2 F& m7 ^" B4 |+ D# Y USART_ClockInitTypeDef usart_clock; USART_ClockStructInit(&usart_clock);$ K2 [' S5 I' w USART_ClockInit(USARTx,&usart_clock);# u1 q# t% r& m; R& J3 V0 J USART_ClearFlag(USARTx,USART_FLAG_IDLE); USART_ClearFlag(USARTx,USART_FLAG_RXNE);5 j! d7 O$ a' y2 V; U# s" x! J USART_ClearITPendingBit(USARTx,USART_IT_RXNE); USART_ClearFlag(USARTx,USART_FLAG_TC); USART_ITConfig(USARTx,USART_IT_IDLE,ENABLE); USART_ITConfig(USARTx,USART_IT_RXNE,ENABLE); //USART_ITConfig(USARTx,USART_IT_ORE,ENABLE); USART_Cmd(USARTx,ENABLE);' s2 K4 ^* S6 b x //USART_ITConfig(USARTx,USART_IT_TXE,ENABLE);3 n6 t$ W: p) X8 D" _% B: { } |
微信公众号
手机版