#include <includes.h>
#include "remote.h"
extern u8 in_wx_setup_flag;
extern u8 wx_id;
extern u8 Red_ZF[16];
u32 Remote_Odr=0; //命令暂存处
u8 Remote_Cnt=0; //按键次数,此次按下键的次数
u8 Remote_Rdy=0; //红外接收到数据
//初始化红外接收引脚的设置
//开启中断,并映射
void Remote_Init(void)
{
/*
RCC->APB2ENR|=1<<2; //PA时钟使能
GPIOA->CRL&=0XFFFFFF0F;
GPIOA->CRL|=0X00000080; //PA1输入
GPIOA->ODR|=1<<1; //PA.1上拉
Ex_NVIC_Config(GPIO_A,1,FTIR);//将line1映射到PA.1,下降沿触发.
MY_NVIC_Init(2,1,EXTI1_IRQChannel,2);
*/
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Connect EXTI 0 Line to GPIO d.8 Pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource8);
/* Configure EXTI 0 Line to generate an interrupt on falling edge */
EXTI_InitStructure.EXTI_Line = EXTI_Line8;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);
/* Configure the Priority Group to 2 bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Enable the EXTI9_5 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //9
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//检测脉冲宽度
//最长脉宽为5ms
//返回值:x,代表脉宽为x*20us(x=1~250);
u8 Pulse_Width_Check(void)
{
u8 t=0;
//high
if(in_wx_setup_flag==0x00)
{
Send_RedData_Direct(wx_id);
}
while(RDATA)
{
t++;
delay_us(20);
if(t==250)return t; //超时溢出
}
//low
if(in_wx_setup_flag==0x00)
{
Send_RedData_Direct(wx_id);
}
return t;
}
//处理红外接收
/*-------------------------协议--------------------------
开始拉低9ms,接着是一个4.5ms的高脉冲,通知器件开始传送数据了
接着是发送4个8位二进制码,第一二个是遥控识别码(16),第一个为
正码(16),第二个为反码(239),接着两个数据是键值,第一个为正码
第二个为反码.发送完后40ms,遥控再发送一个9ms低,2ms高的脉冲,
表示按键的次数,出现一次则证明只按下了一次,如果出现多次,则可
以认为是持续按下该键.
---------------------------------------------------------*/
//外部中断服务程序
void EXTI9_5_IRQHandler(void)
{
u8 res=0;
u8 OK=0;
u8 RODATA=0;
while(1)
{
if(RDATA)//有高脉冲出现
{
res=Pulse_Width_Check();//获得此次高脉冲宽度
if(res==250)break;//非有用信号
if(res>=200&&res<250)OK=1; //获得前导位(4.5ms)
else if(res>=85&&res<200) //按键次数加一(2ms)
{
Remote_Rdy=1;//接受到数据
Remote_Cnt++;//按键次数增加
break;
}
else if(res>=50&&res<85)RODATA=1;//1.5ms
else if(res>=10&&res<50)RODATA=0;//500us
if(OK)
{
Remote_Odr<<=1;
Remote_Odr+=RODATA;
Remote_Cnt=0; //按键次数清零
}
}
}
//EXTI_ClearITPendingBit(EXTI_1);
EXTI->PR=1<<8; //清除中断标志位
}
//处理红外键盘
//返回相应的键值
u8 Remote_Process(void)
{
u8 t1,t2;
t1=Remote_Odr>>24; //红外解码 01ffa05f u32
t2=(Remote_Odr>>16)&0xff;
Remote_Rdy=0;//清除标记
if(t1==(u8)(~t2+1)&&t1==REMOTE_ID)//检验遥控识别码(ID)
{
t1=Remote_Odr>>8;
t2=Remote_Odr;
if(t1==(u8)~t2)return t1; //处理键值
}
else
{
return 255;//排除掉乱码导致的0x00,被识别为1个键值的问题。。。
}
return 255; //01ff1ae5左上 01ffba45左下 01ff5aa5右上 01fffa05
//01ffa05f红 01ff906f 绿 01ff42bd黄 01ffc23d蓝
//01ffb847 A 708f B 827d C f00f D
// 9a65 E E01f F
//NEC 地址码 地址反码 控制码 控制反码 不符合!
}
//外部中断配置函数
//只针对GPIOA~G;不包括PVD,RTC和USB唤醒这三个
//参数:GPIOx:0~6,代表GPIOA~G;BITx:需要使能的位;TRIM:触发模式,1,下升沿;2,上降沿;3,任意电平触发
//该函数一次只能配置1个IO口,多个IO口,需多次调用
//该函数会自动开启对应中断,以及屏蔽线
//待测试...
void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM)
{
u8 EXTADDR;
u8 EXTOFFSET;
EXTADDR=BITx/4;//得到中断寄存器组的编号
EXTOFFSET=(BITx%4)*4;
RCC->APB2ENR|=0x01;//使能io复用时钟
AFIO->EXTICR[EXTADDR]&=~(0x000F<<EXTOFFSET);//清除原来设置!!!
AFIO->EXTICR[EXTADDR]|=GPIOx<<EXTOFFSET;//EXTI.BITx映射到GPIOx.BITx
//自动设置
EXTI->IMR|=1<<BITx;// 开启line BITx上的中断
//EXTI->EMR|=1<<BITx;//不屏蔽line BITx上的事件 (如果不屏蔽这句,在硬件上是可以的,但是在软件仿真的时候无法进入中断!)
if(TRIM&0x01)EXTI->FTSR|=1<<BITx;//line BITx上事件下降沿触发
if(TRIM&0x02)EXTI->RTSR|=1<<BITx;//line BITx上事件上升降沿触发
}
//设置NVIC
//NVIC_PreemptionPriority:抢占优先级
//NVIC_SubPriority :响应优先级
//NVIC_Channel :中断编号
//NVIC_Group :中断分组 0~4
//注意优先级不能超过设定的组的范围!否则会有意想不到的错误
//组划分:
//组0:0位抢占优先级,4位响应优先级
//组1:1位抢占优先级,3位响应优先级
//组2:2位抢占优先级,2位响应优先级
//组3:3位抢占优先级,1位响应优先级
//组4:4位抢占优先级,0位响应优先级
//NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先
//CHECK OK
//100329
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)
{
// u32 temp;
// u8 IPRADDR=NVIC_Channel/4; //每组只能存4个,得到组地址
// u8 IPROFFSET=NVIC_Channel%4;//在组内的偏移
// IPROFFSET=IPROFFSET*8+4; //得到偏移的确切位置
// MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
// temp=NVIC_PreemptionPriority<<(4-NVIC_Group);
// temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
// temp&=0xf;//取低四位
//
// if(NVIC_Channel<32)NVIC->ISER[0]|=1<<NVIC_Channel;//使能中断位(要清除的话,相反操作就OK)
// else NVIC->ISER[1]|=1<<(NVIC_Channel-32);
// NVIC->IPR[IPRADDR]|=temp<<IPROFFSET;//设置响应优先级和抢断优先级
}
//延时nus
//nus为要延时的us数.
void delay_us(u32 nus)
{
u16 TIMCounter = (u16)nus;
TIM_Cmd(TIM4, ENABLE);
TIM_SetCounter(TIM4, TIMCounter);
while (TIMCounter>1)
{
TIMCounter = TIM_GetCounter(TIM4);
}
TIM_Cmd(TIM4, DISABLE);
}
//设置NVIC分组
//NVIC_Group:NVIC分组 0~4 总共5组
//CHECK OK
//091209
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{
u32 temp,temp1;
temp1=(~NVIC_Group)&0x07;//取后三位
temp1<<=8;
temp=SCB->AIRCR; //读取先前的设置
temp&=0X0000F8FF; //清空先前分组
temp|=0X05FA0000; //写入钥匙
temp|=temp1;
SCB->AIRCR=temp; //设置分组
}
#define GET_HX1838_STATUS() GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_8)
/*
功能:直接将一个gpio状态发送到另外一个gpio去,放在exti中断内测试
各个通道的gpio通道待确定。。。
ID:1-16 88
*/
void GPIO_WriteBit_New(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint8_t BitVal)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_BIT_ACTION(BitVal));
if (BitVal != Bit_RESET)
{
GPIOx->BSRR = GPIO_Pin;
}
else
{
GPIOx->BRR = GPIO_Pin;
}
}