库函数及寄存器对应

android 串口寄存器ttl协议 串口数据寄存器_数据寄存器


上图为串口的框图,主要有数据寄存器(DR)、状态寄存器(SR)、波特比率寄存器(BRR)。

数据寄存器(DR)包含接收数据寄存器(RDR)和发送数据寄存器(TDR)等。

串口接收数据流程为:RX接口接收到数据,通过编解码模块传输给“接收移位寄存器”,再传递给“接收数据寄存器(RDR)”,再传输给内核。
串口发送数据流程为:内核将数据写入“发送数据寄存器(TDR)”,再将数据存入“发送移位寄存器”,再将数据通过编解码模块输出到TX接口。

图中的发送器时钟和接收器时钟是通过波特比率寄存器(BRR)的设置来控制的
F103芯片的串口1的时钟来源是PCLK2,串口2-4的时钟开源是PCLK1,由BRR寄存器左侧的“/USARTDIV”设置,参数为1或者2,二者时钟频率默认均为72MHz。

状态寄存器(SR)用于存储串口状态,发送器控制单元和接收器控制单元可以对其状态标志位进行更改,其状态标志位可供中断控制单元获取。

控制寄存器(内部参数用于控制串口)

android 串口寄存器ttl协议 串口数据寄存器_android 串口寄存器ttl协议_02


串口使能函数

#define CR1_UE_Set                ((uint16_t)0x2000)
#define CR1_UE_Reset              ((uint16_t)0xDFFF)
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;

void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
{
  /* Check the parameters (验证参数)*/
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  /* Enable the selected USART by setting the UE bit in the CR1 register */
  /*通过在CR1寄存器中设位13来启用所选的串口*/
  if (NewState != DISABLE)
  {  
    USARTx->CR1 |= CR1_UE_Set; 
  }
  /* Disable the selected USART by clearing the UE bit in the CR1 register */
  /*通过在CR1寄存器中设位13来禁用所选的串口*/
  else 
  {  
    USARTx->CR1 &= CR1_UE_Reset;  
  }
}

状态寄存器(存储串口状态)

android 串口寄存器ttl协议 串口数据寄存器_寄存器_03


获取状态标志位函数

typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;  
#define USART_FLAG_CTS  ((uint16_t)0x0200)

FlagStatus USART_GetFlagStatus(USART_TypeDef*  USARTx, uint16_t  USART_FLAG)
{
  FlagStatus bitstatus = RESET;  //声明枚举变量(状态标记)并初始化为0
  /* Check the parameters (验证参数输入是否正确)*/
  assert_param(IS_USART_ALL_PERIPH(USARTx)); //验证是否是正确的串口名
  assert_param(IS_USART_FLAG(USART_FLAG));  //验证标志
  /* The CTS flag is not available for UART4 and UART5 */
  /* CTS标志不适用于UART4和UART5。(见上图位9)*/
  if (USART_FLAG == USART_FLAG_CTS)  //验证串口是否是串口1、2、3
  {
    assert_param(IS_USART_123_PERIPH(USARTx)); 
  }  
  //串口号对应的SR寄存器的值与USART_FLAG进行与运算判断对应位的值是否为1来获取串口的状态,
  if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)  //若上述计算结果如果不等于0  
  { 
    bitstatus = SET;   //状态标记设置为1
  }       
  else 
  {
    bitstatus = RESET;   //否则为设置0
  } 
  return bitstatus;      //返回状态位
}

数据寄存器(存储串口传输数据)

android 串口寄存器ttl协议 串口数据寄存器_stm32_04

android 串口寄存器ttl协议 串口数据寄存器_寄存器_05


串口发送函数

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) //发送数据到串口,DR寄存器
{ 
  /* Check the parameters (验证参数) */
  assert_param(IS_USART_ALL_PERIPH(USARTx));  
  assert_param(IS_USART_DATA(Data)); 
  /* Transmit Data (发送数据)*/  //串口号对应的DR寄存器存入Data数据的9位
  USARTx->DR = (Data & (uint16_t)0x01FF);
}

串口接收函数

uint16_t USART_ReceiveData(USART_TypeDef* USARTx) //接受数据,从DR读取接受到的数据
{  
  /* Check the parameters (验证参数) */
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  /* Receive Data(接受数据) */   //返回寄存器DR寄存器的前9位数据
  return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
}

波特比率寄存器(设置串口通讯的波特率)

android 串口寄存器ttl协议 串口数据寄存器_寄存器_06


android 串口寄存器ttl协议 串口数据寄存器_stm32_07

串口初始化函数中的波特率部分

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
{
  uint32_t  usartxbase = 0 ,  apbclock = 0x00;
  RCC_ClocksTypeDef  RCC_ClocksStatus;
  usartxbase = (uint32_t)USARTx;  //将串口的地址强制转换成32位整数
  RCC_GetClocksFreq(&RCC_ClocksStatus);  //获取时钟频率
  //如果串口地址为串口1的地址则设置时钟源为PCLK2,否则为PCLK1
  if (usartxbase == USART1_BASE)   
  {  
    apbclock = RCC_ClocksStatus.PCLK2_Frequency;  
  }
  else
  {  
    apbclock = RCC_ClocksStatus.PCLK1_Frequency;  
  }
  ……
  //将apbclock经过一系列运算(原理见上图)得到tmpreg,并存入BRR寄存器
  USARTx->BRR = (uint16_t)tmpreg;
}

文中函数和部分内容摘自正点原子stm32资料与官方库函数