stm32之USART/UART應用實例(詳細)

  • 硬件:STM32F103VCT6
  • 開發工具:Keil uVision4
  • 下載調試工具:ARM仿真器

USART與UARTD的區別:
usart:全雙工通用異步串行收發器
uart:全雙工通用同步/異步串行收發器
usart支持同步通訊時比uart多一條時鐘線,usart用於異步通訊時跟uart一樣。

單工: 只能單向傳輸數據
半雙工:某一個時刻只能接受或者發送的雙向傳輸數據
全雙工:**可以同時進行接收和發送數據

異步:發送方發送一幀數據後不需要接受方應答繼續發送下一幀
同步:發送方發送完一幀數據後需要等待接受方應答才能發下一幀

串行:每一傳輸按位進行,在一個導線上一位一位一次傳輸
並行:每次傳輸按兩位或者兩位以上進行,通過幾根導線同一時刻可以進行多位傳輸

波特率:一秒鐘內傳輸多少位數據,單位:Bps(byte 字節每秒),發送設備與接收設備的波特率必須一致。

USART/UART是一種通用的標準接口,根據導線的電壓等不同也分爲很多的同類,比如: RS485, RS422,RS232

stm32的usart編程應用的步驟:
1.串口設備的的初始化
2.串口中斷優先級的定義
3.發送函數USART_SendData、接收函數USART_ReceiveData

第二步是爲了當串口接收到數據的時候系統會從主程序中跳轉到中斷裏面去,然後再進行數據的讀取,當然如果少了這一步也是可以通訊的,方法就是在主函數中不斷查詢是否收到數據,如此會佔用很多資源,所以在所用的芯片有中斷的情況下最好使用中斷。

void USART1_Config(unsigned int bound)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    /*使能端口時鐘*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

    /*USART1-TX輸出腳配置*/
    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);

    /*USART1-RX接收腳配置*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /*串口參數配置*/
    USART_InitStructure.USART_BaudRate = bound;//設置波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//一幀中傳輸或者接收的數據位數(8位/9位)
    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_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    /*配置好參數之後,使能USART1外設*/
    USART_Cmd(USART1, ENABLE); 
    /*USART1終端優先級的配置*/
}   
void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure; 
    /*設置優先級分組*/
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//指定IRQ通道   
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//指定先佔優先級
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//從優先級

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //定義的IRQ是被使能還是失能
    NVIC_Init(&NVIC_InitStructure);
}

/*重定向c庫函數printf到USART1,調用printf會將需要打印的數據從串口發送出去*/
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (unsigned char) ch);
    while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);     //等到USART1發送完成
    return (ch);
}

/*串口發送一個字符*/
void USART_SendChar(USART_TypeDef* pUSARTx, uint8_t c)
{
    USART_SendData(pUSARTx, c);
    while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/
*串口發送一個字符串*/
void USART_SendString(USART_TypeDef* pUSARTx, char* str)
{
    uint32_t n = 0;

    while (*(str + n) != '\0')
    {
        USART_SendChar(pUSARTx, *(str + n));
        n++;
    }
    while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}

int main(void)
{
    USART1_Config(9600);
    NVIC_Configuration();
    printf(“********************************”);
    printf(“hello ward!\r\n”);
    printf(“********************************”);
    While(1){} //阻止程序結束

}

還要在stm32f10x_it.c(中斷函數一般都會放在這裏)文件裏面實現串口中斷的處理函數:

void USART1_IRQHandler(void)
{
    unsigned char code;
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {   
        code=USART_ReceiveData(USART1);
        printf("%c",code);    //將接受到的數據直接返回打印
    }
}

完成以上步驟,接好線就可以在電腦上使用串口調試助手進行調試,stm32會將所接收到的數據從串口再發送出去。
重定向c庫的printf函數還需要在項目設置裏勾選:
這裏寫圖片描述

僅供參考,錯誤之處以及不足之處還望多多指教

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章