中科因仑“3+1”工程特种兵精英论坛
标题:
STM8 红外解码程序--使用外部中断和定时器
[打印本页]
作者:
liliuyang
时间:
2016-4-13 20:07
标题:
STM8 红外解码程序--使用外部中断和定时器
/*
*********************************************************************************************************
*
* 模块名称 : 红外遥控解码
*
引导码 地址码 地址反码 数据码 数据反码
\ 9+4.5ms \ c0-c07 \ c0-c07 \ c0-c07 \ c0-c07 \
*********************************************************************************************************
*/
#include "Ir_decode.h"
u8 Ir_Status=0; //红外接收处理状态
u8 Ir_Receive_Count=0; //红外接收数据位计数
u32 Ir_Receive_Data=0; //32位的红外接收数据
u8 Ir_receive_ok=0; //红外接收完成标志
void TIM2_Config(void)
{
TIM2_DeInit();
TIM2_TimeBaseInit(TIM2_PRESCALER_16, 60000);//定时器设置1M的计数频率,1US的分辨率
TIM2_ClearFlag(TIM2_FLAG_UPDATE);
/* Enable update interrupt (使能更新中断)*/
TIM2_ITConfig(TIM2_IT_UPDATE, ENABLE);
/* Disable TIM2 */
TIM2_Cmd(DISABLE);
}
/*
********************************************************************************
定时器溢出中断内处理
********************************************************************************
*/
void TIM_IT_Updata_Handdle(void)
{
Ir_Status=0;
TIM2_ClearITPendingBit(TIM2_IT_UPDATE);
TIM2_SetCounter(0);
TIM2_Cmd(DISABLE);
}
/*
********************************************************************************
红外解码初始化函数
********************************************************************************
*/
void Ir_Init(void)
{
GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_IN_PU_IT); //配置引脚上拉中断输入
EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOD, EXTI_SENSITIVITY_FALL_ONLY);//下降沿中断
TIM2_Config();
}
/*
********************************************************************************
红外接收数据处理函数
********************************************************************************
*/
u8 Ir_Process(void)
{
u8 Ir_num=0; //最终处理后的键值返回值
u8 Address_H,Address_L; //地址码,地址反码
u8 Data_H,Data_L; //数据码,数据反码
if(Ir_receive_ok==1) //接收完成
{
Address_H=Ir_Receive_Data>>24; //得到地址码
Address_L=(Ir_Receive_Data>>16)&0xff; //得到地址反码
//if((Address_H==(u8)~Address_L)&&(Address_H==REMOTE_ID))//检验遥控识别码(ID)及地址
if((Address_H==(u8)~Address_L))//检验遥控识别码(ID)及地址
{
printf("\r\n %d",Address_H);
Data_H=Ir_Receive_Data>>8; //得到数据码
Data_L=Ir_Receive_Data; //得到数据反码
if(Data_H==(u8)~Data_L) //接收数据码正确
{
Ir_num=Data_H; //正确键值
Ir_receive_ok=0;
printf("\r\n %d",Ir_num);
}
}
}
return Ir_num; //返回键值
}
/*
********************************************************************************
红外接收中断处理函数
********************************************************************************
*/
void Ir_Receive_Handle(void)
{
u16 Interval_tim=0;//两个下降沿间隔时间
switch(Ir_Status)
{
case 0://第一个下降沿,定时器开始计数
Ir_Status=1;
TIM2_Cmd(ENABLE); //Enable TIM2
TIM2_SetCounter(0); //定时器计数值清零
break;
case 1://第二个下降沿,定时器关闭,读取定时器计数值
TIM2_Cmd(DISABLE);
Interval_tim=0;
Interval_tim=TIM2_GetCounter(); //读取定时器计数值
TIM2_SetCounter(0); //定时器计数值清零
TIM2_Cmd(ENABLE); //Enable TIM2
if( (Interval_tim>=12500)&&(Interval_tim<=14500) )//判断引导码是否正确9+4.5ms
{
Ir_Status=2; //进入下一状态
}
else //引导码错误,从新接收
{
Ir_Status=0;
Ir_Receive_Count=0;
}
break;
case 2://进入32位数据接收
TIM2_Cmd(DISABLE);
Interval_tim=0;
Interval_tim=TIM2_GetCounter();
TIM2_SetCounter(0);
TIM2_Cmd(ENABLE); //Enable TIM2
if(Ir_Receive_Count<32)
{
if( (Interval_tim>=1000)&&(Interval_tim<=1300) ) //间隔1.12ms ->0
{
Ir_Receive_Data=Ir_Receive_Data<<1;
Ir_Receive_Count++;
}
else if( (Interval_tim>=2000)&&(Interval_tim<=2600) ) //间隔2.25ms ->1
{
Ir_Receive_Data=Ir_Receive_Data<<1;
Ir_Receive_Data=Ir_Receive_Data|0x0001;
Ir_Receive_Count++;
}
else//不是0,1 接收错误,从新接收
{
Ir_Status=0;
Ir_Receive_Data=0;
Ir_Receive_Count=0;
}
break;
}
else//超出接收数据位数,接收下一个
{
Ir_receive_ok=1;//红外接收完成
Ir_Status=0;
Ir_Receive_Count=0;
break;
}
break;
default :
break;
}
}
/*
*********************************************************************************************************
*
* 模块名称 : 红外遥控解码
*
*********************************************************************************************************
*/
#ifndef __Ir_decode_H
#define __Ir_decode_H
#include "stm8s.h"
#include "uart.h"
//红外遥控识别码(ID)
#define REMOTE_ID 0
extern u8 Ir_Status;
extern u8 Ir_Receive_Count;
extern u8 Ir_receive_ok;
extern u32 Ir_Receive_Data;
u8 Remote_Scan(void);
void Ir_Init(void);
u8 Ir_Process(void);
void Ir_Receive_Handle(void);
void TIM_IT_Updata_Handdle(void);
#endif
******************************************************************************
stm8s_it.c
******************************************************************************
INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6)
{
Ir_Receive_Handle();
}
INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)
{
TIM_IT_Updata_Handdle();
}
欢迎光临 中科因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/)
Powered by Discuz! X3.4