你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C++封装类 USART

[复制链接]
wecreate 发布时间:2019-8-16 18:24
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->ortNo,ENABLE);
//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->inNo/2) ,GPIO_AF_USART1);
    GPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX->inNo/2) ,GPIO_AF_USART1);
  break;
  case 3:
  case 4:
  case 5:
    GPIO_PinAFConfig(TX->GPIO,GPIO_PinSource0 + (TX->inNo/2) ,GPIO_AF_UART4);
    GPIO_PinAFConfig(RX->GPIO,GPIO_PinSource0 + (RX->inNo/2) ,GPIO_AF_UART4);
    break;
  
}


/*
RX.setMode(GPIO_Mode_AF);
RX.setType(GPIO_OType_PP);
TX.setMode(GPIO_Mode_AF);
TX.setType(GPIO_OType_PP);
*/

Tx=TX->in;
Rx=RX->in;

  //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);
}
收藏 评论0 发布时间:2019-8-16 18:24

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版