/*该例程使用STM8 TIM1捕获功能读取NEC协议红外遥控数据*/
/*使用8MHZ外部晶振,TIM1 工作频率1MHZ,使用别的系统需要修改TIM分频系数*/
/*UATR2 按照fMaster=8M设置,如果使用别的频率需要修改宏定义F_MASTER*/
#include "UART2.h"
#include "Sys_CLOCK.h"
uint8_t i=0;
uint16_t IR_High_Data,IR_Cycle_Data;
uint32_t IR_Data=0;
void TIM1_Capture_Init(void)
{
TIM1_PSCRH=0;//TIM1分频器配置
TIM1_PSCRL=7;//计数器工作频率1MHZ,周期1uS
TIM1_CCMR1=0x30;//设置输入捕获采样1MHZ(8分频),输入/捕获1预分频器0分频
TIM1_CCER1_CC1P=1;//下升沿捕获
TIM1_CCER1_CC2P=0;//上降沿捕获
TIM1_CCMR1_CC1S=0x01;//CC1通道被配置为输入,IC1映射在TI1FP1上;
TIM1_CCMR2_CC2S=0x02;//CC1通道被配置为输入,IC1映射在TI1FP2上;
TIM1_SMCR_TS=0x05;//滤波后的定时器输入1(TI1FP1)
TIM1_SMCR_SMS=0x04;//复位模式
TIM1_IER_CC1IE=1;//使能捕获/比较1中断
TIM1_CR1|=0x01;//使能TIM1
}
#pragma vector=TIM1_CAPCOM_CC1IF_vector //TIM1捕获/比较1中断
__interrupt void TIM1_CAPCOM_CC1IF_vector_IRQHandler(void)
{
IR_High_Data=(uint16_t)TIM1_CCR2H<<8;//读取高电平时长
IR_High_Data|=TIM1_CCR2L;
IR_Cycle_Data=(uint16_t)TIM1_CCR1H<<8;//读取数据时长
IR_Cycle_Data|=TIM1_CCR1L;
if(i==1)//第一个接收到的码是无效码,所以从第二个开始判断引导码
{
if(IR_Cycle_Data<12000)//判断引导码
{
i=0;
IR_Data=0;
return;
}
}
if(i>1)//开始读取数据
{
if(IR_Cycle_Data>1000&&IR_Cycle_Data<2600)//有效数据
{
IR_Data>>=1;
//这个地方可以添加一堆的高低电平判断代码,但是我觉得判断一个总的数据时长就可以了,实际也没有发生过错误
if(IR_Cycle_Data>1800&&IR_Cycle_Data<2600)//数据1
{
IR_Data|=0x80000000;
}
}
else//无效数据
{
i=0;
IR_Data=0;
return;
}//
}
i++;
}
void main(void)
{
HSE_Init();//使能外部晶振8MHZ
//CLOCK_Config(8);//使能内部HSI,2分频,频率8MHZ
delay_ms(300);
Init_UART2(9600);
TIM1_Capture_Init();
TIM1_CCER1|=0x11;//输入捕获使能
asm("rim");//使能全局中断
while(1)
{
if(i>33)//数据接受完毕
{
TIM1_CCER1&=0xEE;//捕获功能禁止"CC1E=0、CC2E=0"
//NEC协议是地位在前传输的,所以接收到的数据是反的,需要调整过来。
IR_Data=((IR_Data&0xff)<<24)|(((IR_Data>>8)&0xff)<<16)|(((IR_Data>>16)&0xff)<<8)|((IR_Data>>24)&0xff);
printf("%08lX\r\n",IR_Data);
TIM1_CCER1|=0x11;//输入捕获使能
i=0;
}
}
}