找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3538|回复: 0
打印 上一主题 下一主题
收起左侧

基于attiny13的NEC红外线遥控信号解码程序

[复制链接]
跳转到指定楼层
楼主
ID:352246 发表于 2018-6-21 23:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近参考了网上的51红外线遥控遥控信号解码程序,编写了基于attiny13的NEC红外线遥控信号解码程序,拿出来给大家共勉,欢迎大家批评指正。程序如下:
#include <avr/io.h>
#include <avr/interrupt.h>

#define uchar unsigned char
#define star()  TCCR0B=(1<<CS01)|(1<<CS00)    //启动定时器,64分频,定时器时钟周期在53.3us~58.2us之间,中位数55.75us
#define stop()  TCCR0B=0                     //停止定时器  
#define ir_in PB1    //int0引脚定义

volatile uchar ir_flag=0;
volatile uchar ir_da[4];
/****************************************************/
uchar getHtime(void)           
{
  TCNT0=0;
  star();                        //开始计时
  while (PINB&(1<<ir_in))       //等待高电平结束
  {
   if (TCNT0>250) break;         //高电平时间太长不合法,退出等待
  }
   stop(); //停止计时     
  
  return TCNT0;
}
/****************************************************/
uchar getLtime(void)           
{
  TCNT0=0;
  star();                        //开始计时
  while ((PINB&(1<<ir_in))==0)       //等待低电平结束
  {
   if (TCNT0>250) break;         //高电平时间太长不合法,退出等待
  }
   stop(); //停止计时     
  
  return TCNT0;
}
/****************************************************/
ISR(INT0_vect)  //外部中断
{
  static uchar step=1;   //用于区分按键码和连续码以执行不同的中断程序
  uchar i,j;
  uchar byt=0;
  uchar time;
if (step)        //刚按下遥控器的按键,执行下面的程序段
{
  time=getLtime(); //接收并判定引导码的 9ms 低电平,
  if((time<152)||(time>171)) //时间判定范围为 8.5~9.5ms,超过此范围则说明为误码,直接退出
    {
GIFR=(1<<INTF0);  //写入 ”1” 来清零外部中断标志
    return; //结束外部中断程序
}
  time=getHtime();   //接收并判定引导码的 4.5ms 高电平
   if ((time<71)||(time>89))       //时间判定范围为 4.0~5.0ms,超过此范围则说明为误码,直接退出
   {
  GIFR=(1<<INTF0);  //写入 ”1” 来清零外部中断标志
    return; //结束外部中断程序   
   }
  for (i=0; i<4; i++)       //循环接收 4 个字节
   {   
    for (j=0; j<8; j++)
    {
    time=getLtime();
if ((time<6)||(time>14))    //时间判定范围为 340~780us,超过此范围则说明为误码,直接退出  
    {
  GIFR=(1<<INTF0);  //写入 ”1” 来清零外部中断标志
    return; //结束外部中断程序   
    }
    time=getHtime();
    if ((time>5)&&(time<15))  byt>>=1;  //时间判定范围为 340~780us,在此范围内说明该 bit 值为 0
        else if ((time>25)&&(time<35))  //时间判定范围为 1460~1900us,在此范围内说明该 bit 值为 1
    {
    byt>>=1;
    byt|=0x80;
                }
              else
                {
    GIFR=(1<<INTF0);  //写入 ”1” 来清零外部中断标志
                return; //结束外部中断程序
    }  
}
ir_da[i]=byt;
  }
  ir_flag=1;
   step=0;    //如果按键未松开,下次中断执行连发码处理程序
  GIFR=(1<<INTF0);  //写入 ”1” 来清零外部中断标志
}

else   //如果是连发码执行下面的程序段
  {
  time=getLtime(); //接收并判定连发码引导码的 9ms 低电平
  if((time<152)||(time>171)) //时间判定范围为 8.5~9.5ms,超过此范围则说明为误码,直接退出
    {
step=1;     //下次中断执行按键处理程序
GIFR=(1<<INTF0);  //写入 ”1” 来清零外部中断标志
    return; //结束外部中断程序
}
  time=getHtime();   //接收并判定连发引导码的 2.25ms 高电平
   if ((time<36)||(time>44))       //时间判定范围为 2.0~2.5ms,超过此范围则说明为误码,直接退出
   {
    step=1;     //下次中断执行按键处理程序
  GIFR=(1<<INTF0);  //写入 ”1” 来清零外部中断标志
    return; //结束外部中断程序   
   }else     //确定为连发码
    {
ir_flag=1;
    step=0;    //如果按键仍未松开,下次中断继续执行连发码处理程序
    GIFR=(1<<INTF0);  //写入 ”1” 来清零外部中断标志
}
  }
}
/****************************************************/
int main(void)
{
  PORTB=0xff;  
   MCUCR=(1<<ISC01);     //INT0 的下降沿产生异步中断请求
  GIMSK=(1<<INT0);       //外部引脚中断使能
  sei();                 //开全局中断
  while (1)
  {;}
}
attiny13使用内部时钟,电源电压5V时实测1.15MHz左右。编译器为GCC

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表