嵌入式笔记3

本次学习的是:
在这里插入图片描述
在这里插入图片描述
可直接复制粘贴之前的工程文件,重新命名文件名即可使用
方法一、模块化代码:
main.c

#include "stm32f10x.h"
#include "led.h"
#include "key.h"

void Delay(__IO uint32_t nCount);

int main(void)
{
  SystemInit();
	LED_Config();
	Key_Init();
	
	while(1)
	{
		if(Key_Press()==1) {LED1_ON();LED2_OFF();LED3_OFF();}
			if(Key_Press()==2) {LED1_OFF();LED2_ON();LED3_OFF();}
				if(Key_Press()==3) {LED1_OFF();LED2_OFF();LED3_ON();}
		
	}

}
 
void Delay(__IO uint32_t nCount)
{
   for(; nCount != 0; nCount--);
}

led.c

#include "led.h"
#include "stm32f10x.h"
 
void LED_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD , ENABLE);	
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;	//LED1 V6//½«V6,V7,V8 配置为通用复用推挽输出
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//翻转速度为50MHz
 
  GPIO_Init(GPIOB, &GPIO_InitStructure);					 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_3;		 //LED2, LED3	 V7 V8
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 
  GPIO_Init(GPIOD, &GPIO_InitStructure);

	LED_ALL_OFF();
}

led.h

#ifndef _LED_H
#define _LED_H

#include "stm32f10x.h"

#define LED1_ON() GPIO_SetBits(GPIOB, GPIO_Pin_5);  
#define LED1_OFF() GPIO_ResetBits(GPIOB, GPIO_Pin_5); 

#define LED2_ON() GPIO_SetBits(GPIOD, GPIO_Pin_6);  
#define LED2_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_6); 

#define LED3_ON() GPIO_SetBits(GPIOD, GPIO_Pin_3);  
#define LED3_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_3);

#define LED_ALL_OFF() {GPIO_ResetBits(GPIOB, GPIO_Pin_5);GPIO_ResetBits(GPIOD, GPIO_Pin_3|GPIO_Pin_6); }
#define LED_ALL_ON() {GPIO_SetBits(GPIOB, GPIO_Pin_5);GPIO_SetBits(GPIOD, GPIO_Pin_3|GPIO_Pin_6); }

#define LED3_ON_OFF()		GPIO_WriteBit(GPIOD,GPIO_Pin_3, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_3)))
#define LED2_ON_OFF()		GPIO_WriteBit(GPIOD,GPIO_Pin_6, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_6)))
#define LED1_ON_OFF()		GPIO_WriteBit(GPIOB,GPIO_Pin_5, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5)))

void LED_Config(void);

#endif 

key.c

#include "key.h"

u8 _it0=0;

void Key_Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

void Key_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	 //输入上拉
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;		
	GPIO_Init(GPIOC, &GPIO_InitStructure);
  
  /* K3 配置 PC3 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;					 
	GPIO_Init(GPIOC, &GPIO_InitStructure);
    
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  /* Enable the EXTI9-5 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel =EXTI9_5_IRQn;				 //外部中断9-5
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	     //抢占优先级0
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			 //子优先级2 
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				 //使能
  NVIC_Init(&NVIC_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;				 //外部中断2
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	     //抢占优先级0
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;			 //子优先级2 
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				 //使能
  NVIC_Init(&NVIC_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;				 
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	     
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;			   
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
  NVIC_Init(&NVIC_InitStructure);

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5); //外部中断AFIO--ETXI9-5
 
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);     //外部中断AFIO--ETXI2
  
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);     //外部中断AFIO--ETXI3

  EXTI_InitStructure.EXTI_Line = EXTI_Line5;   //PC5作为键盘K1 检测状态
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			    //中断模式
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	//下降沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
	
  EXTI_InitStructure.EXTI_Line = EXTI_Line2;		//PC2 作为键盘K2 检测状态
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;    //中断模式
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	//下降沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  EXTI_InitStructure.EXTI_Line = EXTI_Line3;	
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			    
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;		   
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

}

void EXTI9_5_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line5) != RESET)				  //判别是否有按键按下
  {
	_it0=1;	    										  //按键中断标志
    EXTI_ClearITPendingBit(EXTI_Line5);					  //清除中断请求标志
  }
}

void EXTI2_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line2) != RESET)				  //判断是否有按键按下
  {
	_it0=2;	    										  //按键中断标志
    EXTI_ClearITPendingBit(EXTI_Line2);					  //清除中断请求标志
  }
}

void EXTI3_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line3) != RESET)				  
  {
	_it0=3;	    										  
    EXTI_ClearITPendingBit(EXTI_Line3);					   
  }
}
u8 Key_Press(void){
   
	if(_it0==1){			 									  //按键按下
   	 if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0){		  //K1  
	  	Key_Delay(0x1ffff);										  
		if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0){		  //按键消抖
			while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0);//是否松开按键	 
			 _it0=0; return 1; //健值1 为K1 按下
		}
	  }		  
   }
   else if(_it0==2){			 							  
   	 if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0){		  
	  	Key_Delay(0x1ffff);										  
		if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0){		  
			while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0);
			 _it0=0; ;return 2;//¼üÖµ2  ΪK2°´ÏÂ
		}
	  }		  
   }
   else if(_it0==3){			 							  
   	 if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0){		  //K3  
	  	Key_Delay(0x1ffff);										  
		if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0){		 
			while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0);
			 _it0=0; return 3;//¼üÖµ3  ΪK3°´ÏÂ
		}
	  }		  
   }
	 return 0;
}

key.h

#ifndef __KEY__H
#define __KEY__H

#include "stm32f10x.h"

void Key_Init(void);
void EXTI9_5_IRQHandler(void);
void EXTI2_IRQHandler(void);
void EXTI3_IRQHandler(void);
u8 Key_Press(void);

#endif 

方法一把索要需要的函数配置都配置好了,注意题目要求,根据题目要求再稍加修改就是了

方法二代码、集中写在main函数中:
main

#include"stm32f10x.h"
void Delay(u32 ncount);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void EXTI_Configuration(void);
extern vu8 _it0;
int main()
{
	GPIO_Configuration();
	NVIC_Configuration();
	EXTI_Configuration();
	
while(1){
	if(_it0==1){
		if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0)
			Delay(0xAFFFFF);
		  if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0){
				while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0);//等按键释放
				 if(GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_3)==0)
					 GPIO_SetBits(GPIOD,GPIO_Pin_3);
				 else 
					 GPIO_ResetBits(GPIOD,GPIO_Pin_3);
			}   }   }   }
void GPIO_Configuration(void){
GPIO_InitTypeDef p;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);//开时钟
	p.GPIO_Pin=GPIO_Pin_3;
	p.GPIO_Mode=GPIO_Mode_Out_PP;
	p.GPIO_Speed=GPIO_Speed_2MHz;
	GPIO_Init(GPIOD,&p);
	
	p.GPIO_Pin=GPIO_Pin_3;
	p.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_Init(GPIOC,&p);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
  GPIO_ResetBits(GPIOD,GPIO_Pin_3);//复位,led的初始状态为灭
}

void NVIC_Configuration(void){
	NVIC_InitTypeDef nv;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
	nv.NVIC_IRQChannel=EXTI3_IRQn;
	nv.NVIC_IRQChannelPreemptionPriority=0;
	nv.NVIC_IRQChannelSubPriority=0;
	nv.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&nv);
}

void EXTI_Configuration(void){
  EXTI_InitTypeDef ext;
	ext.EXTI_Line=EXTI_Line3;
	ext.EXTI_Mode=EXTI_Mode_Interrupt;
	ext.EXTI_Trigger=EXTI_Trigger_Falling;
	ext.EXTI_LineCmd=ENABLE;
	EXTI_Init(&ext);
}

void Delay(u32 ncount)
{
	for(;ncount!=0;ncount--);
}

总结:不管是应用哪一种方法,掌握中断控制定时是必须掌握的一个入门基础,从胚配置函数的参数到实际应用理解,需要花费一点时间

猜你喜欢

转载自blog.csdn.net/qq_44761239/article/details/107368063