STM32之串口

来源:互联网 发布:手机流量监测软件 编辑:程序博客网 时间:2024/06/05 08:55

众所周知,现今开发板上的485和232是用来进行断距离通信的。对于单片机来说,实际中的通信是用485还是232,没有区别。因为他们两者都用的是单片机的串口功能。

之所以不同,是因为485的硬件通信是通过差分方式来进行的,而232是共模信号,TX和RX是对地的信号。因而在实际接线中,232需将TX和RX还要地线都接上,而485只需接A和B即可。

好了,现在简单介绍一下,STM32库函数讲解串口的常用发送和接收方式。

串口发送和接收引脚是GPIO的复用,所以串口初始化需要使能响应的GPIO和时钟。
GPIO使能:
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

#ifdef USE_STM3210C_EVAL 
  /* Enable the USART2 Pins Software Remapping */
  GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);  
#elif defined(USE_STM3210B_EVAL) || defined(USE_STM32100B_EVAL)
  /* Enable the USART2 Pins Software Remapping */
  GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
#endif

  /* Configure USARTy Rx as input floating */
  GPIO_InitStructure.GPIO_Pin = USARTy_RxPin;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);
  
  /* Configure USARTy Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = USARTy_TxPin;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(USARTy_GPIO, &GPIO_InitStructure); 
}


时钟使能:
  /* Enable GPIO clock */
  RCC_APB2PeriphClockCmd(USARTy_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);

#ifndef USE_STM3210C_EVAL
  /* Enable USARTy Clock */
  RCC_APB2PeriphClockCmd(USARTy_CLK, ENABLE); 
#else
  /* Enable USARTy Clock */
  RCC_APB1PeriphClockCmd(USARTy_CLK, ENABLE); 
#endif

接下来初始化串口参数:
USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  
  /* Configure USARTy */
  USART_Init(USARTy, &USART_InitStructure);

/************************************************************************************************/

先介绍查询方式。


发送:


void SendByte(uint8_t ch)
{
  USART_SendData(EVAL_COM1, (uint8_t) ch);
  while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)
  {}
}



接收:


uint8_t RecvgByte(void)
{
    while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_RXNE) == RESET)
    {}
    return USART_ReceiveData(EVAL_COM1);
}

/************************************************************************************************/


/************************************************************************************************/

使用中断方式时,还需要配置中断:
NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the USARTz Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);


中断响应函数:
  if(USART_GetITStatus(USARTy, USART_IT_RXNE) != RESET)
  {
    /* Read one byte from the receive data register */
    RxBuffer[RxCounter] = USART_ReceiveData(USARTy);
        
    if(RxBuffer[RxCounter-1] == '\r' && RxBuffer[RxCounter] == '\n')
    {
      /* 关闭接受中断,开启发送中断 */
      USART_ITConfig(USARTy, USART_IT_RXNE, DISABLE);
      USART_ITConfig(USARTy, USART_IT_TXE,  ENABLE);
    }

        RxCounter++;
  }
  
  if(USART_GetITStatus(USARTy, USART_IT_TXE) != RESET)
  {   
    /* Write one byte to the transmit data register */

        USART_SendData(USARTy,RxBuffer[TxCounter++]);
        if(TxCounter == RxCounter)
        {
                RxCounter = 0;
                TxCounter = 0;
                /* 关闭接受中断,开启发送中断 */
            USART_ITConfig(USARTy, USART_IT_RXNE, ENABLE);
            USART_ITConfig(USARTy, USART_IT_TXE,  DISABLE);
     } 
  }


中断管理函数:
开发送中断:
USART_ITConfig(USARTy, USART_IT_TXE, ENABLE);
开发送中断:
USART_ITConfig(USARTy, USART_IT_TXE, DISABLE);
开接收中断:
USART_ITConfig(USARTy, USART_IT_RXNE, ENABLE);
关接收中断:
USART_ITConfig(USARTy, USART_IT_RXNE, DISABLE);


原创粉丝点击