历史上的今天
今天是:2024年12月21日(星期六)
2018年12月21日 | STM32一枚按键的旅行(GPIO+中断+NVIC分组)
2018-12-21 来源:eefocus
首先看硬件原理图

GPIO的C13和E0是两个按键,平时是高电平,当按键下去的时候就接地变成低电平。(所以中断是下降沿触发)
开始软件配置:
宏定义两个按键
(仔细看是有必要的,因为你看 GPIO_Pin_13和GPIO_PinSource13的排序是不同的)
#define TSKEY1GPIO GPIOC
#define TSKEY1GPIOPIN GPIO_Pin_13
#define TSKEY1IRQ EXTI15_10_IRQn
#define TSKEY1_ExtiPortsource GPIO_PortSourceGPIOC
#define TSKEY1_ExtiPin GPIO_PinSource13
#define TSKEY1_Line EXTI_Line13
#define TSKEY2GPIO GPIOE
#define TSKEY2GPIOPIN GPIO_Pin_0
#define TSKEY2IRQ EXTI0_IRQn
#define TSKEY2_ExtiPortsource GPIO_PortSourceGPIOE
#define TSKEY2_ExtiPin GPIO_PinSource0
#define TSKEY2_Line EXTI_Line0
初始化函数:
void TS_Key_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE| RCC_APB2Periph_AFIO,ENABLE ) ;
//RCC_APB2Periph_AFIO不能没有!!
GPIO_InitStructure.GPIO_Pin = TSKEY1GPIOPIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//MUST 如果是GPIO_Mode_IN_FLOATING则失败;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TSKEY1GPIO, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TSKEY1IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_EXTILineConfig(TSKEY1_ExtiPortsource, TSKEY1_ExtiPin);
EXTI_InitStructure.EXTI_Line = TSKEY1_Line;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling ;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
GPIO_InitStructure.GPIO_Pin = TSKEY2GPIOPIN ;
GPIO_Init(TSKEY2GPIO, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TSKEY2IRQ;
NVIC_Init(&NVIC_InitStructure);
GPIO_EXTILineConfig(TSKEY2_ExtiPortsource, TSKEY2_ExtiPin);
EXTI_InitStructure.EXTI_Line = TSKEY2_Line;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling ;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
现在就可以用中断了,到it.c去写服务程序吧。
int it=100;//Test
u8 EXit_Delay(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)//消抖 延时以后去读 如果还是低电平 那就是中断!
{
OSTimeDlyHMSM(0, 0, 0, 100);
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==RESET)
return 1;
else
return 0;
}
这里主要是因为init的时候是下降沿是中断,所以去读,如果是0那就真的是中断。
void EXTI0_IRQHandler(void)
{
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL();
OSIntNesting++;
OS_EXIT_CRITICAL();
if(EXTI_GetITStatus(TSKEY2_Line) != RESET)
{
if( EXit_Delay(TSKEY2GPIO,TSKEY2GPIOPIN))
{
it+=10;
}
EXTI_ClearITPendingBit(TSKEY2_Line);
}
OSIntExit();
}
void EXTI15_10_IRQHandler(void)
{
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL();
OSIntNesting++;
OS_EXIT_CRITICAL();
if(EXTI_GetITStatus(TSKEY1_Line) != RESET)
{
if( EXit_Delay(TSKEY1GPIO,TSKEY1GPIOPIN))
{
it-=5;
}
EXTI_ClearITPendingBit(TSKEY1_Line);
}
OSIntExit();
}
思考:
1对比文章:https://blog.csdn.net/tianshi_1988/article/details/52175434
为什么 GPIO_Mode_IPU成功 GPIO_Mode_IN_FLOATING失败;
回答:http://www.stmcu.org/module/forum/thread-616140-1-1.html
2复用不能丢
3消抖是软件写的,如果你是上升沿触发的话,那就是延时一会再去读,是高电平,1
++++++++++++++++++++++补充HAL库++++++++++++++++++++++++
HAL库写的话非常简单,无脑写。
上传工程。https://pan.baidu.com/s/1BDr4Z-0nOq8lgv5kW2-m9Q
按键下去,就是低电平,灯就翻转。(没有消抖 你 会理解的)
外接一个声控开关,3.3v+GND 连接,OUT连接到D9,有声音的时候就OUT出1,所以STM32是IN
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(100);
sound=HAL_GPIO_ReadPin(SOUNDIN_GPIO_Port, SOUNDIN_Pin);
key =!HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin);
if(sound)
{
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
sound=0;
}
if(key)
{
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
key=0;
}
}
+++++++++20180626补充中断知识+++++++
视频 :http://www.moore8.com/courses/trainning_playback/1679
没想到NVIC中断也说了一节课。有必要的
https://blog.csdn.net/jdsnpgxj/article/details/54573855
默认情况下,如何不设置中断优先级分组,则中断优先级分组默认为0,
即0位抢占优先级,4位响应优先级,则无任何抢占优先级,所以无论中断的优先级设多少,都没有抢占中断的功能,
所以,如果想要一个中断打断另一个中断,必须设置中断优先级分组为1,2,3,4.
如设置优先级分组为2
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
参考: https://blog.csdn.net/bloong/article/details/46409511
STM32的NVIC:https://blog.csdn.net/ABAP_Brave/article/details/52457175
上一篇:STM32 GPIO初始化步骤
下一篇:STM32USB的枚举过程简介
史海拾趣
|
由于是第一次做红外传感器,所以自己到网上搜了几个电路,发现了很多问题,和大家分享一下。 第一个问题就是检测电路是否正确,我一开始就上来就做,其实是错误的,后来就发生了怎么调电路 的结果都是错误的。(其实错误的一塌糊涂) 所以很好 ...… 查看全部问答> |
|
wince 6.0增加简体字库后,NK.bin就有33M了。 想把NK.bin调大,如35M 1、修改Bootloader\\Eboot\\eboot.bib,修改如下: //#define ROM_RAMIMAGE_SIZE 0x02000000   ...… 查看全部问答> |
|
大家好,在单片机中发送双音频是怎么回事? 发送双音频和发送单音频有什么区别和联系? 我现在做的是报警器,一个主机接收,手持机用于发送 里面用到双音频,还有发送一位单音频,这样的发送有什么方法可以看得出来? 谢谢! … 查看全部问答> |
|
我以前只会写一些单片机的小程序 现在发现测试驱动的性能也不知道如何下手,我觉得wince驱动和win32 有些类似,我想请问这些驱动应该如何测试? 都有什么指标要求?我们公司混乱得很,用肉眼感觉测试,觉得有点离谱。请大家说说你们的办法。多谢 ...… 查看全部问答> |
|
怎么通过WAVEINOPEN那些API函数把音频数据录成原始的PCM文件(没有压缩,没有处理过)?在网上没找到,只找到录成WAV文件的例子 怎么通过WAVEINOPEN那些API函数把音频数据录成原始的PCM文件(没有压缩,没有处理过)?在网上没找到,只找到录成WAV文件的例子! //------------- 希望能够给个简单的例子程序啊!… 查看全部问答> |
|
为什么我每次创建菜单后都出现fatal error RC1015: cannot open include file 'afxres.h'.。。 为什么我每次创建菜单后都出现fatal error RC1015: cannot open include file \'afxres.h\'.。。 我创建菜单后,就inclue \"resource.h\" 然后编译 每次都是这个错误 为此 我实验过 重装evc \\sdk\\但是还是 这样 所以求救。。还有 一个问题我写 ...… 查看全部问答> |
|
P1REN会影响到P1OUT吗?请有EZ430-F2013的朋友帮我做个实验,非常简单 从TI提供的P1口的图纸上看,P1OUT.0的输出不受P1REN.0的影响,可是如果做个实验,发现完全不是这么回事: 如下分析使用EZ430-F2013: 1.随便打开一个工程,进入调试状态,不运行程序,打开寄存器窗口; 2.在寄存器窗口中,设置P1OUT.0=1,P1DIR.0 ...… 查看全部问答> |
|
AT91RM9200 ARM中SMC里的NWAIT信号的使用 datasheet中对于NWAIT的描述没理解,是这样的么?比如外挂FPGA,当EBI向外设输出读命令之后,外设FPGA将NWAIT信号拉低,这样EBI开始等待,等外设中的数据读回来之后,外设把NWAIT拉高,结束读过程。同理,写操作,当EBI向外设输出写命令之后,外设F ...… 查看全部问答> |




