圣源电子制作

标题: NEC 6121 红外遥控器的解码-51C程序-M16C程序 [打印本页]

作者: sydz    时间: 2011-10-10 14:56
标题: NEC 6121 红外遥控器的解码-51C程序-M16C程序
(, 下载次数: 97)

(, 下载次数: 85)
(, 下载次数: 95)
(, 下载次数: 94)
(, 下载次数: 87)

51程序
  1. //#################################################################################################
  2. //文件:51单片机的红外遥控解码程序
  3. //属性:使用外部中断0连接遥控头,接收红外遥控键值送P2口显示,12MHz外部晶振
  4. //资源:P3.2=接收头输入,P2=8LED
  5. //#################################################################################################
  6. #include"reg52.h"

  7. #define uint unsigned int
  8. #define uchar unsigned char

  9. uchar led=0x00;

  10. void io_init(void);
  11. void int_init(void);

  12. void main(void)
  13. {
  14.         io_init();
  15.         int_init();
  16.         while(1);
  17. }

  18. void io_init(void)
  19. {
  20.         P0=0xff;
  21.         P1=0xff;
  22.         P2=0xff;
  23.         P3=0xff;
  24. }

  25. void int_init(void)
  26. {
  27.         EX0=1;
  28.         EA=1;
  29. }

  30. void interrupt0()interrupt 0
  31. {
  32.         uchar i=0,j=0,k=0,us=0;
  33.         uchar addr[4]={0};

  34.         EX0=0;

  35.         for(i=0;i<255;i++)  //9ms内有高电平认为是干扰
  36.         {
  37.                 if(P3&0x04)            //255的值实际时间为800us
  38.                 {
  39.                         EX0=1;
  40.                         return;
  41.                 }
  42.         }
  43.         while(!(P3&0x04));        //等待9ms低电平过去
  44.            for(i=0;i<4;i++)
  45.         {
  46.                 for(j=0;j<8;j++)
  47.                 {
  48.                         while(P3&0x04);        //等待4.5ms高电平过去       
  49.                         while(!(P3&0x04));        //等待0.56ms低电平后面的高电平
  50.                         while(P3&0x04)                //计算这个高电平的时间
  51.                         {
  52.                                 for(us=0;us<=32;us++);        //100us的延时语句
  53.                                 if((k++)>=30)                //高电平时间过长退出程序
  54.                                 {
  55.                                         EX0=1;
  56.                                         return;
  57.                                 }
  58.                         }
  59.                         addr[i]=addr[i]>>1;        //接收一位数据
  60.                         if(k>=8)
  61.                                 addr[i]=addr[i]|0x80;        //高电平大于0.56ms,则为1
  62.                         k=0;
  63.                 }
  64.         }       

  65.         P2=~(addr[2]);         //P2的LED显示二进制键值

  66.         EX0=1;          
  67. }          
复制代码

ATmega16单片机程序
  1. /***********************************************
  2. ****      AVR  红外接收范例           ***
  3. **** MCU: ATmega16                           ***
  4. **** 编译器:WINAVR                   ***
  5. ****                                         ***
  6. ****   2009.3.27           ***
  7. ***********************************************/

  8. #include <avr/io.h>         
  9. #include <util/delay.h>
  10. #include <avr/interrupt.h>   //中断函数头文件
  11. #include "usart.h"

  12. void INT_Init(void);   //外部中断初始化
  13. void Delayus(unsigned int lus);         //us延时函数
  14. void Delayms(unsigned int lms);        //ms延时函数
  15.   

  16. int main(void)            
  17. {
  18.    
  19. Port_Init();
  20. Usart_Init();
  21. INT_Init();
  22.    
  23. sei();          //使能全局中断   
  24.   
  25. while(1)
  26. {
  27.    
  28. }
  29. }

  30. //外部中断初始化
  31. void INT_Init(void)
  32. {
  33. MCUCR |= (1 << ISC01);   //选择外部中断0,下降沿触发中断
  34. GICR |= (1 << INT0);    //使能外部中断0
  35. GIFR |= (1 << INTF0);    //清除INT0中断标志位

  36. }  

  37. //
  38. ISR(INT0_vect)
  39. {
  40. unsigned char i,j,k = 0,addr[4] = {0};
  41.   
  42. GICR = 0x00;    //禁止外部中?   关闭外部中断,开始接受数据
  43. for(i = 0;i < 14;i++)
  44. {
  45.   Delayus(400);
  46.   if(PIND & (1 << PD2))    //9MS内有高电平,则判断为干扰,退出处理程序
  47.   {
  48.    GICR |= (1 << INT0);    //使能外部中断4
  49.    return;
  50.   }
  51. }
  52. while(!(PIND & (1 << PD2)));  //等待9ms低电平过去
  53. for(i = 0;i < 4;i++)               //
  54. {
  55.   for(j = 0;j < 8;j++)           //
  56.   {
  57.    while(PIND & (1 << PD2)); //等待4.5ms高电平过去
  58.    while(!(PIND & (1 << PD2))); //等待变高电平
  59.    while(PIND & (1 << PD2))  //计算高电平时间
  60.    {
  61.     Delayus(100);
  62.     k++;
  63.     if(k >= 30)             //高电平时间过长,则退出处理程序
  64.     {
  65.      GICR |= (1 << INT0);    //使能外部中断
  66.      return;            //
  67.     }
  68.      
  69.    }
  70.    addr[i] = addr[i] >> 1;        //接受一位数据
  71.    if(k >= 8)
  72.    {
  73.     addr[i] = addr[i] | 0x80;   //高电平时间大于0.56,则为数据1
  74.    }
  75.    k = 0;                  //计时清零
  76.   }
  77. }
  78.   
  79. Usart_PutChar(addr[0]);         //通过串口发送接收到的4个字节
  80. Usart_PutChar(addr[1]);
  81. Usart_PutChar(addr[2]);
  82. Usart_PutChar(addr[3]);
  83.   
  84. GICR |= (1 << INT0);    //使能外部中断
  85. }

  86. //
  87. //us级别的延时函数
  88. void Delayus(unsigned int lus)
  89. {
  90. while(lus--)
  91. {
  92.   _delay_loop_2(3);      //_delay_loop_2(1)是延时4个时钟周期,参数为3则延时12
  93.              //个时钟周期,本实验用12M晶体,则12个时钟周期为12/12=1us
  94.     }
  95. }

  96. //ms级别的延时函数
  97. void Delayms(unsigned int lms)
  98. {
  99. while(lms--)
  100. {
  101.   _delay_loop_2(3000);        //延时1ms
  102.     }
  103. }
复制代码

(, 下载次数: 60)
(, 下载次数: 71)


作者: 1260086278    时间: 2012-8-20 22:05
谢谢   学习一下




欢迎光临 圣源电子制作 (https://bbs.syyyd.com/) Powered by Discuz! X3.4