STM32外部中断及串口

一、外部中断的类型

STM32F4 外部中断/事件控制器(EXTI)包含多达 23 个用于产生事件/中断 请求的边沿检测器。EXTI 的每根输入线都可单独进行配置,以选择类型(中断 或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发),还可单独屏蔽。

什么是中断     程序在正常运行过程中发生了内部或外部事件时,打断了正在执行的程序,转到外部或内部事件中去执行中断对应的代。

中断的意义   高效的去执行程序,不会一直占用MCU的资源。

中断入口   中断服务函数:芯片中固定了一段地址空间用来存储程序代码。这一段程序代码是中断执行的程序代码   中断的入口:中断服务函数名。

中断的优先级    中断优先级:指的是给中断编号,用来区分那件事件先执行,那件事情后执行。编号越小优先级越高

  • 输入线:EXTI 控制器有 20 个中断/事件输入线,这些输入线可以通过寄存器设置为任意一个 GPIO,也可以是一些外设的事件,输入线一般是存在电平变化的信号。
  • 边沿检测电路:它会根据上升沿触发选择寄存(EXTI_RTSR)和下降沿触发选择寄存器(EXTI_FTSR)对应位的设置来控制信号触发。边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号 1 ,否则输出无效信号0。而 EXTI_RTSR 和 EXTI_FTSR 两个寄存器可以控制器需要检测哪些类型的电平跳变过程,可以是只有上升沿触发、只有下降沿触发或者上升沿和下降沿都触发。
  • NVIC中断控制器:NVIC中断控制器接收到EXTI_PR 寄存器发送的内容,实现中断的发生。
  • 脉冲发生器:脉冲发生器发送信号后会产生事件线路,脉冲信号可以给其他外设电路使用,比如定时器 TIM、模拟数字转换器 ADC等等,这样的脉冲信号一般用来触发 TIM 或者 ADC开始转换。

二、GPIO外部中断的配置

 触发方式:STM32 的外部中断是经过边沿来触发的,不支持电平触发

外部中断分组:STM32 的每个GPIO都能配置成一个外部中断触发源,STM32 经过根据引脚的序号不一样将众多中断触发源分红不一样的组,好比:PA0,PB0,PC0,PD0,PE0,PF0,PG0为第一组,那么依此类推,咱们能得出一共有16 组,STM32 规定,每一组中同时只能有一个中断触发源工做,那么,最多工做的也就是16个外部中断。
三、串口的介绍

    1.串口的数据包格式为 起始位+数据位+校验位+停止位,所以一般需要设置数据位为8,校验位为1,停止位为1。我们再发送过程中只发送数据,其他的都由硬件来完成了,所以通信的双方在数据包格式配置相同时才能正确通信。
   2.除去数据包格式设置一样外,因为串口大多数都是用异步通信,由于没有时钟信号,所以2个通信设备需约定好波特率,常见的有4800、9600、115200等,波特率一致时才能正确通信。
   3.stm32的库文件中将这些需要配置的参数都写在了USART_InitTypeDef 结构体中,我们只要对其进行赋值,再调用函数USART_Init(),USART_Init函数会将USART_InitTypeDef 结构体中的数据写入相应的寄存器,这样就完成了对32串口的配置。

串口中断
    1.结构体写好后,接下来就是中断函数,串口中断来对接受的数据进行整理,如果串口处理数据的方法相差不是太大,都可以使用此中断函数来整理接收的数据。
    2.串口数据整理的思想,以数据接受为例:
        (1).开辟两个256字节的数组,用来存放接受或者发送的数据。
        (2).数据接收:给256个字节设数据头尾,每当进入一次中断,有一个数据传入就把数据写到结构体的rbuf数组中保存起来,同时把数据头rbuf_head 值+1,当数据头超过数据缓冲区大小时清零。
        (3).数据处理:有数据传入就把标志位 com_already 置1,处理完数据后清0,同时更新数据尾部rbuf_tail的数值。
        (4).例如:刚上电时都为0,传入8个字节正确的数据,先将8个字节的数据保存在结构体中,同时每传入一个字节数据头加1。置1标志位等待数据处理函数。 数据处理函数处理完成数据后将数据尾加8等于数据头。(此时假设数据都是正确的情况,这样就可以造成循环可以保存接受的每一个数据,详情请看第5节代码。
    3.中断函数中只写了数据的接受,对于stm32来说,数据发送直接封装为函数更加简单方便。

四、串口的配置方法

1.串口配置时,只有少数值需要时常更改,大部分都是重复内容,因此将常用的这些值做为参数传入。这样调用一个函数可以对所有的串口进行赋值。(串口使用的GPIO在后续的文章中统一配置)借鉴前辈的代码。
   2.串口初始化流程   开外设时钟->配置引脚(统一配置)->配置参数 ->使能中断 ->使能串口

1、先对端口进行复用或者重映射操作(该程序中是对端口进行复用操作)

2、串口复位,函数为USART_DeInit();

3、串口初始化:USART_Init();

4、中断初始化: NVIC_Init();

5、串口使能:USART_Cmd();

6、开启中断:USART_ITConfig();

7、编写中断处理函数:void USART1_IRQHandler(void)

void MY_USART_Init(void)
{
 
    GPIO_InitTypeDef GPIO_InitStrue;     //在GPIO_Init函数调用时需定义一个GPIO_InitTypeDef结构体类型变量
    USART_InitTypeDef USART_InitStrue;    //USART_Init函数调用时需定义一个USART_InitTypeDef结构体类型变量
    NVIC_InitTypeDef NVIC_InitStrue;    //USART_Init函数调用时需定义一个NVIC_InitTypeDef结构体类型变量
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
        //RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
        //由于串口功能是GPIO的第二功能,所以要对端口进行复用操作,
        //一般步骤为:GPIO时钟使能-》复用的外设时钟使能-》将端口按照复用的功能进行模式配置
 
    USART_DeInit(USART1);    //串口复位
 
        GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;    //复用功能推挽输出模式
        GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;    //PA9
        GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;    //设置输出速度
    GPIO_Init(GPIOA,&GPIO_InitStrue);
 
        GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;    //浮空输入模式
        GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;    //PA10
    GPIO_Init(GPIOA,&GPIO_InitStrue);
 
    USART_InitStrue.USART_BaudRate=;//设置波特率9600
    USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件数据流控制,相关寄存器为CR3
    USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//模式为接收和发送
    USART_InitStrue.USART_Parity=USART_Parity_No;//无奇偶校验位0x0000,相关寄存器为SR1的PS位
    USART_InitStrue.USART_StopBits=USART_StopBits_1;    //1个停止位
    USART_InitStrue.USART_WordLength=USART_WordLength_8b;    //数据长度为8位
    USART_Init(USART1,&USART_InitStrue);    //串口初始化
 
    NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn; //串口1对应的中断名称
    NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;    //使能该中断通道
    NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=;//抢占优先级为2,因为此程序只有一个中断,故可任意设置
    NVIC_InitStrue.NVIC_IRQChannelSubPriority=;//响应优先级为1,因为此程序只有一个中断,故可任意设置
    NVIC_Init(&NVIC_InitStrue);    //中断初始化
 
    USART_Cmd(USART1,ENABLE); //串口使能  就是将寄存器CR1中的UE位置1
 
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能串口中断,也叫开启串口中断,第二个参数是设置具体开启哪种中断,具体为寄存器SR
 
}
 
//在stm32f10x_it.文件
void USART1_IRQHandler(void)        //中断函数
{
    u16 DATA;
    if(USART_GetITStatus(USART1,USART_IT_RXNE))//判断如果收到了数据,收到数据CR1中RXNE位为1,该函数的返回值为1,则执行if包含的语句
    {
    DATA=USART_ReceiveData(USART1);//读取数据
    USART_SendData(USART1,DATA);//发送读到的数据
    }
 
}
 
int main(void) //主函数
 {   
      SystemInit(); //系统时钟设置
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//进行中断分组,分为2组:2位抢占优先级,2位响应优先级
      MY_USART_Init();    //调用串口初始化函数
        while();  //等待中端发生
 
 }
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值