STM32串口通信

我的第一個項目是STM32嵌入式系統設計,包括了硬件部分和軟件部分。項目與公共衛生學院合作,主要內容是關于藥劑檢測。
之前做過用51單片機開發板讀取溫度濕度的小項目,主要的任務是代碼的編寫,相比于51單片機這種入門級別的MCU,STM32在各方面性能都領先51單片機,但是使用起來也復雜不少,光是選擇用庫函數法或是寄存器法編程就讓人糾結。
我主要通過視頻+相關文檔的方法來學習STM32。
視頻地址:【正點原子】STM32開發板實驗教程,視頻講的很細,電路原理圖也都有講,不過涉及到原理乏味而又高深。
相對應的實驗配套文檔:正點原子戰艦版資料
其中個人認為最有用的是:
①軟件資料下的軟件壓縮包,有MDK5的安裝包和各種實用軟件,比如程序下載軟件、串口軟件
②STM32F1開發指南,包括庫函數版和寄存器版。
③STM32參考資料文件夾下的STM32中文參考手冊
④STM32F103ZET6
⑤程序源碼,包括庫函數版和寄存器版。

STM32快速簡介

我總結了下我對STM32的理解:

STM32是ST公司生產的MCU,32位,內核是ARM公司的Cortex內核。Cortex內核有A,R,M三個系列,STM32主要是Cortex-M系列。Cortex-M3內核在各方面都領先于ARM7內核,成本也更低。

配置程序的模板框架其實挺復雜的,但其實不需要自己一步一步的建立,直接套用程序源碼中的模板就好了。現成的有STM32F103系列和STM32F407系列的模板。

為了方便開發,我最后選擇的是庫函數法。本文以串口通信作為例子,盡量詳盡的給出模板,中間必須要用到的頭函數定義和GPIO函數也進行了一定的介紹。

頭文件設置
#ifndef __XXX_H
#define __XXX_H                
#include "XXXXXX.h"
void XXX//各種函數聲明
#define LED0 PAout(1)//各種宏定義,PAout(1)這樣的位帶操作在sys.h中定義

#endif
GPIO的設置,包括輸入輸出
(1)初始化
 GPIO_InitTypeDef  GPIO_InitStructure;  //定義名稱為GPIO_InitStructure的結構體
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;               //LED0-->PB.5 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //推挽輸出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //IO口速度為50MHz,數值感覺不太重要
 GPIO_Init(GPIOB, &GPIO_InitStructure);                  //根據設定參數初始化GPIOB.5

其中GPIO_InitTypeDef是一個結構體,主要包括GPIO的引腳、速度、模式三個參數。

typedef struct
{
  uint16_t GPIO_Pin;         //GPIO_Pin_0到GPIO_Pin_15         
  GPIOSpeed_TypeDef GPIO_Speed; 
  GPIOMode_TypeDef GPIO_Mode;  
}GPIO_InitTypeDef;

GPIO_Speed的參數規范為:

typedef enum
{ 
  GPIO_Speed_10MHz = 1,
  GPIO_Speed_2MHz, 
  GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;

輸出模式必須配置,輸入模式無須配置。設置端口的翻轉速度級別為50MHz,這種級別時端口能輸出頻率很高的信號,但要求外設的容性負載很小。另外還有2MHz和10MHz級別的,能驅動容性負載較大的外設。
GPIO_Mode的參數規范為:

typedef enum
{ GPIO_Mode_AIN = 0x0,              //模擬輸入
  GPIO_Mode_IN_FLOATING = 0x04,     //浮空輸入
  GPIO_Mode_IPD = 0x28,             //下拉輸入  
  GPIO_Mode_IPU = 0x48,             //上拉輸入
  GPIO_Mode_Out_OD = 0x14,          //開漏輸出
  GPIO_Mode_Out_PP = 0x10,          //通用推挽輸出
  GPIO_Mode_AF_OD = 0x1C,           //復用開漏輸出
  GPIO_Mode_AF_PP = 0x18            //復用推挽輸出
}GPIOMode_TypeDef;

各種輸出輸入模式應用場合:
http://www.openedv.com/posts/list/21980.htm

(2)信號輸出和檢測輸入

有相應的庫函數

GPIO_SetBits(GPIOE,GPIO_Pin_5);   //LED1對應引腳GPIOE.5拉高
GPIO_ResetBits(GPIOB,GPIO_Pin_5);  //LED0對應引腳GPIOB.5拉低
GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4);//讀取GPIOE.4的輸入

用位帶操作法比較方便

PAout(1) = 1;
PBin(2);
按鍵設置(以低電平觸發為例)

其中u8是無符號數字8位的意思,進行過宏定義。

//mode=0時,不支持連按;mode=1時,支持連按
u8 KEY_Scan(u8 mode)
{    
    static u8 key_up=1;//按鍵按松開標志
    if(mode)key_up=1;  //支持連按         
    if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
    {
        delay_ms(10);//去抖動 
        key_up=0;
        if(KEY0==0)return KEY0_PRES;
        else if(KEY1==0)return KEY1_PRES;
        else if(KEY2==0)return KEY2_PRES;
        else if(WK_UP==1)return WKUP_PRES;
    }else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;      
    return 0;// 無按鍵按下
}
串口通信

串口配置的一般步驟(以USART1為例,PA9為TX發送端,PA10為RX接收端為例):
①串口時鐘使能,GPIO時鐘使能:

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);    

其他串口可能是RCC_APB1PeriphClockCmd();
②串口復位(可不寫):

USART_DeInit(USART1);

③GPIO端口模式設置:

STM32中文參考手冊P110
GPIO_InitTypeDef  GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;               
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;      //復用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;    
GPIO_Init(GPIOA, &GPIO_InitStructure);               

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;              
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);    

④串口參數初始化:

USART_InitTypeDef  USART_InittStructure;

USART_InittStructure.USART_BaudRate = 115200;  //波特率
USART_InittStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流設置
USART_InittStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; //接收發送模式
USART_InittStructure.USART_Parity = USART_Parity_No; //奇偶校驗位
USART_InittStructure.USART_StopBits = USART_StopBits_1; //停止位
USART_InittStructure.USART_WordLength = USART_WordLength_8b; //字長
     
USART_Init(USART1, &USART_InittStructure);

⑤開啟中斷并且初始化NVIC(如果需要開啟中斷才需要這個步驟)

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //分組2,放到主函數main的開頭位置
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  //設置中斷類型,USART_IT_RXNE表示接收緩沖區非空
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中斷,在stm32F10x.h中有定義
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //搶占優先級為1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //響應優先級為2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能

NVIC_Init(&NVIC_InitStructure);

⑥串口使能:

USART_Cmd(USART1, ENABLE);

⑦編寫中斷處理函數:

//會和system文件夾里的usart.h有沖突,刪掉usart.h。
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
              {
   
               }
}

⑧串口數據收發操作:

USART_SendData(USART1, uint16_t Data);
USART_ReceiveData(USART1);

串口通信需要的軟硬件設置:
①安裝CH340驅動(在軟件目錄下),讓電腦USB口能變成串口
②開發板USB口選擇USB_232(如圖)
③PA9、PA10通過跳線帽分別與RXD、TXD相連(如圖)


利用串口輸入指令控制程序
 int main(void)
 {      
    u16 len;
    u8 flag = 0;
    delay_init();            //延時函數初始化    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級
    uart_init(115200);   //串口初始化為115200
    LED_Init();              //LED端口初始化
    KEY_Init();          //初始化與按鍵連接的硬件接口
    MCP9808_init(); //溫度傳感器初始化
    while(1)
    {
        if(USART_RX_STA&0x8000) //第15位標志位為1時表示接收完成
        {                      
            len=USART_RX_STA&0x3fff;//得到此次接收到的數據長度,第0位~第13位
            
            if(USART_RX_BUF[len-1]=='E')//指令以E(END)結束
            {
                if(USART_RX_BUF[0]=='R'&USART_RX_BUF[1]=='T'&USART_RX_BUF[2]==' '&len==4)  //指令為RT E
                {
                    printf("溫度為%.2f℃\r\n",MCP9808_ReadTP());  //顯示溫度
                    flag = 0;
                }
                else
                    flag = 1;
            }
            else
                flag = 1;       
            if(flag==1)
            {
                flag =0;
                printf("錯誤\r\n");
            }
            else
                printf("代碼已執行\r\n");
            USART_RX_STA = 0;
        }
    }    
 }

可以根據需求再增加指令。

關于串口1下載程序:
下載軟件設置

orient/strip%7CimageView2/2/w/1240)
BOOT0=1,BOOT1=0,如果下載一直識別不出來,嘗試按一按RST鍵。
下載完成后,由于軟件勾上了編成后執行,程序會開始執行。
若需要按RST鍵復位程序,需要再把BOOT0拉低。否則按RST鍵程序不會執行。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容