STM32自学之串口中断模式

发布者:忙中取乐最新更新时间:2018-06-09 来源: eefocus关键字:STM32  串口  中断模式 手机看文章 扫描二维码
随时随地手机看文章

    今天是自学STM32的第7天了,之前的流水灯,按键,查询方式串口,PWM,计数器和红外有时间再补上来吧,先从今天调试的中断式串口写起吧。

    事先说明,写此博客只是为了记录自己的自学历程,由于水平极其有限,所以很多理解可能是错的,欢迎大家积极指出,让我们一起在嵌入式的开发上向前进。

   我所使用的是神舟三号学习开发板,芯片型号是STM32F103ZE。功能很齐全了,作为初期自学用绰绰有余。

   串口的printf在STM32程序调试过程中,确实可以起到实时跟踪程序进程的作用,但是经过昨天的红外和今天的中断式串口程序的坑爹BUG之后,深深感觉,没事还是不要加printf了,特别是在待处理事件的时间频率很高时,如昨天的红外调试时,信号的解码在ms级别,在加了printf和不加printf时,所解码的结果相差十万八千里。

  好了,回到正题,先上今天的中断式串口程序吧。

  以下是串口配置函数,我单独写了一个头文件,仅贴出核心部分。

void USART1_Configuration(void)
{
   //定义GPIO,,NVIC,USART结构体
   GPIO_InitTypeDef GPIO_InitStructure;
   NVIC_InitTypeDef NVIC_InitStructure;
   USART_InitTypeDef USART_InitStructure;
   //初始化系统时钟
   SystemInit();
//   //调试用指示灯 
//   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOF, ENABLE);   //首先是开调试用LED灯的GPIO口时钟
//   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
//   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;               //或者写成 GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2一直重复下去 
//   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//   GPIO_Init(GPIOF,&GPIO_InitStructure);

//进行串口配置

//   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);   //开串口和GPIOA的时钟
   //进行中断配置
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);                         //中断优先组0
   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;       
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
   //配置PA9即USART1_TX_
   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
   GPIO_Init(GPIOA,&GPIO_InitStructure);
   //配置PA10即USART1_RX
   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
   GPIO_Init(GPIOA,&GPIO_InitStructure);
   //配置USART1
   USART_InitStructure.USART_BaudRate=115200;
   USART_InitStructure.USART_WordLength=USART_WordLength_8b;
   USART_InitStructure.USART_StopBits=USART_StopBits_1;
   USART_InitStructure.USART_Parity=USART_Parity_No;
   USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
   USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
   USART_Init(USART1,&USART_InitStructure);

/***************

      今天的一大坑点来了。在开中断使能时,不能开IT-TXE中断使能,因为 初始化时也会有TXE置位,

  原因就是此时发送数据寄存器为空。今天在这里被深深的坑了一下

                                                    **************************/

// USART_ITConfig(USART1,USART_TI_TXE,ENABLE);    //就是这句,千万不能要,不然马上进入中断
   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
   USART_Cmd(USART1,ENABLE);
   USART_ClearFlag(USART1,USART_FLAG_TC);
}

再就是中断处理函数了。

void USART1_IRQHandler(void)
{
   int i=0;      //中断内读取字符串组用
   flag=0;     //主函数中打印字符串组用,每进一次中断就清零。 
// GPIO_Write(GPIOF,0X340); //调试时用来判断进入中断否的LED灯标志
   if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)    //每个中断函数最好都加上这句,原因我也不知道,前辈说的。
   {
      while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET)    //如果接收数据寄存器非空,就不停地读
 {
              RxBuffer[i++]=USART_ReceiveData(USART1);

/********************

第二大坑点来了,这句本来是为了跟踪读取过程的,结果每次读了2个数据就跳出来了,

很是无语,开始怀疑是前面的配置有问题,一句句的核对了2个小时,实在没发现错误,

再拿出前几天调的查询时串口和这个作比较,发现唯一的不同是这里的printf多了一个\r\n。

其实也就是换行而已,结果我尝试性的把它去掉,一切正常。我嘞个去啊,坑了劳资一下午。

                                                                                 **************/
// printf("%c\r\n",RxBuffer[i-1]);  //调试用语句,为什么这里多一个\r\n就只能获取2个值便跳出中断??????????????
      }
 USART_ClearITPendingBit(USART1,USART_IT_RXNE);     //清除中断标志位,每个中断必备的,不然就出不来了。
   }
}


关键字:STM32  串口  中断模式 引用地址:STM32自学之串口中断模式

上一篇:stm32—普通串口(接收查询和中断相结合)
下一篇:STM32的串口中断发送

推荐阅读最新更新时间:2024-03-16 16:05

DS18b20在Atmega8下的编程,串口通信电脑显示
=****************************************************** MCU:Atmega8 内部振荡器:8M 环境:ICCAVR 7.0 程序:sdyzxue 薛海涛 2010/06/16 =******************************************************* #include macros.h #include iom8v.h #define fosc 8000000 #define baud 9600 #define SEI() asm( sei ) #define CLR_DIR_1WIRE DDRC&=~BIT(1)
[单片机]
关于STM32函数定义
1.*(__IO uint8_t *) CIR_BYTE3_ADDRESS #define __IO volatile /*! Defines 'read / write' permissions 声明 volatile ,目的:使编译器不优化该变量。从相应变量内存中取数。 /* Check the parameters */ assert_param(IS_TIM_ALL_PERIPH(TIMx)); //assert _param函数作参数检查用 2. static: static局部变量中文名叫静态局部变量。它与普通的局部变量比起来有如下几个区别: 1)位
[单片机]
STM32定时器PWM输出
  脉冲宽度调制PWM(Pulse Width Modulation),调节占空比以控制脉冲宽度。   STM32的定时器除了TIM6和TIM7,其它定时器都可以用来产生PWM信号,高级定时器TIM1和TIM8可同时产生7路PWM输出,通用定时器可同时产生4路PWM输出。   STM32定时器PWM输出设置的几个步骤如下: 1)开启STM32时钟,配置输出I/O为复用输出 2)设置ARR(周期)和PSC(预分频) 3)设置PWM模式(边沿对齐或中央对齐) 4)使能定时器的通道输出,使能定时器 5)修改CCR2来控制占空比   例程:72MHz主频,PB7(TIM4_CH2)输出PWM GPIO_InitStr
[单片机]
使用 STM32 测量频率和占空比的几种方法
使用平台:官方 STM32F429 DISCOVERY 开发板 ,180MHz的主频,定时器频率90MHz。 相关题目: (1)测量脉冲信号频率f_O,频率范围为10Hz~2MHz,测量误差的绝对值不大于0.1%。(15分) (2)测量脉冲信号占空比D,测量范围为10%~90%,测量误差的绝对值不大于2%。(15分) 思路一:外部中断 思路:这种方法是很容易想到的,而且对几乎所有MCU都适用(连51都可以)。方法也很简单,声明一个计数变量TIM_cnt,每次一个上升沿/下降沿就进入一次中断,对TIM_cnt++,然后定时统计即可。如果需要占空比,那么就另外用一个定时器统计上升沿、下降沿之间的时间即可。 缺点:缺
[单片机]
STM32堆和栈(Heap & Stack)及SRAM存储使用
编译一个程序,出现下面的信息: 明明程序没有什么内容,为什么变量大小就有RW+ZI=52+1836=1888字节大小了呢,就已经使用了1888字节的SRAM空间。让我们打开map文件: 可以看到每个文件所使用的SRAM大小,比如delay文件使用了4个字节,地址从0x20000014到0x20000017。其中可以看到HEAP和STACK占了大头,分别占了0x00000200和0x00000400的空间。STACK的起始地址是0x20000360,大小是0x00000400,那么最后的地址是0x20000760,刚好等于1888=0x760字节。于是我们就知道SRAM空间用来存放了什么东西了:1、各个文件中
[单片机]
<font color='red'>STM32</font>堆和栈(Heap & Stack)及SRAM存储使用
STM32CUBE HAL库 关于串口usart收发的一个问题
最近项目中遇到了一个问题,因为开始用freertos,然后想加入串口收发功能。打印正常,但是加入接收中断后,开始出bug,最后锁定接收中断挂掉了。 原因:HAL库的串口接收发送函数有bug,就是收发同时进行的时候,会出现锁死的现象。 解决:需要注释掉 HAL_UART_Receive_IT 和 HAL_UART_Transmit_IT 中的 __HAL_LOCK(huart) 函数 -----------------------------------------------------------------------------------------------------------------------
[单片机]
STM32三种定时器
STM32三种定时器:高级控制定时器(TIM1与TIM8)、通用定时器(TIM2~TIM5)、基本定时器(TIM6与TIM7)。 TIM1与TIM8定时器的功能 (1)16位向上、向下、向上/下自动装载计数器 (2)16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值 (3)多达4个独立通道: ─ 输入捕获 ─ 输出比较 ─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出 (4)死区时间可编程的互补输出 (5)使用外部信号控制定时器和定时器互联的同步电路 (6)允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器 (7)刹车输入信号可以将定时器输出信号置于复位状态或者一
[单片机]
<font color='red'>STM32</font>三种定时器
基于STM32编写一个SPI接口例程
引言 SPI是串行外设接口的缩写,是一种高速的,全双工,同步的通信总线。由于SPI高速和同步的特性,使其成为嵌入式系统和小型设备中使用最广泛的几种通信接口之一。本文将详细讲解一下SPI,并且最后基于STM32编写一个例程。 介绍 SPI简介 SPI(Serial Peripheral Interface)是一种串行外设接口,用于在微控制器(MCU)或数字信号处理器(DSP)等主设备与外部设备之间进行通信。SPI的设计旨在实现高速数据传输和简单的硬件实现。 SPI接口通常由一个主设备(Master)和一个或多个从设备(Slave)组成。主设备控制通信的时序和数据传输,而从设备根据主设备的指令进行响应。SPI通信基于全双工传输方式
[单片机]
基于<font color='red'>STM32</font>编写一个SPI接口例程
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved