stm32-8串口通信

来源:互联网 发布:网络流行歌曲 编辑:程序博客网 时间:2024/06/05 11:35

stm32-8串口通信


      • stm32-8串口通信
        • 一 串口通信相关
          • 知识点
          • 串口工作过程
        • 二分析程序
          • main函数中调用了USART1的配置函数
          • 函数USART1_Config主要完成了以下功能
          • 跟踪其中的USART_Cmd函数找到了它函数操作单片机的寄存器实现了对USART1的控制使能失能
          • print函数重定向


一 串口通信相关

1. 知识点
  • stm32串口功能
    • 支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。使用多缓冲器配置的DMA方式,可以实现高速数据通信。
  • 设置参数
    • 字长
    • 波特率
    • 奇偶校验位
    • 停止位
  • 直通线和交叉线
    • 实现全双工串口通信,交叉线
    • 引出用杜邦线连接
2. 串口工作过程
  • 波特率控制
    • 波特率:每秒传输的二进制位数
    • USART_BRR
  • 收发控制
    • USART_CR1-3
    • USART_SR
  • 数据存储转移
    • 内核或DMA将数据从内存(变量)写入发送数据寄存器TDR,发送控制器会适时的把数据从发送数据寄存器 TDR加载到发送移位寄存器,然后通过串口线Tx一位位发送

二、分析程序


1. main函数中调用了USART1的配置函数
/* USART1 config 115200 8-N-1 */        USART1_Config();

2. 函数USART1_Config()主要完成了以下功能:
  1. 使能USART1的时钟
  2. 配置USART1的IO
  3. 配置USART1的工作模式:115200-8-n-1

以下是跟踪到bsp_usart1.c中的函数定义

/**  * @brief  USART1 GPIO   * @param  * @retval  */void USART1_Config(void){    GPIO_InitTypeDef GPIO_InitStructure;    USART_InitTypeDef USART_InitStructure;    /* config USART1 clock */    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);    /* 初始化USART1和GPIOA的时钟,其中使用了PA9和PA10的默认复用USART1功能 */    /* USART1 GPIO config */    /* Configure USART1 Tx (PA.09) as alternate function push-pull */    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        /*复用推挽输出模式*/    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_Init(GPIOA, &GPIO_InitStructure);    /* Configure USART1 Rx (PA.10) as input floating */    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  /*浮空输入模式*/    GPIO_Init(GPIOA, &GPIO_InitStructure);    /* USART1 mode config */    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;    USART_Init(USART1, &USART_InitStructure);     USART_Cmd(USART1, ENABLE);}

跟踪到USART_InitTypeDef 结构体类型的定义

/**   * @brief  USART Init Structure definition    */ typedef struct{//波特率  uint32_t USART_BaudRate;              /*!< This member configures the USART communication baud rate.       The baud rate is computed计算 using the following formula公式:       - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate)))整数部分       - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */小数部分//数据位数  uint16_t USART_WordLength;            /*!< Specifies the number of data bits transmitted or received in a frame.       This parameter can be a value of @ref USART_Word_Length *///停止位数目  uint16_t USART_StopBits;              /*!< Specifies the number of stop bits transmitted.       This parameter can be a value of @ref USART_Stop_Bits *///奇偶模式  uint16_t USART_Parity;                /*!< Specifies the parity mode.       This parameter can be a value of @ref USART_Parity       @note When parity is enabled, the computed parity is inserted            at the MSB position of the transmitted data (9th bit when           the word length is set to 9 data bits; 8th bit when the           word length is set to 8 data bits). */ //接受或发送  uint16_t USART_Mode;                  /*!< Specifies wether the Receive or Transmit mode is enabled or disabled.       This parameter can be a value of @ref USART_Mode *///时钟使能失能  uint16_t USART_HardwareFlowControl;   /*!< Specifies wether the hardware flow control mode is enabled or disabled.       This parameter can be a value of @ref USART_Hardware_Flow_Control */} USART_InitTypeDef;

翻阅32固件库手册找到了Table707,708便是对以上结构体定义的解释


3. 跟踪其中的USART_Cmd();函数找到了它,函数操作单片机的寄存器实现了对USART1的控制:使能失能

控制寄存器USART_CR1中的UE位,即USART使能位

/**  * @brief  Enables or disables the specified USART peripheral.  * @param  USARTx: Select the USART or the UART peripheral.   *         This parameter can be one of the following values:  *           USART1, USART2, USART3, UART4 or UART5.  * @param  NewState: new state of the USARTx peripheral.  *         This parameter can be: ENABLE or DISABLE.  * @retval None  */void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState){  /* Check the parameters */  assert_param(IS_USART_ALL_PERIPH(USARTx));  assert_param(IS_FUNCTIONAL_STATE(NewState));  if (NewState != DISABLE)  {    /* Enable the selected USART by setting the UE bit in the CR1 register */    USARTx->CR1 |= CR1_UE_Set;  }  else  {    /* Disable the selected USART by clearing the UE bit in the CR1 register */    USARTx->CR1 &= CR1_UE_Reset;  }}

4.print函数重定向

重定向指用户可以自己重写C的库函数,当链接器检查到用户编写了与C库函数相同名字的函数时,优先采用用户编写的函数,这样用户就可以实现对库的修改了。

///重定向c库函数printf到USART1int fputc(int ch, FILE *f){        /* 发送一个字节数据到USART1 */        USART_SendData(USART1, (uint8_t) ch);        /* 等待发送完毕 */        while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);               return (ch);}///重定向c库函数scanf到USART1int fgetc(FILE *f){        /* 等待串口1输入数据 */        while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);        return (int)USART_ReceiveData(USART1);}

函数USART_SendData发送一个字节数据

/**  * @brief  Transmits single data through the USARTx peripheral.  * @param  USARTx: Select the USART or the UART peripheral.   *   This parameter can be one of the following values:  *   USART1, USART2, USART3, UART4 or UART5.  * @param  Data: the data to transmit.  * @retval None  */void USART_SendData(USART_TypeDef* USARTx, uint16_t Data){  /* Check the parameters */  assert_param(IS_USART_ALL_PERIPH(USARTx));  assert_param(IS_USART_DATA(Data));   /* Transmit Data */  USARTx->DR = (Data & (uint16_t)0x01FF);}

函数USART_ReceiveData:返回 USARTx 最近接收到的数据

/**  * @brief  Returns the most recent received data by the USARTx peripheral.  * @param  USARTx: Select the USART or the UART peripheral.   *   This parameter can be one of the following values:  *   USART1, USART2, USART3, UART4 or UART5.  * @retval The received data.  */uint16_t USART_ReceiveData(USART_TypeDef* USARTx){  /* Check the parameters */  assert_param(IS_USART_ALL_PERIPH(USARTx));  /* Receive Data */  return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);}

数据寄存器DR低八位包含了发送或接收的数据。
由于它是由两个寄存器组成的,一个给发送用(TDR),一个给接收用(RDR),该寄存器兼具读和写的功能。
TDR寄存器提供了内部总线和输出移位寄存器之间的并行接口(参见图236)。
RDR寄存器提供了输入移位寄存器和内部总线之间的并行接口。
当使能校验位(USART_CR1种PCE位被置位)进行发送时,写到MSB的值根据数据的长度不同, MSB是第7位或者第8位)会被后来的校验位该取代。当使能校验位进行接收时,读到的MSB位是接收到的校验位。


函数USART_GetFlagStatus是用来检查指定的 USART 标志位设置与否其中第二个参数是待检查位,函数还有其他可以检查的位,如下

USART_FLAG_CTS CTS 标志位
USART_FLAG_LBD LIN 中断检测标志位
USART_FLAG_TXE 发送数据寄存器空标志位
USART_FLAG_TC 发送完成标志位
USART_FLAG_RXNE 接收数据寄存器非空标志位
USART_FLAG_IDLE 空闲总线标志位
USART_FLAG_ORE 溢出错误标志位
USART_FLAG_NE 噪声错误标志位
USART_FLAG_FE 帧错误标志位
USART_FLAG_PE 奇偶错误标志位

/**  * @brief  Checks whether the specified USART flag is set or not.  * @param  USARTx: Select the USART or the UART peripheral.   *   This parameter can be one of the following values:  *   USART1, USART2, USART3, UART4 or UART5.  * @param  USART_FLAG: specifies the flag to check.  *   This parameter can be one of the following values:  *     @arg USART_FLAG_CTS:  CTS Change flag (not available for UART4 and UART5)  *     @arg USART_FLAG_LBD:  LIN Break detection flag  *     @arg USART_FLAG_TXE:  Transmit data register empty flag  *     @arg USART_FLAG_TC:   Transmission Complete flag  *     @arg USART_FLAG_RXNE: Receive data register not empty flag  *     @arg USART_FLAG_IDLE: Idle Line detection flag  *     @arg USART_FLAG_ORE:  OverRun Error flag  *     @arg USART_FLAG_NE:   Noise Error flag  *     @arg USART_FLAG_FE:   Framing Error flag  *     @arg USART_FLAG_PE:   Parity Error flag  * @retval The new state of USART_FLAG (SET or RESET).  */FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG){  FlagStatus bitstatus = RESET;  /* 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 */  if (USART_FLAG == USART_FLAG_CTS)  {    assert_param(IS_USART_123_PERIPH(USARTx));  }    if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)  {    bitstatus = SET;  }  else  {    bitstatus = RESET;  }  return bitstatus;}
0 0
原创粉丝点击