前言
本文章记录了博主嵌入式课的作业,其也可以使用参考到其它项目中去,比如一些多个按键中断的使用中。
一、实验内容
设计游泳竞赛冲线检测系统,要求:
- 设计8个泳道,编号为1——8。每个泳道设置一个冲线触摸传感器(可以用开关模拟),非触摸状态时输出低电平,触摸状态输出高电平。
- 设置8个LED指示灯对应8个泳道,当运动员选手冲线时对应泳道的LED指示灯亮。
- 设置1个7段数码管,当运动员选手冲线时显示对应的泳道编号。
二、电路原理图设计及说明
1.仿真电路图
连线使用标号的方式,看起来整洁一点:
2.数码管的引脚定义
3.关于中断的简要说明
设置每个按键的IO口与中断线的映射关系,PA0对应中断线0,PA1对应中断线1…PA7对应中断线7,都为上升沿触发,中断事件。中断分组为组0,0位抢占优先级,4位响应优先级。
抢占优先级 & 响应优先级区别:
- 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
- 抢古优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
- 抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
- 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。
本实验设置级别都一样。
不同中断线对应不同的中断服务函数,在中断函数里执行led灯的亮和数码管的显示。
若几条中断的中断服务函数一样,则要用if函数查询中断标志位判断是否为对应的中断。
中断向量对应的中断服务函数。
三.效果仿真
随机按下不同的按键,对应的LED亮且数码管显示对应的数字
中断应用
四.代码编程流程图
五.主要代码
中断初始化:
void M_EXIT_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//
Key_Init();
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//按键PA0中断初始化配置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);//设置IO口与中断线的映射关系
EXTI_InitStructure.EXTI_Line =EXTI_Line0;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
//PA1
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
EXTI_InitStructure.EXTI_Line =EXTI_Line1;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
//PA2
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);
EXTI_InitStructure.EXTI_Line =EXTI_Line2;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
//PA3
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);
EXTI_InitStructure.EXTI_Line =EXTI_Line3;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
//PA4
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);
EXTI_InitStructure.EXTI_Line =EXTI_Line4;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
//PA5
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);
EXTI_InitStructure.EXTI_Line =EXTI_Line5;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
//PA6
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);
EXTI_InitStructure.EXTI_Line =EXTI_Line6;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
//PA7
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource7);
EXTI_InitStructure.EXTI_Line =EXTI_Line7;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
//配置中断分组
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_Init(&NVIC_InitStructure);
}
配置中断服务函数:
void EXTI0_IRQHandler(void)
{
Delay_ms(20);
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_8|GPIO_Pin_1|GPIO_Pin_2);//点亮第一个和数码管显示1
GPIO_SetBits(GPIOB,GPIO_Pin_0| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7);
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI1_IRQHandler(void)
{
Delay_ms(20);
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_9|GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_3|GPIO_Pin_4);
//点亮第二个灯和数码管显示2
GPIO_SetBits(GPIOB, GPIO_Pin_2|GPIO_Pin_5|GPIO_Pin_7);
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
void EXTI2_IRQHandler(void)
{
Delay_ms(20);
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)==1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_10|GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_6);
GPIO_SetBits(GPIOB, GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_7);
}
EXTI_ClearITPendingBit(EXTI_Line2);
}
void EXTI3_IRQHandler(void)
{
Delay_ms(20);
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)==1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_11|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_5|GPIO_Pin_6);
GPIO_SetBits(GPIOB, GPIO_Pin_0| GPIO_Pin_3| GPIO_Pin_4|GPIO_Pin_7);
}
EXTI_ClearITPendingBit(EXTI_Line3);
}
void EXTI4_IRQHandler(void)
{
Delay_ms(20);
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_12|GPIO_Pin_0|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_2|GPIO_Pin_3);
GPIO_SetBits(GPIOB, GPIO_Pin_1|GPIO_Pin_4| GPIO_Pin_7);
}
EXTI_ClearITPendingBit(EXTI_Line4);
}
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line5)==SET)
{
Delay_ms(20);
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_13|GPIO_Pin_0|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4);
GPIO_SetBits(GPIOB, GPIO_Pin_1|GPIO_Pin_7);
EXTI_ClearITPendingBit(EXTI_Line5);
}
}
if(EXTI_GetITStatus(EXTI_Line6)==SET)
{
Delay_ms(20);
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_14|GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2);
GPIO_SetBits(GPIOB, GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7);
EXTI_ClearITPendingBit(EXTI_Line6);
}
}
if(EXTI_GetITStatus(EXTI_Line7)==SET)
{
Delay_ms(20);
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_15|GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6);
EXTI_ClearITPendingBit(EXTI_Line7);
}
}
}
总结
以上就是实验的主要内容。
关于中断分组、配置可以参考其它博主的文章,他们讲的更加详细;
本人只是提供给已经有些基础的同学的思路。希望能够帮到你们,如果有帮助就点个赞吧!