完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
STM32学习记录——中断和事件
最近比较懒惰,突然有人让详述一下中断是什么,脑中又闪出那个解释:中断就是你在做某件事,突然被打断了要去做更重要的事,做完更重要的事之后再回来继续把被打断的事做完; 在学习单片机的时候,中断是一个必须要理解的知识点,在CPU执行程序时,发生了某种内部或者外部的随机事件(中断源),引起CPU暂时中断正在运行的程序,转去执行中断服务子程序或中断处理程序来处理发生的随机事件,处理完后又返回被中断的程序继续执行原来被中断的程序,这一过程就是中断; 关于中断向量表,下面深色的地方属于内核异常,内核异常不能被打断,优先级无法设置,其他的浅色部分都是外部中断,外部中断又有两种优先级:抢占优先级(父优先级/主优先级)和响应优先级(子优先级/次优先级 ): 1.抢占优先级高的能够打断低优先级的任务优先执行,甚至嵌套的打断; 2.响应优先级则在执行的时候不能被下一个响应优先级更高的任务打断; 嵌套向量中断控制器——NVIC NVIC几乎负责所有的中断,十分重要 首先有一个结构体:NVIC_InitTypeDef;配置这个结构体有一个专门的函数NVIC_Init(),只需要知道结构体里的成员具体是谁再去配置,最后再调用该函数即可,这些都是STM32的套路。 除此之外,还要注意的是NVIC只能配置16种中断优先级,其抢占优先级和响应优先级都是用一个4位的数字表示,上图中也有说明,只要找到了NVIC_InitTypeDef这个结构体,就会有对应的分配方式说明,我们只需要根据实际需求来配置即可。 这个分配接口函数是: NVIC_PriorityGroupConfig(); 关于配置GPIO的中断大概只需要三步即可 1.中断线的配置 2.对应GPIO引脚的配置 3.中断函数中添加中断里要做的事(中断里要实现什么功能,代码尽量越少越短越好) 下面通过我之前的按键控制灯状态切换的代码来展示: //外部中断0服务程序 控制PA0按一次亮,再按一次灭 void EXTI0_IRQHandler(void) { //使能APB2的GPIOA0 *(volatile unsigned int *)0x40021000 |= 1《《2; *(volatile unsigned int *)0x40010800 &= ~(1《《0); *(volatile unsigned int *)0x40010800 &= ~(1《《2); *(volatile unsigned int *)0x40010800 |= (0x02《《2);//上拉下拉 *(volatile unsigned int *)0x40010810 |= 1《《0; delay_ms(10); //消抖 if(1 == ( *(volatile unsigned int*)0x40010808 & (1《《0))) //WK_UP按键 { LED0=!LED0; } *(volatile unsigned int *)0x40010414=1《《0; //清除LINE0上的中断标志位 } #define KEY1_INT_GPIO_PORT GPIOA void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 配置NVIC为优先级组1 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); /* 配置中断源:按键1 */ NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //配置为EXTI0通道 /* 配置抢占优先级 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 配置子优先级 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 使能中断通道 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //将上述配置参数传入中断初始化函数 } void EXTI_Key_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; /*开启按键GPIO口的时钟*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE); /* 配置 NVIC 中断*/ NVIC_Configuration(); /*--------------------------KEY1配置-----------------------------*/ /* 选择按键用到的GPIO */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; /* 配置为浮空输入 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure); /* 选择EXTI的信号源 */ GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); EXTI_InitStructure.EXTI_Line = EXTI_Line0; /* EXTI为中断模式 */ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; /* 上升沿中断 */ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; /* 使能中断 */ EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); } 除了上面说的,我们还需要知道的是这个中断函数的名称必须是在标准库里的,这个名称在startup_stm32f10x_hd.s或者startup_stm32f10x_md.s文件里面(这个取决于你的单片机的容量) 结合上图和前面的代码就可以知道EXTI0_IRQHandler 就是中断线0的中断函数 以上就是STM32中断和事件部分的理解和配置了,这期间或许理解还不到位或者还没见识到更高级的处理,需要大家多多指出和相互交流,本文不足之处希望大家多多指出,非常感谢。 |
|
|
|
只有小组成员才能发言,加入小组>>
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
416 浏览 1 评论
273 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
243 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
607 浏览 2 评论
631 浏览 2 评论
1356浏览 9评论
36浏览 3评论
STM32CUBEMX4.22.1在main函数里面添加一行语句就死机的原因?
40浏览 3评论
38浏览 3评论
KEIL MDK为什么无法debug library中的代码?
75浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-4-25 12:31 , Processed in 0.663378 second(s), Total 75, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号