bsp_exti.c
#include "bsp_exti.h"
static void NVIC_Configuration(void) //中断优先级函数
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置NVIC为优先级组1 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //配置NVIC为优先级组1
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn ; //配置中断源:
/*EXTI0_IRQn/EXTI1_IRQn/ EXTI2_IRQn/EXTI3_IRQn/EXTI4_IRQn/EXTI9_5_IRQn/EXTI15_10_IRQn*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //配置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //配置子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道
NVIC_Init(&NVIC_InitStructure); //写入结构体成员
}
void remote_EXTI_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //GPIO结构体
EXTI_InitTypeDef EXTI_InitStructure; //中断结构体
NVIC_Configuration(); //中断优先级函数
//初始化GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); //开启GPIO口的时钟//开启按键GPIO口的时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; // 哪个引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //配置为浮空输入
GPIO_Init(GPIOE, &GPIO_InitStructure); //写入结构体GPIO成员
//初始化EXTI
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启复用GPIO口的时钟 //开启按键GPIO口的时钟
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource5); //选择EXTI的信号源GPIOE,pin5
EXTI_InitStructure.EXTI_Line = EXTI_Line5; //选择中断源,引脚哪个就选择哪个
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //上升沿和下降沿都触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断
EXTI_Init(&EXTI_InitStructure); //写入结构体中断成员
}
在这里插入代码片
remote.c
#include "remote.h"
#include "bsp_exti.h"
extern u32 count_100us;
u32 lt=0; //记录低电平时间
u32 ht=0; //记录低电平时间
u8 ind=0; //记录32个数据码
u8 remotecode[4]; //数组来保存地址码,地址反码,数据码,数据反码
u8 remotestat=0; //0表示未解码,1表示解码中,2表示解好码
void EXTI9_5_IRQHandler(void)
{
u8 triger;
static u8 dat,i,j;
if(EXTI_GetITStatus(EXTI_Line5) != RESET)
{
//清除中断标志位
EXTI_ClearITPendingBit(EXTI_Line5);
triger=GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_5); //读取端口电平
//上升沿
if(triger==1)
{
lt=count_100us; //捕获上升沿时间
count_100us=0;
}
//下降沿
else
{
ht=count_100us; //捕获下降沿时间
count_100us=0;
//=========================解码===========================//
//判断前导码来了没有
if(remotestat==0)
{
if((lt<100)&&(lt>80)&&(ht<50)&&(ht>40)) //判断前导码是否正确
{
remotecode[0]=remotecode[1]=remotecode[2]=remotecode[3]=0; //地址码,地址反码,数据码,数据反码 从零开始
ind=i=0;
remotestat=1;//前导码正确进入解码--解数据码
}
}
else if(remotestat==1) //前导码正确进入解码--解数据码
{
j=ind>>3;//j=ind/8;//第ind个码 放在数组的第j个字节里面
if((lt<8)&&(lt>4)&&(ht<7)&&(ht>3)){remotecode[j]|=0x00;} //如果低是600us,高是500us,表示0
else if((lt<8)&&(lt>4)&&(ht<18)&&(ht>14)){remotecode[j]|=0x80;} //如果低是600us,高是1600us,表示1
else{remotestat=0;return;} //否则解码失败,退出
ind++; //记录多少个高低电平
i++; //记录我的remotecode[j]移了多少次
if(i!=8){remotecode[j]>>=1;} //每移动8次保存一位数组
else{i=0;}
if(ind>=32) //总共有32个高低电平
{
ind=0;
if((remotecode[2]+remotecode[3])==0xff) //判断数据码正反是否正确
{
remotestat=2; //正确接下来进入我们要实现的功能
}
else
{
remotestat=0; //否则如果数据码不正确,退出
}
}
}
}
}
}