您的位置:首页 > 编程语言

分享一段M16解红外码的代码

2009-10-09 15:40 337 查看
/*
单片机: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: