AVR单片机使用外部中断和定时器的NEC红外解码程序

    刚开始学习AVR单片机,移植了一个以前51上红外解码的程序,使用外部中断0和定时器0,使用外部8M晶振。

有一点可能需要大家注意一下,就是解码的时候定时器的配置。因为AVR单片机定时器0是一个8bit的定时器,根据个人晶振大小,大家要选择一个合适的定时器时钟的分频,既要满足NEC时序的时间长度要求,又要注意其分辨率是不是足够。

在使用时,首先运行初始化函数,程序里定义了一个接收成功的标志位全局变量,用户操作后要置0;

Ir_buf[ ]是接收到的数据的解码。

下面是程序:

/****************************************************************************
*  NEC 红外遥控接收
*  文件名:IR_Receive.c
*  资源占用:定时器0;   外部中断1	
*  AVR8515	晶振:8MHz
*
*  作者:DuPeng
*  版本日期:2016-11-1 18:20:32
*****************************************************************************/
#include "iom8515.h"
#include "IR_Receive.h"
#include "ModeManager.h"

#define DQ_IR (0x01<<2) //PD2
#define DQ_status() (PIND & DQ_IR)  //Read PD2

unsigned char IR_success = 0; 	//遥控接收成功
unsigned char Ir_Buf[4]; 		//用于保存解码结果

/****************************************************************************
*  红外接收初始化
****************************************************************************/
void NEC_IR_init(void)
{
  DDRD=0xFB;  //PD2  INT0 INPUT
  SREG = 0x80;  //使能全局中断
  MCUCR=0x02;       // 下降沿有效
  GICR=0x40;    //使能外部中断0
}

/*************************************
*  获取低电平时间
**************************************/
unsigned int Ir_Get_Low()
{
  TCCR0 = 0x05; //开启定时器0 1024分频
  TCNT0 = 0x00; //初始值
  while (!DQ_status());  //等待高电平
  TCCR0 = 0x00;           
  return TCNT0;
}

/**************************************
*  获取高电平时间
***************************************/
unsigned int Ir_Get_High()
{
  TCCR0 = 0x05; //开启定时器0 1024分频
  TCNT0 = 0x00; //初始值
  while (DQ_status());  //等待低电平
  TCCR0 = 0x00;           
  return TCNT0;
}

/****************************************************************************
*  外部中断服务函数
****************************************************************************/
#pragma vector=INT0_vect
__interrupt void int1_isr()
{
  unsigned int temp;
  char i,j;

  temp = Ir_Get_Low();
  if ((temp < 66) || (temp > 74))  //引导脉冲低电平8500~9500us
  {
    return;
  }
  temp = Ir_Get_High();
  if ((temp < 31) || (temp > 39))  //引导脉冲高电平4000~5000us
  {
    return;
  }

  for (i=0; i<4; i++) //4个字节
  {
    for (j=0; j<8; j++) //每个字节8位
    {
      temp = Ir_Get_Low();
      if ((temp < 1) || (temp > 7)) //200~800us
      {
         return;
      }
      temp = Ir_Get_High();
      if ((temp < 1) || (temp > 16)) //200~2000us
      {
        return;
      }
      Ir_Buf[i] >>= 1;
      if (temp > 8) //1120us
      Ir_Buf[i] |= 0x80;
    }
  }
  IR_success = 1; // 遥控接收成功
}


.h文件:

/****************************************************************************
*  NEC 红外遥控接收	( 头文件 )
*  作者:DuPeng
*  版本日期:2016-11-1 18:20:32
*****************************************************************************/


#ifndef _IR_Receive_H
#define _IR_Receive_H



#define key_power 0x45 
#define key_menu  0x47	 
#define key_test  0x44
#define key_back  0x43
#define key_play  0x15
#define key_del   0x0D	  // EQ
#define key_last  0x07
#define key_next  0x09
#define key_add   0x40	  // +
#define key_minus 0x19	  // -
#define key_0     0x16
#define key_1     0x0c
#define key_2     0x18
#define key_3     0x5E
#define key_4     0x08		      
#define key_5     0x1C
#define key_6     0x5A
#define key_7     0x42
#define key_8     0x52
#define key_9     0x4A


extern unsigned char Ir_Buf[4]; //用于保存解码结果
extern unsigned char IR_success; // 遥控接收成功


void NEC_IR_init(void);  // 红外接收初始化


#endif



  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值