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

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口。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 229,763评论 6 539
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,238评论 3 428
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 177,823评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,604评论 1 317
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,339评论 6 410
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,713评论 1 328
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,712评论 3 445
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,893评论 0 289
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,448评论 1 335
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,201评论 3 357
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,397评论 1 372
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,944评论 5 363
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,631评论 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,033评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,321评论 1 293
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,128评论 3 398
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,347评论 2 377

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,818评论 18 139
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,197评论 30 471
  • 一、温故而知新 1. 内存不够怎么办 内存简单分配策略的问题地址空间不隔离内存使用效率低程序运行的地址不确定 关于...
    SeanCST阅读 7,859评论 0 27
  • 中等大的那朵花不确定叠什么色,试错了颜色,看起来有点脏。 下面的是原图,外出游玩时候拍摄的。背景纷繁杂乱的草不知道...
    瘦晓白阅读 471评论 0 1
  • (屏)一屏遮档内乾坤,一障隐藏机关尽。心有屏障难放松,绕过屏风出新天。精雕细琢山水现,梅兰竹菊独傲骨。花鸟鱼虫屏上...
    甘朝武阅读 177评论 0 0