美文网首页
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