STM32学习笔记 输出/外部中断/通讯(2)

在这里插入图片描述一.按键
这些按键在没有被按下的时候,GPIO 引脚的输入状态为低电平。(则应该设置成下拉模式)推挽输出以及速出速率都不用要了。这里已经硬件消抖了,软件就不用了。
按键的初始化:

void KEY_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;//变量第一要在第一位
	
	RCC_AHB1PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);//开启时钟
	

	GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStruct.GPIO_PuPd= GPIO_PuPd_DOWN;//下拉	
	GPIO_Init(KEY1_GPIO_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = KEY2_GPIO_PIN;
	GPIO_Init(KEY2_GPIO_PORT,&GPIO_InitStruct);
	
}

按键扫描程序

uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{
	/*检测是否有按键按下 */
	if (GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON )
	{
		while (GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);
		return KEY_ON;
	}
	else
	{
		return KEY_OFF;
	}

GPIO_ReadInputDataBit()是检测GPIO的函数,可以直接调用,用读取返回的键值来作为判断依据。

头文件:
在这里插入图片描述主函数调用Key_Scan进行读取再判断键值,进行动作。

2.系统时钟树
在这里插入图片描述在这里插入图片描述二.中断
STM32 每个外设都可以产生中断(异常)。
有关具体的系统异常和外部中断可在标准库文件stm32f4xx.h 这个头文件查询到,在IRQn_Type 这个结构体里面包含了F4 系列全部的异常声明。
在这里插入图片描述先了解一下NVIC 是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对Cortex-M4 内核里面的NVIC 进行裁剪,把不需要的
部分去掉,所以说STM32 的NVIC 是Cortex-M4 的NVIC 的一个子集。
在这里插入图片描述在这里插入图片描述固件库文件core_cm4.h 的最后,还提供了NVIC 的一些函数,这些函数遵循CMSI 规则,只要是Cortex-M4 的处理器都可以使用。里面是NVIC的一些库函数。
在这里插入图片描述在misc.h里面罗列了有关中断NVIC的函数。
在这里插入图片描述在这里插入图片描述中断编程:
在这里插入图片描述在这里插入图片描述1)NVIC_IROChannel:第一个中断源的设置可参考stm32f4xx.h 头文件里面的IRQn_Type 结构体定义,这个结构体包含了所有的中断源。,不同的中断中断源不一样,且不可写错,即使写错了程序不会报错,只会导致不想要中断。
2)NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定。
3)NVIC_IRQChannelSubPriority:子优先级,具体的值要根据优先级分组来确定。
4)NVIC_IRQChannelCmd:中断使能(ENABLE)或者失能(DISABLE)。操作的是NVIC_ISER 和NVIC_ICER 这两个寄存器。

那么开始编写中断服务函数
在启动文件startup_stm32f429_439xx.s 中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是为空,为的只是初始化中断向量表。实际的中断服务函数都需要我们重新编写,中断服务函数我们统一写在stm32f4xx_it.c 这个库文件中。

EXTI外部中断
外部中断/事件控制器(EXTI)管理了控制器的23 个中断/事件线。
每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。
EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。

在这里插入图片描述EXTI 可分为两大部分功能,一个是产生中断,另一个是产生事件,这两个功能从硬件
上就有所不同。红色虚线指示的电路流程。它是一个产生中断的线路,最终信号流入到NVIC 控制器内。(3或门,4与门)
产生中断线路目的是把输入信号输入到NVIC,进一步会运行中断服务函数,实现功能,这样是软件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级别的信号传输,属于硬件级的。
另外,EXTI 是在APB2 总线上的,在编程时候需要注意到这点。

在这里插入图片描述
在这里插入图片描述编程:
在这里插入图片描述
外部中断初始化结构体
1)EXTI_Line:EXTI 中断/事件线选择,可选EXTI0 至EXTI22,可参考表 17-1 选择。
2) EXTI_Mode:EXTI 模式选择,可选为产生中断(EXTI_Mode_Interrupt)或者产生事
件(EXTI_Mode_Event)。
3) EXTI_Trigger:EXTI 边沿触发事件,可选上升沿触发(EXTI_Trigger_Rising)、下
降沿触发( EXTI_Trigger_Falling) 或者上升沿和下降沿都触发
( EXTI_Trigger_Rising_Falling)。
4) EXTI_LineCmd:控制是否使能EXTI 线,可选使能EXTI 线(ENABLE)或禁用
(DISABLE)。

我们创建了两个文件:bsp_exti.c 和bsp_exti.h 文件用来存放EXTI 驱动程序及相关宏定义,中断服务函数放在stm32f4xx_it.h 文件中。(要把这个文件放到对应的外设文件里面去,反正不知道为哈我单独创了个文件夹他就找不到头文件了啊 啊啊啊啊啊!!!!比如KEY文件夹里面可以存放。可能是跟他这个EXTI的名字有关系吧,反正我在conf里面看了也没有屏蔽的头文件啊QWQ)

先对exti.h进行编写,在key.h的基础上,我们可以添加对SYSCFG_EXTI_Port_Sources\pin 的定义(跟普通GPIO是一样的)。还有外部中断线和外部中断编号。以及中断服务函数。

在这里插入图片描述
在这里插入图片描述
.h文件 通过查找该启动文件,可以发现EXTI13的中断服务函数应该是EXTI15_10_IRQHandler,而EXTI0的中断函数就是EXTI0_IRQHandler。
在这里插入图片描述.C文件
首先,使用GPIO_InitTypeDef 和EXTI_InitTypeDef 结构体定义两个用于GPIO 和EXTI 初始化配置的变量。使用GPIO 之前必须开启GPIO 端口的时钟;用到EXTI 必须开启SYSCFG 时钟。
编写 EXTI_NVIC_Config(void)完成对NVIC的配置。再写EXTI_Key_Config, 调用EXTI_NVIC_Config函数完成对按键1、按键2 优先级配置并使能中断通道。
我们的目的是产生中断,执行中断服务函数,EXTI 选择中断模式,按键1 使用上升沿触发方式,并使能EXTI 线,按键2 基本上采用与按键1 相关参数配置,只是改为下降沿沿触发方式。最后再在中断服务函数里面编写文件实现。


static void EXTI_NVIC_Config(void)//NVIC配置
{
	NVIC_InitTypeDef NVIC_InitStructure;
	/* 配置NVIC 为优先级组1 */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	/* 配置中断源:按键1 */
	NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
	/* 配置抢占优先级:1 */
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	/* 配置子优先级:1 */
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	/* 配置中断源:按键2,其他使用上面相关配置 */
 	NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
    NVIC_Init(&NVIC_InitStructure);
}

void EXTI_Key_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	EXTI_InitTypeDef  EXTI_InitStructure;
	
	/*开启按键相关的GPIO外设时钟*/
	RCC_AHB1PeriphClockCmd (KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);
	/* 使能 SYSCFG 时钟 ,使用GPIO 外部中断时必须使能SYSCFG 时钟*/
	RCC_APB2PeriphClockCmd ( RCC_APB2Periph_SYSCFG, ENABLE);
	/* 配置 NVIC */
	EXTI_NVIC_Config();
	
	/*选择要控制的GPIO引脚*/	
	GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
	
	/* 连接 EXTI 中断源 到key1 引脚 */
	SYSCFG_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE,KEY1_INT_EXTI_PINSOURCE);
	EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;/* 中断模式 */
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发,相当于按下按键触发
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
	
	/*KEY2跟着设就行了*/
	GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN;
	GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);
	
	SYSCFG_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE,KEY2_INT_EXTI_PINSOURCE);
	EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;/* 中断模式 */
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发,相当于弹起按键触发
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
}

三.系统定时器
SHPRx,其中STK 这个章节有SysTick 的简介和寄存器的详细描述。因为SysTick 是属于CM4 内核的外设,有关寄存器的定义和部分库函数都在core_cm4.h 这个头文件中实现。所以学习SysTick 的时候可以参考这两个资料,一个是文档,一个是源码。SysTick 属于内核的外设,有关的寄存器定义和库函数都在内核相关的库文件core_cm4.h 中。

SysTick—系统定时器是属于CM4 内核中的一个外设,内嵌在NVIC 中。系统定时器是一个24bit 的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK 等于180M。当重装载数值寄存器的值递减到0 的时候,系统定时器就产生一次中断,以此循环往复。</font color >

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述用固件库编程的时候我们只需要调用库函数SysTick_Config()即可,形参ticks 用来设置重装载寄存器的值,最大不能超过重装载寄存器的值224,当重装载寄存器的值递减到0的时候产生中断,然后重装载寄存器的值又重新装载往下递减计数,以此循环往复。紧随其后设置好中断优先级,最后配置系统定时器的时钟为180M,使能定时器和定时器中断,这样系统定时器就配置好了,一个库函数搞定。(core_cm4.h)
在这里插入图片描述
可以看到,如果定时器配置成功了会返回值0。SysTick_Config()库函数主要配置了SysTick 中的三个寄存器:LOAD、VAL 和CTRL.因为SysTick 属于
内核外设
,跟普通外设的中断优先级有些区别,并没有抢占优先级和子优先级的说法。在STM32F429 中,内核外设的中断优先级由内核SCB 这个外设的寄存器:SHPRx(x=1.2.3)来配置。
在这里插入图片描述计数一次的时间TDEC=1/CLKAHB,当重装载寄存器中的值VALUELOAD 减到0 的时候,产生中断,可知中断一次的时间
TINT=VALUELOAD * TDEC 中断= VALUELOAD/CLKAHB,其中CLKAHB =180MHZ。如果设置为180,那中断一次的时间TINT=180/180M=1us。不过1us 的中断没啥意义,整个程序的重心都花在进出中断上了,根本没有时间处理其他的任务。

SysTick_Config()的形我们配置为SystemCoreClock / 100000=180M/100000=1800从刚刚分析我们知道这个形参的值最终是写到重装载寄存器LOAD 中的,从而可知我们现在把SysTick 定时器中断一次的时间TINT=1800/180M=10us。设置好中断时间TINT 后,我们可以设置一个变量t,用来记录进入中断的次数,那么变量t 乘以中断的时间TINT 就可以计算出需要定时的时间。
在这里插入图片描述

在这里插入图片描述在这里插入图片描述语法补充:这里定义了static __IO uint32_t TimingDelay这个变量:_IO 一般宏定义为volatile,表示可百读可写volatile 就是为了禁止编译器对其优化,因为对于timingdelay来说 你要设置一个初始值 但是变化是在中断中度进行的 编译器不知道 会吧这个变量优化掉。
在这里插入图片描述
在这里插入图片描述主函数里面还是会报…\User\main.c(14): warning: #223-D: function “SysTick_Init” declared implicitly的warning到处都声明了的呜呜…
最后下载进去实现了红灯闪1s,绿灯闪10S。

通讯的基本概念
①1.按数据传送的方式,通讯可分为串行通讯与并行通讯
···2.全双工、半双工及单工通讯
在这里插入图片描述3.根据通讯的数据同步方式:分为同步和异步两种,可以根据通讯过程中是否有使用到时钟信号进行简单的区分。在同步通讯中,收发设备双方会使用一根信号线表示时钟信号,在时钟信号的驱动下双方进行协调,同步数据。
在这里插入图片描述
③通讯速率:
衡量通讯性能的一个非常重要的参数就是通讯速率,通常以**比特率(Bitrate)来表示,即每秒钟传输的二进制位数,**单位为比特每秒(bit/s)。容易与比特率混淆的概念是“波特率”(Baudrate),它表示每秒钟传输了多少个码元
而码元是通讯信号调制的概念,通讯中常用时间间隔相同的符号来表示一个二进制数字,这样的信号称为码元。如常见的通讯传输中,用0V 表示数字0,5V 表示数字1,那么一个码元可以表示两种状态0 和1,所以一个码元等于一个二进制比特位,此时波特率的大小与比特率一致;如果在通讯传输中,有0V、2V、4V 以及6V 分别表示二进制数00、01、10、11,那么每个码元可以表示四种状态,
即两个二进制比特位,所以码元数是二进制比特位数的一半,这个时候的波特率为比特率
的一半。

五.串口通讯协议简介
我们分别对串口通讯协议的物理层及协议层进行理解。
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408201448246.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2F2Y在这里插入图片描述
在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32中,外部中断的初始化可以通过以下步骤完成: 1. 配置外部中断线:根据需要选择外部中断线,例如EXTI_Line4。\[2\] 2. 初始化EXTI_InitTypeDef结构体:定义一个EXTI_InitTypeDef结构体,并设置其成员变量,包括EXTI_Line(指定中断线)、EXTI_Mode(指定是事件还是中断)、EXTI_Trigger(指定触发方式)和EXTI_LineCmd(是否使能)。\[2\] 3. 调用EXTI_Init函数:将初始化好的EXTI_InitTypeDef结构体作为参数传入EXTI_Init函数,以初始化外设EXTI寄存器。\[2\] 以下是一个外部中断初始化的示例代码: ```c EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = EXTI_Line4; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); ``` 在上述代码中,我们选择了EXTI_Line4作为外部中断线,并设置了中断模式为中断,触发方式为下降沿触发,使能外部中断。通过调用EXTI_Init函数,将配置好的EXTI_InitStructure结构体传入,即可完成外部中断的初始化。\[2\] #### 引用[.reference_title] - *1* *3* [stm32外部中断](https://blog.csdn.net/qq_62846920/article/details/124655894)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [stm32学习笔记——外部中断](https://blog.csdn.net/Zn_Hua/article/details/120780463)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值