【嵌入式作业--游泳竞赛冲线检测 STM32F1外部中断的运用 Proteus仿真】


前言

本文章记录了博主嵌入式课的作业,其也可以使用参考到其它项目中去,比如一些多个按键中断的使用中。


一、实验内容

设计游泳竞赛冲线检测系统,要求:

  1. 设计8个泳道,编号为1——8。每个泳道设置一个冲线触摸传感器(可以用开关模拟),非触摸状态时输出低电平,触摸状态输出高电平。
  2. 设置8个LED指示灯对应8个泳道,当运动员选手冲线时对应泳道的LED指示灯亮。
  3. 设置1个7段数码管,当运动员选手冲线时显示对应的泳道编号。

二、电路原理图设计及说明

1.仿真电路图

连线使用标号的方式,看起来整洁一点:
在这里插入图片描述

2.数码管的引脚定义

在这里插入图片描述

3.关于中断的简要说明

设置每个按键的IO口与中断线的映射关系,PA0对应中断线0,PA1对应中断线1…PA7对应中断线7,都为上升沿触发,中断事件。中断分组为组0,0位抢占优先级,4位响应优先级。
抢占优先级 & 响应优先级区别:

  • 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
  • 抢古优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
  • 抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
  • 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。

本实验设置级别都一样。

不同中断线对应不同的中断服务函数,在中断函数里执行led灯的亮和数码管的显示。
若几条中断的中断服务函数一样,则要用if函数查询中断标志位判断是否为对应的中断。
中断向量对应的中断服务函数。

Alt

三.效果仿真

随机按下不同的按键,对应的LED亮且数码管显示对应的数字

中断应用

四.代码编程流程图

Alt

五.主要代码

中断初始化:

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); 
		 
	 }
	
 }
	 
 }

总结

以上就是实验的主要内容。
关于中断分组、配置可以参考其它博主的文章,他们讲的更加详细;
本人只是提供给已经有些基础的同学的思路。希望能够帮到你们,如果有帮助就点个赞吧!

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值