5# 關(guān)于 STM32 中 USART 庫文件

1. 前言

??USART是通用(U)同步(S)異步(A)收(R)發(fā)(T)器。
??STM32F103VGT6上有3個(gè)USART和2個(gè)UART。
??同步與異步的區(qū)別是:
??通信時(shí)是否需要對外提供時(shí)鐘輸出。
官方的usart頭文件為:
stm32f10x_usart.h

2. 關(guān)于結(jié)構(gòu)體

??USART有2個(gè)結(jié)構(gòu)體:
與USART運(yùn)行相關(guān):
USART_InitTypeDef
成員有:
??// 波特率
??USART_BaudRate
??// 字長
??USART_WordLength
??// 停止位
??USART_StopBits
??// 校驗(yàn)位
??USART_Parity
??// USART模式
??USART_Mode
??// 硬件流控制
??USART_HardwareFlowControl
與該成員相關(guān)的宏定義有:
??USART_WordLength
????USART_WordLength_8b
????USART_WordLength_9b
??USART_Stop_Bits
????USART_StopBits_1
????USART_StopBits_0_5
????USART_StopBits_2
????USART_StopBits_1_5
??USART_Parity
????USART_Parity_No
????USART_Parity_Even
????USART_Parity_Odd
??USART_Mode
????USART_Mode_Rx
????USART_Mode_Tx
??USART_Hardware_Flow_Control
????USART_HardwareFlowControl_None
????USART_HardwareFlowControl_RTS
????USART_HardwareFlowControl_CTS
????USART_HardwareFlowControl_RTS_CTS


另一個(gè)結(jié)構(gòu)體與同步通信相關(guān)。
USART_ClockInitTypeDef
成員有:
??USART_Clock // 時(shí)鐘使能控制
??USART_CPOL // 時(shí)鐘極性控制
??USART_CPHA // 時(shí)鐘相位控制
??USART_LastBit // 最尾位時(shí)鐘脈沖控制
該類成員相關(guān)的宏定義
??USART_Clock
????USART_Clock_Disable
????USART_Clock_Enable
??USART_CPOL
????USART_CPOL_Low
????USART_CPOL_High
??USART_CPHA
????USART_CPHA_1Edge
????USART_CPHA_2Edge
??USART_LastBit
????USART_LastBit_Disable
????USART_LastBit_Enable

3. 關(guān)于函數(shù)方法

// 使用輸入的配置信息USART_InitStruct對于USARTx,進(jìn)行初始化
USART_Init(USART_TypeDef* USARTx,USART_InitTypeDef* USART_InitStruct);
// 使能串口接收中斷
USART_ITConfig(USART_TypeDef* USARTx,uint16_t USART_IT, FunctionalState NewState);
// 使能串口USARTx,NewState=>(ENABLE/DISABLE)
USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
// 在 USARTx 中發(fā)送數(shù)據(jù)Data
USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
// 確認(rèn)串口USARTx的一些標(biāo)志位是 set狀態(tài)還是reset狀態(tài)
USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
??USART_FLAG有:
????USART_FLAG_CTS
????USART_FLAG_LBD
????USART_FLAG_TXE 數(shù)據(jù)發(fā)送寄存器是否為空
????USART_FLAG_TC 數(shù)據(jù)發(fā)送完成標(biāo)志
????USART_FLAG_RXNE 數(shù)據(jù)接收寄存器是否不為空
????USART_FLAG_IDLE
????USART_FLAG_ORE
????USART_FLAG_NE
????USART_FLAG_FE
????USART_FLAG_PE
// 類似USART_GetFlagStatus,但是專門用來判斷中斷時(shí)間的狀態(tài)
USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
??USART_IT有:
????USART_IT_CTS
????USART_IT_LBD
????USART_IT_TXE
????USART_IT_TC
????USART_IT_RXNE 數(shù)據(jù)接收寄存器是否不為空
????USART_IT_IDLE
????USART_IT_ORE_RX
????USART_IT_ORE_ER
????USART_IT_NE
????USART_IT_FE
????USART_IT_PE
// 獲取USARTx接收到的數(shù)據(jù)
USART_ReceiveData(USART_TypeDef* USARTx);

4. 可用模板

  1. 初始化USART1
    USART_Config代碼
void USART_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    // TODO0:初始化時(shí)鐘
    // 0.1打開串口GPIO的時(shí)鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    // 0.2打開串口外設(shè)的時(shí)鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    // TODO1:初始化GPIO
    // TODO1.1:將USART Tx的GPIO配置為推挽復(fù)用模式
    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);
    
    // TODO1.2:將USART Rx的GPIO配置為浮空輸入模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    // TODO2: 初始化USART
    // 配置串口的工作參數(shù)
    // 配置波特率
    USART_InitStructure.USART_BaudRate = 115200;
    // 配置 針數(shù)據(jù)字長
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    // 配置停止位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    // 配置校驗(yàn)位
    USART_InitStructure.USART_Parity = USART_Parity_No ;
    // 配置硬件流控制
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    // 配置工作模式,收發(fā)一起
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    // 完成串口的初始化配置
    USART_Init(DEBUG_USARTx, &USART_InitStructure);
    
    // TODO3:初始化NVIC
    // 串口中斷優(yōu)先級配置
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 嵌套向量中斷控制器組選擇 */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    /* 配置USART為中斷源 */
    NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
    /* 搶斷優(yōu)先級*/
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    /* 子優(yōu)先級 */
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    /* 使能中斷 */
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    /* 初始化配置NVIC */
    NVIC_Init(&NVIC_InitStructure);
    
    // 使能串口接收中斷
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  
    // TODO4:使能串口
    USART_Cmd(USART1, ENABLE);      
}

備注:

??如果想使用printf來打印調(diào)試信息,則生成項(xiàng)目時(shí)候需要如下勾選:

image.png

??會(huì)生成兩個(gè)文件:
????syscalls.c和tiny_printf.c


image.png

修改 syscalls.c 中的 _write 函數(shù)如下:

int _write(int32_t file, uint8_t *ptr, int32_t len)
{
    /* Implement your write code here, this is used by puts and printf for example */
   int DataIdx;
   for (DataIdx = 0; DataIdx < len;DataIdx++)
   {
         __io_putchar(*ptr++);

   }
   /* return len; */
   return len;
}

并在開頭加入:

#include "bsp_usart.h"
int __io_putchar(int ch)
{
    /* 發(fā)送一個(gè)字節(jié)數(shù)據(jù)到串口 */
    USART_SendData(DEBUG_USARTx, (uint8_t) ch);
    /* 等待發(fā)送完畢 */
    while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
    return (ch);
}

這樣就能使用printf了。

5. 樣例項(xiàng)目

程序中自己編寫“bsp_usart.c”,“bsp_usart.h”,“main.c”這三個(gè)文件:
“bsp_usart.c”文件如下:

#include "bsp_usart.h"
void USART1_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    // TODO0:初始化時(shí)鐘
    // 0.1打開串口GPIO的時(shí)鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 0.2打開串口外設(shè)的時(shí)鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    // TODO1:初始化GPIO
    // TODO1.1:將USART Tx的GPIO配置為推挽復(fù)用模式
    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);

    // TODO1.2:將USART Rx的GPIO配置為浮空輸入模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    // TODO2: 初始化USART
    // 配置串口的工作參數(shù)
    // 配置波特率
    USART_InitStructure.USART_BaudRate = 115200;
    // 配置 針數(shù)據(jù)字長
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    // 配置停止位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    // 配置校驗(yàn)位
    USART_InitStructure.USART_Parity = USART_Parity_No ;
    // 配置硬件流控制
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    // 配置工作模式,收發(fā)一起
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    // 完成串口的初始化配置
    USART_Init(USART1, &USART_InitStructure);

    // TODO3:初始化NVIC
    // 串口中斷優(yōu)先級配置
    NVIC_InitTypeDef NVIC_InitStructure;

    // 嵌套向量中斷控制器組選擇
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    // 配置USART為中斷源
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    // 搶斷優(yōu)先級
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    // 子優(yōu)先級
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    // 使能中斷
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    // 初始化配置NVIC
    NVIC_Init(&NVIC_InitStructure);

    // 使能串口接收中斷
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    // TODO4:使能串口
    USART_Cmd(USART1, ENABLE);
}

void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
    /* 發(fā)送一個(gè)字節(jié)數(shù)據(jù)到USART */
    USART_SendData(pUSARTx,ch);

    /* 等待發(fā)送數(shù)據(jù)寄存器為空 */
    while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}

void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
    unsigned int k=0;
  do 
  {
      Usart_SendByte( pUSARTx, *(str + k) );
      k++;
  } while(*(str + k)!='\0');
  
  /* 等待發(fā)送完成 */
  while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
  {}
}

“bsp_usart.h”文件如下:

#ifndef __USART_H
#define __USART_H

#include "stm32f10x.h"
#include <stdio.h>
void USART1_Config(void);
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch);
void Usart_SendString( USART_TypeDef * pUSARTx, char *str);
#endif

主函數(shù)如下:

#include "stm32f10x.h"
#include "bsp_usart.h"
int main(void)
{
  /*初始化USART 配置模式為 115200 8-N-1,中斷接收*/
  USART1_Config();

    /* 發(fā)送一個(gè)字符串 */
    Usart_SendString( USART1,"hello\n");
    printf("1234\r\n");

  while(1)
    {
        Usart_SendString( USART1,"hello\n");
        printf("1234\r\n");
    }
}

TrueSTUDIO自帶串口通信工具:

image.png
image.png
image.png

由此可見 \r\n 才是真正的回車。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 姓名:周崇杰 學(xué)號(hào):16140120059 專業(yè):機(jī)械設(shè)計(jì)制造及其自動(dòng)化 轉(zhuǎn)載自:http://blog.csd...
    CJbaby閱讀 3,656評論 0 3
  • 有一次做一個(gè)東西,為了盡量不占用CPU的處理數(shù)據(jù)時(shí)間,所以就使用DMA接收串口的數(shù)據(jù),但是呢問題來了.,,,,,怎...
    楊奉武閱讀 3,370評論 0 1
  • 詩仙與詩圣 中國詩歌的黃金時(shí)代——唐朝,有著兩座不可跨越的高峰?!霸娤伞崩畎着c“詩圣”杜甫。他們相差十一歲,...
    王之晗閱讀 512評論 0 8
  • 又是好幾天沒有寫文章,打開簡書,居然還有倆個(gè)文友看了我寫的文章,心里很是感動(dòng)和雀躍,謝謝文友能花自己寶貴的時(shí)間來看...
    木木青苔閱讀 464評論 0 1
  • 常用創(chuàng)建操作符 create、just、from、interval、range、repeat等 實(shí)例與功能介紹 1...
    azu_test閱讀 138評論 0 0

友情鏈接更多精彩內(nèi)容