
f407vet6的,有问题,希望大家指证.. 说明: 1.需要我之前发的PORT类支持 2.定义 USART(USART_TypeDef* usart,PORT *rx,PORT *tx,PORT *dir=0,int speed=9600); 这里定义了usart后就知道用哪个tx,rx,是可以省略 rx,tx的,但我的代码没有处理,所以不能省略。 3.dir是用于485设备的输入输出方向。 4.这串口类是用USART_IT_IDLE状态来判断发送结束。 5.使用方法: USART usart(USART1,.......); usart.callback=myCallback;回调程序,就是当数据发送完毕后,由哪个程序处理。 5.callother我的类定义了一个这个回调,当callback返回为false的情况下,会调用callother,我的目的是不管从哪个串口发送过来的数据,先由上层处理,如果上层没有处理,则由callother处理,我在callother处理的都是调试类的程序,也就是用户可以通过任意串口用于调试设备,设置参数什么的。 如果是0,就不处理。 6.enableCRC处理。 有这种情况,接收的数据不定长,非常多,开启这个会在接收的同时计算crc。 7.缓冲区4096个字节. ==============.h文件 #ifndef __USART__ #define __USART__ #include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_usart.h" #include "exint.h" u16 getModbusCRC(u8*,u16); class USART { public: USART(USART_TypeDef* usart,PORT *rx,PORT *tx,PORT *dir=0,int speed=9600);//硬串口 USART(PORT *rx,PORT *tx,int);//模拟串口 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); void setSpeed(u32); void setOutput(); void setInput(); void setEnabledCRC(bool); u16 getCRC(); void sendStart(); void sendOver(); u8 BUF[4096]; private: bool isSoft; USART_TypeDef* USARTx; uint16_t Tx; uint16_t Rx; u8 usartNO; u32 BaudRate; bool enableCRC; u16 _CRC; void setNo(USART_TypeDef *); void setBBR(u32); void InitUSART(); friend void SysTick_Handler(void ); void usart_release_gpio_init(); void usart_nvic_config(); void usart_para_config(); u16 reciveCount; u16 BUFNO; uint64_t syscount; //ɭݾԮࠚԃք int Speed; PORT *DIR; PORT *RX,*TX; EXINT exint; }; #endif ====================.cpp #include "usart.h" #include "myfun.h" #include "exint.h" /* USART1 Tx=A9,Rx=A10 USART2 Tx=A2,Rx=A3 UsART3 Tx=B10,Rx=B11 */ extern uint64_t SysCount; USART *_usart[6]; extern "C"{ void USART1_IRQHandler() { _usart[0]->GetByte(0); } void USART2_IRQHandler() { _usart[1]->GetByte(0); } void USART3_IRQHandler() { _usart[2]->GetByte(0); } void UART4_IRQHandler() { _usart[3]->GetByte(0); } void UART5_IRQHandler() { _usart[4]->GetByte(0); } void USART6_IRQHandler() { _usart[5]->GetByte(0); } } USART::USART(PORT *tx,PORT *rx,int b) { //float s=(float)b; BUFNO=0; isSoft=true; BaudRate=b; Speed= 1000000 /b; //可能不准。 RX=rx; TX=tx; TX->setMode(GPIO_Mode_OUT); TX->High(); RX->setMode(GPIO_Mode_IN); exint.Init(this,*RX,Speed); } void USART::setSpeed(u32 s) { if (isSoft) { BaudRate=s; Speed=1000000/s; } else { setBBR(s); } } void USART::setEnabledCRC(bool c) { enableCRC=c; _CRC=0; } void USART::setBBR(u32 BaudRate) { RCC_ClocksTypeDef RCC_ClocksStatus; uint32_t tmpreg = 0x00, apbclock = 0x00; uint32_t integerdivider = 0x00; uint32_t fractionaldivider = 0x00; /*---------------------------- USART BRR Configuration -----------------------*/ /* Configure the USART Baud Rate */ RCC_GetClocksFreq(&RCC_ClocksStatus); if ((USARTx == USART1) || (USARTx == USART6)) { apbclock = RCC_ClocksStatus.PCLK2_Frequency; } else { apbclock = RCC_ClocksStatus.PCLK1_Frequency; } /* Determine the integer part */ if ((USARTx->CR1 & USART_CR1_OVER8) != 0) { /* Integer part computing in case Oversampling mode is 8 Samples */ 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)); } tmpreg = (integerdivider / 100) << 4; /* Determine the fractional part */ fractionaldivider = integerdivider - (100 * (tmpreg >> 4)); /* Implement the fractional part in the register */ if ((USARTx->CR1 & USART_CR1_OVER8) != 0) { tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); } else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ { tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F); } /* Write to USART BRR register */ USARTx->BRR = (uint16_t)tmpreg; } USART::USART(USART_TypeDef* u,PORT *tx,PORT *rx,PORT *dir,int speed) { isSoft=false; BUFNO=0; if (u==0) return; USARTx=u; 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; RX=rx;TX=tx; DIR=dir; _usart[usartNO]=this; callback=0; callother=0; InitUSART(); } void USART::setNo(USART_TypeDef* u) { } 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]); if (autoIO) setInput(); } void USART::SendString(const char * buf,bool autoIO) { int i=0; if (autoIO) setOutput(); while(buf[i]!=0) {SendByte(buf[i]);i++;} if (autoIO) setInput(); } void USART::SendByte(u8 ch) { if (isSoft) { u8 i=8; TX->Low(); delay_us(Speed); while(i--) { ch&0x01? TX->High(): TX->Low(); delay_us(Speed); ch>>=1; } 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)); //USART_SendData(USARTx,ch); //while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET); } if (enableCRC) _CRC=getByteCRC(ch,_CRC); } u16 USART::getCRC() { return _CRC; } void USART::GetByte(u8 ret) { if (isSoft) { //暂时没处理 } else { if (USART_GetITStatus(USARTx,USART_IT_RXNE)!=RESET) { ret=USART_ReceiveData(USARTx); USART_ClearITPendingBit(USARTx,USART_IT_RXNE); BUF[BUFNO]=ret; BUFNO=(BUFNO+1)%4096; if (enableCRC) _CRC=getByteCRC(ret,_CRC); } else { if (USART_GetITStatus(USARTx,USART_IT_IDLE)!=RESET) { 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) if (!callback(BUF,count) && callother!=0) callother(this,BUF,count); } } } /* BUF[BUFNO]=ret; BUFNO=(BUFNO+1)%4096; syscount=SysCount; */ } void USART::InitUSART(){ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<TX-> ![]() //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; case 1: case 2: case 3: case 4: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2<<(usartNO-1),ENABLE); break; case 5: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE); break; } switch(usartNO) { case 0: case 1: case 2: GPIO_PinAFConfig(TX->GPIO,GPIO_PinSource0 + (TX-> ![]() GPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX-> ![]() break; case 3: case 4: case 5: GPIO_PinAFConfig(TX->GPIO,GPIO_PinSource0 + (TX-> ![]() GPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX-> ![]() break; } /* RX.setMode(GPIO_Mode_AF); RX.setType(GPIO_OType_PP); TX.setMode(GPIO_Mode_AF); TX.setType(GPIO_OType_PP); */ Tx=TX-> ![]() Rx=RX-> ![]() //3?Ⱥ??e¤??ȲȰy?? usart_release_gpio_init(); //????¤??Ȳ?D?? usart_nvic_config(); //????¤??Ȳ?ªȺ? usart_para_config(); } void USART::usart_release_gpio_init() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin=Tx; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; GPIO_Init(TX->GPIO,&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin=Rx; /*GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; */ GPIO_Init(RX->GPIO,&GPIO_InitStruct); } void USART::usart_nvic_config() { NVIC_InitTypeDef NVIC_InitStruct; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); switch(usartNO) { case 0: case 1: case 2: NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn + usartNO; break; case 3: case 4: NVIC_InitStruct.NVIC_IRQChannel=UART4_IRQn + (usartNO-3); break; case 5: NVIC_InitStruct.NVIC_IRQChannel=USART6_IRQn; break; } NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3; NVIC_InitStruct.NVIC_IRQChannelSubPriority=3; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; 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; USART_InitStruct.USART_Parity=USART_Parity_No; USART_InitStruct.USART_StopBits=USART_StopBits_1; USART_InitStruct.USART_WordLength=USART_WordLength_8b; USART_Init(USARTx,&USART_InitStruct); USART_ClockInitTypeDef usart_clock; USART_ClockStructInit(&usart_clock); USART_ClockInit(USARTx,&usart_clock); USART_ClearFlag(USARTx,USART_FLAG_IDLE); USART_ClearFlag(USARTx,USART_FLAG_RXNE); 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); //USART_ITConfig(USARTx,USART_IT_TXE,ENABLE); } |