1. 程式人生 > 實用技巧 >《SLAM機器人基礎教程》第三章 微控制器與STM32:串列埠收發實驗

《SLAM機器人基礎教程》第三章 微控制器與STM32:串列埠收發實驗

3.4節串列埠收發實驗

本節將學習STM32使用串列埠與電腦進行通訊

a.實驗準備:USB轉串列埠模組,ST-Llink下載器,CHEAPX機器人控制板

b.實驗目的:STM32串列埠的使用

c.相關知識點:

串列埠是一種電子裝置間常用的序列通訊方式,電子工程師在除錯裝置時也經常使用該通訊方式輸出除錯資訊。串列埠是全雙工通訊,即可以同時收資料和發資料。發資料使用TX管腳,收資料使用RX管腳。STM32中的USART串列埠外設已經實現了串列埠底層協議,所以我們直接使用就行。STM32中的USART串列埠通訊,一般使用中斷模式。但有資料過來是,產生中斷訊號,CPU直接跳轉進中斷函式執行。注意,STM32是單核單執行緒處理器,硬體中斷的存在,讓STM32可以實現上位機多執行緒類似效果。

d.程式設計及執行

(1)初始化晶片的串列埠管腳A9 A10和配置USART,位置如下圖。步驟如下:開啟對應GPIO口,串列埠的時鐘,再配置管腳引數,配置串列埠引數。

void initDebugSerial(u32 bound){

  GPIO_InitTypeDef  GPIO_InitStruct;
    USART_InitTypeDef USART_InitStruct;
    NVIC_InitTypeDef  NVIC_InitStruct;
    
    //Config Clock 配置時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);    //
Enable Clock:USART1,GPIOA //Config GPIO A9 A10 配置晶片管腳 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStruct);//傳入結構GPIO_InitStruct,配置GPIOA GPIO_InitStruct.GPIO_Pin
= GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStruct); //傳入結構GPIO_InitStruct,配置GPIOA //Config NVIC 配置中斷 NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; //IRQChannel 配置中斷通道為USART1_IRQn NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3 ;//PreemptionPriority 搶佔優先順序 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3; //SubPriority 子優先順序 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //ENABLE IRQChannel 使能中斷通道 NVIC_Init(&NVIC_InitStruct); //傳入結構體NVIC_InitStruct,配置NVIC //Config USART 配置串列埠 USART_InitStruct.USART_BaudRate = bound; //bound 波特率 USART_InitStruct.USART_WordLength = USART_WordLength_8b;//WordLength 字長8位 USART_InitStruct.USART_StopBits = USART_StopBits_1;//StopBits 停止位 USART_InitStruct.USART_Parity = USART_Parity_No;//Parity 奇偶校驗 USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//HardwareFlowControl USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //USART_Mode 串列埠模式:收發模式 USART_Init(USART1, &USART_InitStruct); //傳入結構體USART_InitStruct,配置串列埠USART1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能串列埠中斷 USART_Cmd(USART1, ENABLE); //使能串列埠 }

(2)編寫串列埠接收中斷函式。使用陣列debugRxBuf[20]儲存接收到的資料(每接收到一個8位資料,產生一次中斷,執行一次USART1_IRQHandler()函式),全域性變數debugRxCount用於計數,同時改變陣列debugRxBuf[20]下標值,實現資料從debugRxBuf[0],debugRxBuf[1].....依次儲存。

u8  debugRxBuf[20]; 
u8  debugRxCount=0;
void USART1_IRQHandler(void)    //串列埠1中斷函式,函式名不可改,已在彙編檔案startup_stm32f10x_hd.s 中規定好     
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中斷(接收到串列埠資料)
    {
        debugRxBuf[debugRxCount] =USART_ReceiveData(USART1);    //讀取接收到的資料        
        debugRxCount++;//計數
    }
} 

(3)編寫主函式,如下:

//串列埠收發實驗
int main(void)
{        
    u8 i;
    u8 txbuf[10]={0,1,2,3,4,5,6,7,8,9};
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //PriorityGroupConfig NVIC中斷分組設定 組2(2位搶佔優先順序,2位響應優先順序)
    initDebugSerial(500000);

    //先往串列埠傳送十個數
    for(i=0;i<10;i++)
    {
            while((USART1->SR&0X40)==0);//等待發送完畢   
            USART1->DR = txbuf[i];      //填充資料
    }
    
    while(1)
    {
        if(debugRxCount>=10)//接收滿10個位元組,返回該10個數
        {
            for(i=0;i<10;i++)
            {
                txbuf[i]=debugRxBuf[i];
            }
            debugRxCount=0;//重新從debugRxBuf[0]開始填充
            
            for(i=0;i<10;i++)
            {
                while((USART1->SR&0X40)==0);//等待發送完畢   
                USART1->DR = txbuf[i];      //填充資料
            }
        }
    }
}

(4)編譯執行。步驟如下:開啟sscom串列埠助手軟體,並連線USB轉串列埠模組的埠,sscom串列埠軟體配置如下圖。

(5)實驗結果:如上圖所示,程式執行時,串列埠首先收到十個HEX十六進位制資料。我們在sscom串列埠助手的資料輸入視窗中,編寫十個十六進位制數,點擊發送。然後回收微控制器回傳的這十個數。

e.實驗總結:串列埠的初始化配置和GPIO配置一樣,都有標準流程,我們後續使用串列埠時,參考該程式就可以了。