STM32學(xué)習(xí)教程<三> USART串口接收數(shù)據(jù)

m_<:整個(gè)程序除去基本配置外由四部分組成,main.c、bsp_usart.c、bsp_led.c和stm32f4xx_it.c。其中,bsp_usart.c及.h負(fù)責(zé)外設(shè)USART寄存器的配置,使其能正常工作。bsp_led.c及.h負(fù)責(zé)外設(shè)LED寄存器的配置,使其能正常工作,main.c則是在USART配置完能正常操作后來實(shí)現(xiàn)USART怎么接收數(shù)據(jù),然后通過控制LED的顏色判斷接收到什么數(shù)據(jù)。在stm32f4xx_it.c中寫入中斷服務(wù)函數(shù),這是本節(jié)重點(diǎn)。

1 main.c

#include "stm32f4xx.h"
#include "./led/bsp_led.h"
#include "./usart/bsp_usart.h"   //可將全局變量引入

int main(void)
{
    LED_GPIO_Config();   //配置GPIO口
    USART_Config();   //配置USART
    while (1)
    {
        if(Flag=='a')   //Flag為全局變量,F(xiàn)lag為我們輸入的字符(后面進(jìn)一步說明)
        {
            Flag == '0';   //Flag復(fù)位
            GPIO_ResetBits(GPIOF, GPIO_Pin_6);   //若輸入為'a',則紅燈亮
        }
        if(Flag=='b')
        {
            Flag == '0';
            GPIO_ResetBits(GPIOF, GPIO_Pin_7);   //若輸入為'b',則綠燈亮
        }
    }
}

2.1 bsp_led.h

#ifndef _BSP_LED_H   //防止重定義
#define _BSP_LED_H
#include "stm32f4xx.h"

void LED_GPIO_Config(void);   //聲明配置函數(shù)

#endif

2.2 bsp_led.c

//bsp: board support package(板級(jí)支持包)
#include "bsp_led.h"       

void LED_GPIO_Config(void)
{
  //以下四個(gè)步驟適合所有外設(shè)的初始化
  /* 第一步:開GPIO的時(shí)鐘 */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);   //GPIOF在AHB1總線上,另外注意,系統(tǒng)時(shí)鐘已經(jīng)自己設(shè)定了
  /* 第二步:定義一個(gè)GPIO初始化結(jié)構(gòu)體 */
  GPIO_InitTypeDef GPIO_InitStruct;
  /* 第三步:配置GPIO初始化結(jié)構(gòu)體的成員 */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;   //Pin6紅色、Pin7綠色、Pin8藍(lán)色
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;   //輸出模式
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;   //推挽輸出
  GPIO_InitStruct.GPIO_Speed = GPIO_Low_Speed;   //2MHz
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;    //上拉電阻
  /* 第四步:調(diào)用GPIO初始化函數(shù),把配置好的結(jié)構(gòu)體的成員的參數(shù)寫入寄存器 */
  GPIO_Init(GPIOF, &GPIO_InitStruct);   //將上述參數(shù)賦給GPIOF
  GPIO_SetBits(GPIOF,GPIO_Pin_6);   //輸出置1,紅燈滅
  /* 配置綠燈GPIO引腳 */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;   //Pin7綠色
  GPIO_Init(GPIOF, &GPIO_InitStruct); 
  GPIO_SetBits(GPIOF,GPIO_Pin_6);   //輸出置1,綠燈滅
}

3.1 bsp_usart.h

#ifndef __BSP_USART_H
#define __BSP_USART_H

#include "stm32f4xx.h"

extern char Flag;   //聲明全局變量Flag

void USART_Config(void);  //配置USART

#endif

3.2 bsp_usart.c

#include "./usart/bsp_usart.h"

char Flag = '0';   //定義變量Flag,在頭文件中聲明為全局變量
/***************** 配置USART發(fā)送數(shù)據(jù)中斷 **********************/
static void NVIC_Configuration(void)
{
 NVIC_InitTypeDef NVIC_InitStructure;   //定義一個(gè)中斷結(jié)構(gòu)體
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //選擇嵌套向量中斷控制器組
 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;   //設(shè)置USART為中斷源
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   //搶斷優(yōu)先級(jí)為1
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;   //子優(yōu)先級(jí)為1
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //使能中斷 
 NVIC_Init(&NVIC_InitStructure);   // 初始化NVIC
}

void USART_Config(void)
{
/* 第一步:初始化GPIO */
 GPIO_InitTypeDef GPIO_InitStructure;   //TX與PA9相連,RX與PA10相連
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOA, ENABLE);   //使能GPIO時(shí)鐘
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 /* 配置Tx引腳為復(fù)用功能  */
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;   //選擇復(fù)用模式
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  //選擇復(fù)用的發(fā)送引腳     
 GPIO_Init(GPIOA, &GPIO_InitStructure);   //初始化GPIO
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;   //選擇復(fù)用的接收引腳
 GPIO_Init(GPIOA, &GPIO_InitStructure);   //初始化GPIO
 GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);   //將PA9復(fù)用到USART1的TX上
 GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);   //將PA10復(fù)用到USART1的RX上
 /* 第二步:配置串口初始化結(jié)構(gòu)體 */
 USART_InitTypeDef USART_InitStructure;   //定義一個(gè)USART結(jié)構(gòu)體
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   //使能USART時(shí)鐘
 /* 配置串口USART1模式 */
 USART_InitStructure.USART_BaudRate = 115200;   //波特率
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //8位字長(zhǎng)
 USART_InitStructure.USART_StopBits = USART_StopBits_1;   //1個(gè)停止位
 USART_InitStructure.USART_Parity = USART_Parity_No;   //無校驗(yàn)
 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   //無硬件流
 USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;   //選擇輸入和輸出模式
 USART_Init(USART1, &USART_InitStructure);   //初始化USART
 /* 第三步:配置串口的接收中斷 */
 NVIC_Configuration();   //嵌套向量中斷控制器NVIC配置
 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);   //使能串口接收中斷,中斷一直打開,接收到一個(gè)字節(jié)后,判斷RXNE位為1,執(zhí)行其中的中斷服務(wù)函數(shù)
 /* 第四步:使能串口 */
 USART_Cmd(USART1, ENABLE);
}

4 stm32f4xx_it.c

#include "stm32f4xx_it.h"
#include "./usart/bsp_usart.h"   //可將全局變量引入

void USART1_IRQHandler(void)
{
  uint8_t ucTemp;
  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)   //判斷TDR是否為非空,收到數(shù)據(jù)TXE位置1 
  {
    ucTemp = USART_ReceiveData(USART1);   //將字符轉(zhuǎn)移到ucTemp中
    USART_SendData(USART1, ucTemp);   //將收到的字符發(fā)送出去
    Flag = ucTemp;  //將收到的字符轉(zhuǎn)移到Flag中
  }  
}

說明1:我們需要一個(gè)變量Flag在中斷服務(wù)函數(shù)與主函數(shù)之間傳遞信息,因?yàn)槭莾蓚€(gè)不同的.c,故需要Flag為全局變量,定義方法:
1、在一個(gè).c文件里面定義,可賦值
2、然后在該頭文件里面用extern關(guān)鍵字申明
3、其他.c文件要使用的時(shí),包含該頭文件就可以了
4、頭文件里面不能給變量賦值
說明2:對(duì)于發(fā)送數(shù)據(jù),發(fā)送出去了再判斷TDR是否為空;對(duì)于接收數(shù)據(jù),接收之前先對(duì)RDR判斷是否為不空。兩者區(qū)別要注意。
說明3:本節(jié)只打開了數(shù)據(jù)接收中斷,當(dāng)判斷有數(shù)據(jù)進(jìn)來即刻執(zhí)行中斷服務(wù)函數(shù),若是服務(wù)函數(shù)較大,可通過Flag傳遞信息,將執(zhí)行任務(wù)分配到主函數(shù)中執(zhí)行。下節(jié)將會(huì)分析另一種接口協(xié)議,CAN口。

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

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

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