/*单片机:M16;外部晶体:8M;红外接收采用定时器0和外部中断0配合方式.定时器0用系统时钟256分频.红外协议:引导码-4.5ms低,4.5ms高;长信号为'1',短信号为'0';*/
#include "iom16v.h"#include "macros.h"
//*************** 位操作宏定义 ********************* #define set_bit(x,y) (x|=(1<<y)) //将x中的y位置1 #define clr_bit(x,y) (x&=~(1<<y)) //将x中的y位清0 #define xor_bit(x,y) (x^=(1<<y)) //将x中的y位取反 #define bit(x) (1<<x) //将1左移x位 #define get_bit(x,y) (x&(1<<y)) //取x中的第y位 //****************************************************
/*---------------------*/ /* 红外接收全局变量 */ /*---------------------*/ unsigned char ray_singal_num=0; //接受信号 unsigned char ray_byte_num=0; unsigned char ray_data_in=0; //ray_data_in为接收的数据 unsigned char ray_symbol=0; unsigned char ray_count_array[8]={0,0,0,0,0,0,0,0};//Bit位数组 unsigned char ray_timer=0; // unsigned char irda_data[4]; //irda receive buffer unsigned char irda_finish=0;
/******************************************************************** * 函数说明:定时器0初始化程序 * ********************************************************************/ void Timer0_init(void) { //初始化计时器 TCCR0=0x04;//系统时钟256分频 TCNT0=0x00;//tcnt清零 TIMSK=0x00;//关闭T/C中断屏蔽寄存器 }
/******************************************************************** * 函数说明:外中断0初始化程序 * ********************************************************************/ void int0_init(void) { MCUCR=0x02;//开中断0、下降沿触发脉冲 GIFR=0xff; }
#pragma interrupt_handler int0_isr:2/******************************************************************** * 函数说明:外中断0中断处理程序 * ********************************************************************/void int0_isr(void){ //external interupt on INT0 char temp =0; ray_timer=TCNT0; //读出计时器的值并重置,为了减小误差,故第一时间读出定时值. TCNT0=0; temp = TIMSK; //现场保护 TIMSK = 0; if (ray_symbol==3) //头码已接收完成,正接收数据 { if(TCNT0 < 125) { ray_count_array[ray_singal_num]=ray_timer; ray_singal_num++; if (ray_singal_num==8) { ray_singal_num=0; ray_judger(); irda_data[ray_byte_num-1]=ray_data_in; //save one byte data. if (ray_byte_num==4) //receive finished { irda_finish=1; ray_byte_num=0; ray_symbol=0; } } } else { ray_singal_num = 0; ray_symbol=0; } MCUCR = 0X02; //INT0下降沿触发 }//end if ray_symbol=3 else if(ray_symbol==0) //判断头码低电平 { ray_singal_num = 0; MCUCR = 0x03; //INT0上升沿触发 ray_symbol = 1; } else if (ray_symbol==1) //判断头码高电平 { if (ray_timer>125) //>4ms { ray_singal_num = 0; ray_symbol=2; } else ray_symbol=0; MCUCR = 0X02; //INT0下降沿触发 } else if (ray_symbol==2) //头码判断完成 { if (ray_timer>125) //>4ms { ray_singal_num = 0; ray_symbol=3; } else ray_symbol=0; MCUCR = 0X02; //INT0下降沿触发 }//else ray_symbol
TIMSK = temp; }
/******************************************************************** * 函数说明:红外信号处理程序 * ********************************************************************/ void ray_judger(void) { char i=0; ray_data_in=0; for(i=0;i<8;i++) //加入适当的冗错处理 { if(ray_count_array[i] < 53) //<1.6ms为低电平 { clr_bit(ray_data_in,i); } if(ray_count_array[i] >=53) //>1.6ms为高电平 { set_bit(ray_data_in,i); } } ray_byte_num++; }
/****************自定义函数********************//*函数名:irda_data_processing *//*功能:对接收到的红外数据解包分析 *//*参数: *//*输入: *//*输出: *//**********************************************/void irda_data_processing(){//&&(irda_data[1]==0x0c) int k; char irda_flag=0; if ((irda_data[0]==0x0b)&&(irda_data[1]==0x0c)) //Leader code { irda_flag=1; switch(irda_data[2]) { case ... default: ... }//end switch }//end if}
/*主函数*/void main(void) { int temp,i; CLI(); //disable all interrupts port_init(); Uart_Init(); int0_init(); Timer0_init(); // MCUCR = 0x00; SEI(); //re-enable interruptss GICR = 0x40; //Open external INT0// TIMSK = 0x00; //timer interrupt sources
/
while (1) {
if (irda_finish==1) { irda_finish=0; irda_data_processing(); }//end if-(irda data process)
}//end while}//end main