f407vet6的,有问题,希望大家指证.. 说明: 1.需要我之前发的PORT类支持) i4 @) R1 K3 y E7 j, a1 u 2.定义 USART(USART_TypeDef* usart,PORT *rx,PORT *tx,PORT *dir=0,int speed=9600);' L" v5 h- }8 T6 e# ]# \% O, Q+ F F 这里定义了usart后就知道用哪个tx,rx,是可以省略 rx,tx的,但我的代码没有处理,所以不能省略。 3.dir是用于485设备的输入输出方向。& z& Y, [5 w6 i1 n; d/ ~ 4.这串口类是用USART_IT_IDLE状态来判断发送结束。 5.使用方法:# {* m, j' t" S# z USART usart(USART1,.......); usart.callback=myCallback;回调程序,就是当数据发送完毕后,由哪个程序处理。 5.callother我的类定义了一个这个回调,当callback返回为false的情况下,会调用callother,我的目的是不管从哪个串口发送过来的数据,先由上层处理,如果上层没有处理,则由callother处理,我在callother处理的都是调试类的程序,也就是用户可以通过任意串口用于调试设备,设置参数什么的。 如果是0,就不处理。1 _5 N9 y# @: ^* w E 6.enableCRC处理。* k! z2 k" m/ i- R& S+ s 有这种情况,接收的数据不定长,非常多,开启这个会在接收的同时计算crc。. X+ f1 ]. b1 l+ D1 Q. \ 7.缓冲区4096个字节.3 \( ~. ~# a9 j9 i2 C( J! V; @3 Z ==============.h文件 #ifndef __USART__ #define __USART__ #include "stm32f4xx.h"+ Q: c4 A9 U5 g5 a #include "stm32f4xx_gpio.h"1 E5 X# R( {' h+ k( Z #include "stm32f4xx_rcc.h"7 O0 N1 x' H }- _4 Y) M #include "stm32f4xx_usart.h"8 S: G3 u" A, E0 w+ r* z: K7 e #include "exint.h" u16 getModbusCRC(u8*,u16);5 V4 Z" w$ V3 H4 r) b; j class USART { public: ' ?% v# t$ |5 y USART(USART_TypeDef* usart,PORT *rx,PORT *tx,PORT *dir=0,int speed=9600);//硬串口 USART(PORT *rx,PORT *tx,int);//模拟串口* H5 P3 }' T6 w' z5 s2 G- \2 F void SendBuf(const u8 *buf,int len,bool=true);. r4 j/ g' P6 K1 z: ~8 w/ c void SendByte(u8 ch);/ N$ K3 u3 ]5 E0 i void SendString(const char * buf,bool=true); void GetByte(u8 ch); w) v* ]9 W3 x+ b) O0 B% Z bool (*callback)(u8* buf,u16 len); bool (*callother)(USART*,u8* buf,u16 len); void setSpeed(u32); void setOutput(); void setInput(); void setEnabledCRC(bool); u16 getCRC();6 [( d( c; L. m3 \ void sendStart(); void sendOver(); # }, L+ ~2 w& k o/ ]( s u8 BUF[4096]; private: bool isSoft;8 ^3 X& @& _/ w6 u, V) a- B USART_TypeDef* USARTx; uint16_t Tx;$ L* Y! K: j3 ^8 E uint16_t Rx; u8 usartNO;- _) _! p' H" F+ s- Y* X* S u32 BaudRate; & T8 E4 g' s& F6 @$ ~" l- c bool enableCRC; u16 _CRC;" N; m( k' R8 @4 f* b& y/ Y# G - ]- v/ u5 h6 u7 u void setNo(USART_TypeDef *); void setBBR(u32); void InitUSART();* g# }+ Y9 u: ]$ S6 d! C) C% F friend void SysTick_Handler(void );8 X5 F5 t& ~$ X; {6 q/ K- q void usart_release_gpio_init();5 W% n" t' C+ G2 d8 C5 R void usart_nvic_config(); void usart_para_config();# K8 K+ n) Y, M1 \/ s u16 reciveCount;; f t+ [& @" P9 }- E, D u16 BUFNO; uint64_t syscount;$ j8 f2 \3 |( J5 N% d & U) B" v: l M- y: ] //ɭݾԮࠚԃք int Speed;5 `, a3 c% U% [; _1 ~0 B7 y PORT *DIR;/ o5 O m8 ^1 |% i PORT *RX,*TX;8 y9 l6 ]3 b4 ]6 F) |0 y EXINT exint;6 X7 E* O& ?* ^2 v! q. T }; #endif 7 _( r# c6 b) D3 v8 c* o ====================.cpp #include "usart.h"% J/ |6 H! A) x% @! ? M #include "myfun.h"+ s% j+ _; U$ Z: o3 R4 | #include "exint.h" /*/ ~& B/ D" o* J; }+ A, M' c USART1 Tx=A9,Rx=A10 USART2 Tx=A2,Rx=A3 UsART3 Tx=B10,Rx=B11' z+ D# m! I# ?/ Q */6 b& S* x; A) U2 p' O' Q { extern uint64_t SysCount; USART *_usart[6]; extern "C"{* P6 L( L9 H9 }6 {/ | void USART1_IRQHandler() {+ O/ s- U8 \& A* ~$ h" } _usart[0]->GetByte(0); }; q) y5 N3 a3 m void USART2_IRQHandler() { _usart[1]->GetByte(0);" m* n* H4 ?1 @) b9 L/ q* j6 _ } void USART3_IRQHandler() { _usart[2]->GetByte(0);) w K2 B2 m: O" ? }- m6 C% w* }* R( X void UART4_IRQHandler() { _usart[3]->GetByte(0); }8 c/ t9 Z- v _5 h. d void UART5_IRQHandler() {& v. X( @) o# p _usart[4]->GetByte(0); } void USART6_IRQHandler() {% l) F/ {9 W/ W& O0 _' Z& B! p _usart[5]->GetByte(0);2 f" `& a. ^) h1 H! [+ O } } USART::USART(PORT *tx,PORT *rx,int b) {8 ]9 N" c& h! R* O3 t //float s=(float)b; BUFNO=0;( r0 O+ i4 S- o( E5 B+ ^0 S, H! a# M3 U isSoft=true;* u$ o2 T9 ~. H; _: j3 e! K* F! a5 V 9 T6 u; C* `0 L; l3 R/ Z8 |7 f BaudRate=b; Speed= 1000000 /b; //可能不准。" `8 X. U% ]" j2 C5 X( P RX=rx; TX=tx;; I4 l5 c, @2 M$ v' K1 y* Q- Z. V + L( r6 X# G/ i' k1 r. h; z( E TX->setMode(GPIO_Mode_OUT); TX->High();& _" Y. Y- o- w, R RX->setMode(GPIO_Mode_IN); exint.Init(this,*RX,Speed);3 l7 o2 ~! } g7 ~4 Y" X( a } void USART::setSpeed(u32 s) { if (isSoft) {/ g1 C7 |6 [& }. O, x2 |4 d1 _ BaudRate=s;0 ]% H9 p7 g( A: P$ @0 f Speed=1000000/s; } else { setBBR(s); }2 r9 `4 E6 B7 \" S; v } void USART::setEnabledCRC(bool c) {$ \# z+ l7 |* l; l enableCRC=c;3 K6 o f# w4 i" A& H% H7 C9 q _CRC=0; }4 |% Z' H8 a$ a* I void USART::setBBR(u32 BaudRate) { RCC_ClocksTypeDef RCC_ClocksStatus;% U1 J, L9 l/ Z' p3 M2 j9 _* R uint32_t tmpreg = 0x00, apbclock = 0x00;8 [8 J4 L: q( O, k+ ~2 A2 L1 H3 q# r uint32_t integerdivider = 0x00; uint32_t fractionaldivider = 0x00; % ?! e1 A* b1 T( e3 o5 Y /*---------------------------- USART BRR Configuration -----------------------*/% Y/ }+ h( j! i /* Configure the USART Baud Rate */: Y, z0 K O; u7 [) v' | RCC_GetClocksFreq(&RCC_ClocksStatus); if ((USARTx == USART1) || (USARTx == USART6)); F4 ]. u! ~ t. w) U' E- b { apbclock = RCC_ClocksStatus.PCLK2_Frequency; } else {, W2 ~# \+ _! c/ e7 G t apbclock = RCC_ClocksStatus.PCLK1_Frequency; }! y) \/ e6 J3 w 8 i: M, N; ~4 A" v /* Determine the integer part */( b( A* \$ q/ \0 Q' z+ | if ((USARTx->CR1 & USART_CR1_OVER8) != 0)* a; J2 q9 C& z" B+ {' H$ ? { /* Integer part computing in case Oversampling mode is 8 Samples */ integerdivider = ((25 * apbclock) / (2 * BaudRate)); 5 G/ }* R3 f* \5 ~) U } else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */1 K- h) B7 f) t/ f( E { /* Integer part computing in case Oversampling mode is 16 Samples */5 S9 L0 a2 W) ^7 _: N# O integerdivider = ((25 * apbclock) / (4 * BaudRate)); }$ j' s) X: E( e( k- V tmpreg = (integerdivider / 100) << 4;8 h, a. l5 p' u /* Determine the fractional part */ fractionaldivider = integerdivider - (100 * (tmpreg >> 4));% l& @7 Y8 a! I/ h+ b+ B/ P /* Implement the fractional part in the register */3 L' G+ G1 k' e) g5 ^ if ((USARTx->CR1 & USART_CR1_OVER8) != 0)- |9 b# T& w: ?3 X4 _; H4 h, R {( ~/ y; }. h$ i* r. K( P tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); }$ I4 S- @5 I0 @) Q else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ {6 P/ [' x! a+ Z* L6 F tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);7 s+ e) ]' N5 N1 x } # W6 a/ o8 o, H6 m Z; \' I } /* Write to USART BRR register */0 p4 D2 V. X3 R USARTx->BRR = (uint16_t)tmpreg; }) t1 O$ w1 ?* F2 g USART::USART(USART_TypeDef* u,PORT *tx,PORT *rx,PORT *dir,int speed) { isSoft=false; BUFNO=0; if (u==0) return;5 ~9 |- Z$ _3 R3 H USARTx=u;+ F' r8 T* i% o if (u==USART1) usartNO=0; if (u==USART2) usartNO=1; if (u==USART3) usartNO=2; if (u==UART4) usartNO=3; if (u==UART5) usartNO=4; if (u==USART6) usartNO=5; BaudRate=speed;% q) G( u- H! J+ s 8 K) ?4 z7 f$ G1 i4 t V" x6 Z. `( j RX=rx;TX=tx; DIR=dir;: h W. f( r: E! P' Z: d0 Z7 e4 l _usart[usartNO]=this;1 P1 ?4 P7 |+ j/ Z2 G; p$ s callback=0; callother=0;, N( V) Z4 y+ G InitUSART(); } void USART::setNo(USART_TypeDef* u) {0 v( g# ?9 u$ ?3 Z" }, Q9 k 8 I' c. l) h' `( u, O/ A } void USART::setOutput() { if (DIR!=0) DIR->High();3 h5 o1 s7 K! j; l) s }* t, J1 f0 z! q5 ]: r) Z void USART::setInput() {# c, w* k! i; u# |; L if (DIR!=0) DIR->Low(); }. B% S/ I2 M( J" C2 v void USART::SendBuf(const u8 *buf,int len,bool autoIO){ int i; if (autoIO) setOutput();4 \6 @2 W! H. X for(i=0;i<len;i++) SendByte(buf[i]); if (autoIO) setInput();4 b/ z. N0 \- D1 d" r }4 g& ]" o' T' {+ f5 Y/ B void USART::SendString(const char * buf,bool autoIO) {* e5 ~( o" b/ j, b, U int i=0; if (autoIO) setOutput();0 R$ [0 V6 K6 P8 { while(buf[i]!=0) {SendByte(buf[i]);i++;}7 X" }8 y( p! `& I8 F$ s if (autoIO) setInput(); } void USART::SendByte(u8 ch) {; a- k" A" C& F7 F: o if (isSoft) {8 e9 u+ y% {+ M1 e2 ^ u8 i=8; TX->Low(); delay_us(Speed);% _3 b9 Q, z% M. U8 K l+ s while(i--) { ch&0x01? TX->High(): TX->Low();: P; V0 N2 q: ?/ b6 X# |8 ` delay_us(Speed); ch>>=1; }8 ~. ^( G8 d6 } TX->High(); delay_us(Speed); } else { while(RESET==USART_GetFlagStatus(USARTx,USART_FLAG_TXE)); USART_SendData(USARTx,ch); while(RESET==USART_GetFlagStatus(USARTx,USART_FLAG_TC)); j) p: g+ ^, O& J: P8 U3 g' d //USART_SendData(USARTx,ch);- n1 H% `/ [, b4 o! w //while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET); }4 d/ [% V5 h1 ` if (enableCRC) _CRC=getByteCRC(ch,_CRC);& y, c* g- x8 \4 ~( R. H9 { }: M: l4 G$ Q1 |! _: J# F u16 USART::getCRC() {9 _( ~9 ]# g) {! F7 n2 y3 L0 ` return _CRC;4 y% |- Y( B9 s6 c" y7 G6 _7 i5 s } ' Y- b! m6 B7 f1 J void USART::GetByte(u8 ret) {2 q: K: V+ B/ P! T6 } if (isSoft) { //暂时没处理5 t, ^/ ^& g3 q' O8 A, P( s4 d } else { if (USART_GetITStatus(USARTx,USART_IT_RXNE)!=RESET) {' G: h/ }7 L' ~/ {* x ret=USART_ReceiveData(USARTx);) R0 @$ m# V! g USART_ClearITPendingBit(USARTx,USART_IT_RXNE); BUF[BUFNO]=ret;+ J; V! R* i$ @! M# A ^ BUFNO=(BUFNO+1)%4096;/ y2 z; ~' D- m; r. Y( d if (enableCRC) _CRC=getByteCRC(ret,_CRC); } else { if (USART_GetITStatus(USARTx,USART_IT_IDLE)!=RESET) {0 n1 T: @* G7 m9 i int count=BUFNO;7 n# V# z T" H. ]- N4 i1 ]! O USART_ClearFlag(USARTx,USART_IT_IDLE);# f0 r& E7 O% u& m- b BUFNO=0; uint8_t clear;- f0 d+ i4 q: t clear=USARTx->SR;% a& e4 n8 } E) I/ _" X7 q clear=USARTx->DR; if (callback!=0 && count>0) if (!callback(BUF,count) && callother!=0) callother(this,BUF,count);+ T7 w6 i @; C3 s1 ?) V# Q }4 S J2 v% I6 X' B" Z } ) g% t+ [) Z; j }- ?! h! E8 T) l3 u/ k, D( X/ n /* BUF[BUFNO]=ret; BUFNO=(BUFNO+1)%4096; syscount=SysCount; 7 f. o7 [ \* _ */ }; E. P0 y- s/ T# m- V* h: N9 O2 E6 b 3 ?6 W8 p. r" v6 s8 d void USART::InitUSART(){ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<TX->ortNo,ENABLE);1 r) Z* t- E" {7 j3 I- m //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD,ENABLE);" `* O0 a: t7 x. ?# r : L9 z1 b8 |( \ switch(usartNO) { case 0:- `, J1 M. Z; X7 N2 Z! Q/ u RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); break;9 Y/ I* u; b+ t8 S Q' \' b case 1:/ {; Y$ o0 Q) Z' O. j% |3 }4 p case 2: case 3:) N% K/ X; x2 i: ] c" O8 N, y case 4:5 c! r# B: K8 g' B! P RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2<<(usartNO-1),ENABLE); break; case 5:( n W4 j! @# U! W; v# i RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE); break;- M3 S+ k6 g$ l1 n }- c; S) O' s0 H3 T N- Y + H1 a1 H4 A" X* O, ? switch(usartNO) {6 B/ S( g, K/ ?% e# u case 0:$ o/ X' b$ h* `: W, v case 1:* D' X, {2 n9 m9 K! ? case 2: GPIO_PinAFConfig(TX->GPIO,GPIO_PinSource0 + (TX->inNo/2) ,GPIO_AF_USART1);! l M( I' Y5 R0 M9 k* l, R GPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX->inNo/2) ,GPIO_AF_USART1); break;% {3 T/ ?! m/ u case 3:. c; x5 u# f2 \7 B' I8 r case 4:& w9 Y3 t" h$ N* `7 o' E" n case 5: - M' G b% H9 c- C) o; {; y GPIO_PinAFConfig(TX->GPIO,GPIO_PinSource0 + (TX->inNo/2) ,GPIO_AF_UART4); GPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX->inNo/2) ,GPIO_AF_UART4);, {7 A+ U- E" ]/ m break;& I$ q( \9 ? ^$ x& f* F$ n9 z $ X2 }. b3 v* t8 J5 ^9 | }1 x, q5 U6 i! M /*% Y0 X j2 P, o0 J' g5 R3 P RX.setMode(GPIO_Mode_AF); RX.setType(GPIO_OType_PP);3 \# R( B: i% w$ B7 S( c4 U TX.setMode(GPIO_Mode_AF);' q) r# y/ @4 ^0 b3 U% g TX.setType(GPIO_OType_PP); */ Tx=TX->in; Rx=RX->in;! p; `5 {9 D* K2 Y 8 o- S& B* ^0 W2 j& j9 t //3?Ⱥ??e¤??ȲȰy?? usart_release_gpio_init(); //????¤??Ȳ?D??. V' R! r6 v6 i& i usart_nvic_config();6 j; ]2 e( ^6 M4 Y# r //????¤??Ȳ?ªȺ? usart_para_config();7 A, ~3 L9 `) b. E ) H* ?6 l5 v' ]* z& U/ t } void USART::usart_release_gpio_init() {9 g% J5 W: J" {4 L& T: {: |/ Z6 u GPIO_InitTypeDef GPIO_InitStruct;+ p G( i; U, ]# S GPIO_InitStruct.GPIO_Pin=Tx; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;+ i, ^9 Z0 L& M s4 @ GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;& j( U- W; O; L E/ {- G GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;- Q+ f+ V" c" T# q6 `/ y3 t GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; GPIO_Init(TX->GPIO,&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin=Rx;( C/ M k/ E! w" l2 j' q2 R3 E; i6 a /*GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;/ X0 g. ?3 _6 U$ V/ I; I) O: l GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;! d( k: W$ I8 C# ?) E" @9 D */) L/ U9 S' B* r5 F6 i GPIO_Init(RX->GPIO,&GPIO_InitStruct); }$ |6 c4 x2 O" w* h( ~ void USART::usart_nvic_config() {8 l/ `- Q- i5 M A; i NVIC_InitTypeDef NVIC_InitStruct;1 f- Y0 ^2 `4 x: g* R4 ]( ?1 n NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);) T* A6 {0 }( E& b* R switch(usartNO) { case 0:5 @$ S% h7 n1 E* J% z5 R: r case 1: case 2: NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn + usartNO; break;1 P: H0 ~1 @4 ~ A case 3:+ A/ k0 Q4 a9 Y case 4: NVIC_InitStruct.NVIC_IRQChannel=UART4_IRQn + (usartNO-3); break;+ M( _" s7 ~& A" @ case 5: NVIC_InitStruct.NVIC_IRQChannel=USART6_IRQn; break;; l4 m" G0 t9 V, s- [! l: A5 G+ V } NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3; NVIC_InitStruct.NVIC_IRQChannelSubPriority=3;+ Y' C- S2 k6 m' U# f NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;1 i& x. U7 b' D% G3 x' @ NVIC_Init(&NVIC_InitStruct);5 ? t9 E; g1 ~$ O }5 z$ G+ s k) n5 W. l void USART::usart_para_config() {$ F0 G0 h r: |2 L$ d- B$ F# K USART_InitTypeDef USART_InitStruct; ' P4 T$ B" T3 E$ v: G) l/ [ USART_InitStruct.USART_BaudRate=BaudRate;4 O( e+ k# e. p3 c' U; u, l USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;. ?& _* e; ?/ m+ m5 @$ h USART_InitStruct.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;$ Q/ A- ?! o6 Z7 B2 Y I USART_InitStruct.USART_Parity=USART_Parity_No; USART_InitStruct.USART_StopBits=USART_StopBits_1; USART_InitStruct.USART_WordLength=USART_WordLength_8b;* o% w; x' @( x+ f! q- b! R3 x& z6 X USART_Init(USARTx,&USART_InitStruct); . [9 U: ]+ W( m9 ]' _3 l USART_ClockInitTypeDef usart_clock; USART_ClockStructInit(&usart_clock);* D3 |0 M0 k+ [) t- U% }; s USART_ClockInit(USARTx,&usart_clock); USART_ClearFlag(USARTx,USART_FLAG_IDLE); USART_ClearFlag(USARTx,USART_FLAG_RXNE);3 h) C2 }5 X/ D6 z USART_ClearITPendingBit(USARTx,USART_IT_RXNE); USART_ClearFlag(USARTx,USART_FLAG_TC);+ x& d3 M' S* c2 O( S0 G3 Z- p USART_ITConfig(USARTx,USART_IT_IDLE,ENABLE);4 F2 w( p9 C0 v' ~# b/ Z6 \8 d8 d( G" d USART_ITConfig(USARTx,USART_IT_RXNE,ENABLE); //USART_ITConfig(USARTx,USART_IT_ORE,ENABLE); USART_Cmd(USARTx,ENABLE); //USART_ITConfig(USARTx,USART_IT_TXE,ENABLE);8 V, N" j3 B6 k& ] } |