我是靠谱客的博主 平常百褶裙,最近开发中收集的这篇文章主要介绍嵌入式开发学习之--抢答器前言一、项目概况二、开发步骤总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

本篇以一个简单的抢答器来学习外部中断。

文章目录

  • 前言
  • 一、项目概况
    • 1.1项目需求
    • 1.2 项目来源
    • 1.3开发环境
    • 1.4项目意义
  • 二、开发步骤
    • 2.1涉及硬件电路
    • 2.2项目代码
      • 2.2.1中断配置
  • 总结


前言

  前一篇大致了解了什么是中断,中断需要配置的参数,再结合之前的按键输入,这一篇实战一下。


提示:以下是本篇文章正文内容,下面案例可供参考

一、项目概况

1.1项目需求

  1. 两个按键,按下后蜂鸣器都会响;
  2. 1号按键按下,led红灯长亮;2号按键按下,led蓝灯长亮;
  3. 任意一个按键按下后,另一个按键按下将没有任何反应;也就是说led只会有一种颜色。

1.2 项目来源

  作者脑洞;

1.3开发环境

  软件:keil5;
  硬件:野火挑战者开发板。

1.4项目意义

  可以用在很多娱乐活动中,也可以增加家庭娱乐气氛,也可以用来维持讨论时的纪律,工作的人应该都知道讨论问题尤其是要负责任的问题时,有多么吵。

二、开发步骤

2.1涉及硬件电路

  电路图请参考之前按键检测试验,这里不放了。

2.2项目代码

2.2.1中断配置

  代码如下(示例):

  exti.h

#ifndef __EXTI_H
#define	__EXTI_H

#include "stm32f4xx.h"

#define KEY1_INT_GPIO_PORT                GPIOA
#define KEY1_INT_GPIO_CLK                 RCC_AHB1Periph_GPIOA
#define KEY1_INT_GPIO_PIN                 GPIO_Pin_0
#define KEY1_INT_EXTI_PORTSOURCE          EXTI_PortSourceGPIOA
#define KEY1_INT_EXTI_PINSOURCE           EXTI_PinSource0
#define KEY1_INT_EXTI_LINE                EXTI_Line0
#define KEY1_INT_EXTI_IRQ                 EXTI0_IRQn

#define KEY1_IRQHandler                   EXTI0_IRQHandler

#define KEY2_INT_GPIO_PORT                GPIOC
#define KEY2_INT_GPIO_CLK                 RCC_AHB1Periph_GPIOC
#define KEY2_INT_GPIO_PIN                 GPIO_Pin_13
#define KEY2_INT_EXTI_PORTSOURCE          EXTI_PortSourceGPIOC
#define KEY2_INT_EXTI_PINSOURCE           EXTI_PinSource13
#define KEY2_INT_EXTI_LINE                EXTI_Line13
#define KEY2_INT_EXTI_IRQ                 EXTI15_10_IRQn

#define KEY2_IRQHandler                   EXTI15_10_IRQHandler

/*******************************************************/


void EXTI_Key_Config(void);

#endif /* __EXTI_H */

  exti.c

#include "exti.h"

static void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  

  NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  

  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;
  
	RCC_AHB1PeriphClockCmd(KEY1_INT_GPIO_CLK|KEY2_INT_GPIO_CLK ,ENABLE);  

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  
  NVIC_Configuration();
  
  GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;	    		
 
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure); 

  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);
  
  GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;  

  GPIO_Init(KEY2_INT_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_Rising;  
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
}

  简单说一下,NVIC_Configuration(void)函数中定义了中断优先级以及初始化; EXTI_Key_Config(void)函数则是在按键输入的基础上又加了中断的一些配置,比如上升沿还是下降沿触发,触发的引脚是什么,宏定义中,注意外部中断用的是哪个,则后面的中断函数也需要用哪一个。

  app.c

#include "app.h"


enum Respond respond;
															 													 
//³õʼ»¯app
void app_init(void)
{
	respond=NOBODY;

}


uint8_t user_rank(void)
{
	if(respond==NOBODY){
		respond=FIRST;
		return FIRST;
	}else{
		return NOBODY;
	}
}

  app.h

#ifndef __APP_H
#define __APP_H

#include "stm32f4xx.h"
#define NONE 0
#define GAIN 1

enum Respond{
	NOBODY =0,
	FIRST=1
};

extern enum Respond respond;

void app_init(void);
uint8_t user_rank(void);

#endif

  app.c中做了一个user_rank函数,利用类似互斥锁的理论,来锁定哪一个先触发。

  stm32f4xx.c


void KEY1_IRQHandler(void)
{
	if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) 
	{
		if(user_rank()==FIRST){
			LED_RED;
		}
		EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);     
	}  
}

void KEY2_IRQHandler(void)
{
	if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) 
	{
		if(user_rank()==FIRST){
			LED_BLUE;
		}
		EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);     
	}  
}	

  将中断函数放在stm32f4xx.c中,无论哪一个触发一次后,另一个按键将不会生效了。

#include "stm32f4xx.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "exti.h"
#include "app.h"

void bsp_init(void)
{
	BEEP_GPIO_Config();
//	Key_GPIO_Config();
	LED_GPIO_Config();
	EXTI_Key_Config();
}

uint8_t key1_inspect()
{
	if(KEY1_READ==KEY_ON){
		return KEY_ON;
	}else if(KEY1_READ==KEY_OFF){
		return KEY_OFF;
	}
}

uint8_t key2_inspect()
{
	if(KEY2_READ==KEY_ON){
		return KEY_ON;
	}else if(KEY2_READ==KEY_OFF){
		return KEY_OFF;
	}
}

int main(void)
{

	uint8_t led_status;

	led_status=OFF;
	bsp_init();
	app_init();

  while(1){

		if(key1_inspect()==KEY_ON){
			 BEEP_ON;			
			while(key1_inspect()==KEY_ON){
			
			}
			BEEP_OFF;	
		}			
		if(key2_inspect()==KEY_ON){
			 BEEP_ON;			
			while(key1_inspect()==KEY_ON){
			
			}
			BEEP_OFF;	
		}			

	}		
}

  main.c主要是按键按下后蜂鸣器的处理。

总结

  1、利用中断能节省资源,提高效率;
  2、能实现任务并行。
  3、在写上层逻辑中,要注意的是当多中断同时调用某一变量或者某一函数,最好加互斥锁,否则可能数据会出错。

最后

以上就是平常百褶裙为你收集整理的嵌入式开发学习之--抢答器前言一、项目概况二、开发步骤总结的全部内容,希望文章能够帮你解决嵌入式开发学习之--抢答器前言一、项目概况二、开发步骤总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部