美文网首页
STM32学习教程<三> USART串口接收数据

STM32学习教程<三> USART串口接收数据

作者: 七面琅琊 | 来源:发表于2017-12-07 00:08 被阅读0次

    m_<:整个程序除去基本配置外由四部分组成,main.c、bsp_usart.c、bsp_led.c和stm32f4xx_it.c。其中,bsp_usart.c及.h负责外设USART寄存器的配置,使其能正常工作。bsp_led.c及.h负责外设LED寄存器的配置,使其能正常工作,main.c则是在USART配置完能正常操作后来实现USART怎么接收数据,然后通过控制LED的颜色判断接收到什么数据。在stm32f4xx_it.c中写入中断服务函数,这是本节重点。

    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为全局变量,Flag为我们输入的字符(后面进一步说明)
            {
                Flag == '0';   //Flag复位
                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);   //声明配置函数
    
    #endif
    

    2.2 bsp_led.c

    //bsp: board support package(板级支持包)
    #include "bsp_led.h"       
    
    void LED_GPIO_Config(void)
    {
      //以下四个步骤适合所有外设的初始化
      /* 第一步:开GPIO的时钟 */
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);   //GPIOF在AHB1总线上,另外注意,系统时钟已经自己设定了
      /* 第二步:定义一个GPIO初始化结构体 */
      GPIO_InitTypeDef GPIO_InitStruct;
      /* 第三步:配置GPIO初始化结构体的成员 */
      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;   //Pin6红色、Pin7绿色、Pin8蓝色
      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;    //上拉电阻
      /* 第四步:调用GPIO初始化函数,把配置好的结构体的成员的参数写入寄存器 */
      GPIO_Init(GPIOF, &GPIO_InitStruct);   //将上述参数赋给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发送数据中断 **********************/
    static void NVIC_Configuration(void)
    {
     NVIC_InitTypeDef NVIC_InitStructure;   //定义一个中断结构体
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //选择嵌套向量中断控制器组
     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;   //设置USART为中断源
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   //抢断优先级为1
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;   //子优先级为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时钟
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     /* 配置Tx引脚为复用功能  */
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;   //选择复用模式
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  //选择复用的发送引脚     
     GPIO_Init(GPIOA, &GPIO_InitStructure);   //初始化GPIO
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;   //选择复用的接收引脚
     GPIO_Init(GPIOA, &GPIO_InitStructure);   //初始化GPIO
     GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);   //将PA9复用到USART1的TX上
     GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);   //将PA10复用到USART1的RX上
     /* 第二步:配置串口初始化结构体 */
     USART_InitTypeDef USART_InitStructure;   //定义一个USART结构体
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   //使能USART时钟
     /* 配置串口USART1模式 */
     USART_InitStructure.USART_BaudRate = 115200;   //波特率
     USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //8位字长
     USART_InitStructure.USART_StopBits = USART_StopBits_1;   //1个停止位
     USART_InitStructure.USART_Parity = USART_Parity_No;   //无校验
     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);   //使能串口接收中断,中断一直打开,接收到一个字节后,判断RXNE位为1,执行其中的中断服务函数
     /* 第四步:使能串口 */
     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是否为非空,收到数据TXE位置1 
      {
        ucTemp = USART_ReceiveData(USART1);   //将字符转移到ucTemp中
        USART_SendData(USART1, ucTemp);   //将收到的字符发送出去
        Flag = ucTemp;  //将收到的字符转移到Flag中
      }  
    }
    

    说明1:我们需要一个变量Flag在中断服务函数与主函数之间传递信息,因为是两个不同的.c,故需要Flag为全局变量,定义方法:
    1、在一个.c文件里面定义,可赋值
    2、然后在该头文件里面用extern关键字申明
    3、其他.c文件要使用的时,包含该头文件就可以了
    4、头文件里面不能给变量赋值
    说明2:对于发送数据,发送出去了再判断TDR是否为空;对于接收数据,接收之前先对RDR判断是否为不空。两者区别要注意。
    说明3:本节只打开了数据接收中断,当判断有数据进来即刻执行中断服务函数,若是服务函数较大,可通过Flag传递信息,将执行任务分配到主函数中执行。下节将会分析另一种接口协议,CAN口。

    相关文章

      网友评论

          本文标题:STM32学习教程<三> USART串口接收数据

          本文链接:https://www.haomeiwen.com/subject/nlerixtx.html