⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 遥控器遥控电风扇程序(全)
💻 C
字号:
/******************************************                                         
   电风扇遥控主程序  V1.0     2006/08/8
           作者: 王冠明                 
     目标MCU:MEGA8    外部晶振:4M 
编译:ICCAVR6.13A
      
1.RC5码解码
2.自然风产生
3.获得同步后,每1/2周期检测,读取到的电平就是数据了---反相 0就是1,1就是0。
******************************************/
#include <iom8v.h> 
#include <macros.h>
#include <stdlib.h>
#include "TEST_USART.h"

typedef unsigned char  uint8;
typedef unsigned int   uint16;
typedef unsigned long  uint32;
typedef signed   char  int8;
typedef signed   int   int16;
typedef signed   long  int32;

#define		BIT_SET(a,b)	a|=BIT(b)
#define		BIT_CLR(a,b)	a&=~BIT(b)
#define		BIT_INV(a,b)   	a^=BIT(b)
#define		BIT_STATUS(a,b) a&BIT(b)


#define	  BUZZER_ON()   PORTD&=~BIT(PD4)  
#define	  BUZZER_OFF()  PORTD|=BIT(PD4)

#define	  SCR1_ON()     PORTD&=~BIT(PD5)  
#define	  SCR1_OFF()    PORTD|=BIT(PD5)
#define	  SCR2_ON()     PORTD&=~BIT(PD6)  
#define	  SCR2_OFF()    PORTD|=BIT(PD6)
#define	  SCR3_ON()     PORTD&=~BIT(PD7)  
#define	  SCR3_OFF()    PORTD|=BIT(PD7)

uint8  renovate;//显示更新
uint8  LED;
uint8  KEY;
uint8  BUZZER_time;
uint8  estate;
uint8  timing;
uint16 IR_code_old;
uint16 IR_code_old_time;
uint8  nature_sign;//自然风
uint16 nature_time;
uint8  career;
uint16 LED_time;

uint16 nature2_time;
uint8  career2;
uint8  career2_ONOFF;

//系统初版始化
void intit(void)
{
    //看门狗
   WDR();  //喂狗
   WDTCR=BIT(WDCE)|BIT(WDE);
   WDTCR=BIT(WDE)|BIT(WDP2)|BIT(WDP1);  //使能watchdog,1024K分频,典型溢出时间5V时1S

   DDRD|=BIT(PD7)|BIT(PD6)|BIT(PD5)|BIT(PD4);
   PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5)|BIT(PD4);
     
   PORTB|=BIT(PB0); //IR   
   DDRC|=BIT(PC2);  //COM 
    
   //T2初始化 显示用      
   //OCR2=156;   //10mS 4M
   OCR2=78;     //5mS 4M
   TIMSK=BIT(OCIE2); //比较匹配中断使能
   TCCR2=BIT(WGM21)|BIT(CS22)|BIT(CS21);//256分频CTC模式
    
   //T1初始化 红外解码用 
   TCCR1B=BIT(ICNC1)|BIT(WGM12)|BIT(CS10);//噪声抑制 下降沿触发 CTC(模式4) 1分频
   TIMSK|=BIT(TICIE1);//输入捕捉中断使能
   
     
   SEI(); //开全局中断
  
}



/****************************************************************************
* 名称:    LED_KEY(void)
* 功能:    数码管,LED 显示驱动,按键读取
* 入口参数:
* 出口参数:
****************************************************************************/
void LED_KEY(void)
{

          uint8  i;
   static uint8  com;
   static uint8  KEY_life[3];//按键寿命

   if(renovate==0) return;
   //按键读取 
   DDRC&=~(BIT(PC5)|BIT(PC4)|BIT(PC3)); 
   PORTC|=BIT(PC5)|BIT(PC4)|BIT(PC3);    
   PORTC&=~BIT(PC2);
   
    
   NOP();
   NOP();
   
   for(i=0;i<3;i++)
   { 
   	 if((PINC&BIT(i+3))==0)
   	 	{
   	 	  if(KEY==0)
   	 	  	{
   	 	  		KEY_life[i]++;
   	 	 	    if(KEY_life[i]>50) KEY=i+1; 
   	 	 	  } 
   	 	 }		
   	 else 
   	 	{
   	 		KEY_life[i]=0;
   	 		if(KEY==(i+1)) KEY=10; 
   	 	}
   } 
   
   //显示
   if(LED_time>0)
   	{
     PORTC|=BIT(PC2);
     if((LED&BIT(com))&BIT(com)) 
   	  {
   	  	DDRC|=BIT(com+3);
   		  PORTC&=~BIT(com+3);
   	  }
    }    
   if(++com>2) com=0;
   renovate=0;
}


/****************************************************************************
* 名称:    timer2_comp_isr(void)
* 功能:    T2比较匹配中断处理
* 入口参数:
* 出口参数:
****************************************************************************/
#pragma interrupt_handler timer2_comp_isr:iv_TIMER2_COMP	
void timer2_comp_isr(void)
{  
   static uint16  minute;
   
   renovate=1;  
   	
   //蜂鸣
   if(BUZZER_time>0)     
   	 { 
   		   BUZZER_time--;
         BUZZER_ON(); 
   	 }
   else BUZZER_OFF();  
   	
   if(IR_code_old_time>0)
   	{
   		IR_code_old_time--;
   		if(IR_code_old_time==0) IR_code_old=0xffff;
   	}	
   
   if(nature_time>0) nature_time--;
   if(nature2_time>0) nature2_time--;
   	
   if(LED_time>0) LED_time--;	
   if(++minute==12000) //一分钟
   	{
   		minute=0;
   		if(timing>0) 
   			{
   				timing--;
   				if(timing==0) KEY=10;
   			}
   	}	
   	  
}


/*------------------------------------------------------------------------------ 
模块名称:PB0(ICP)引脚下降沿捕捉中断程序 

RC5码
____     
    |   |         
    |___|
|<-bit->| 
               
遥控器晶振455,一个bit=1.778ms  CPUclck 4M  7112
                       
                       
红外接收器输出是反相的
------------------------------------------------------------------------------*/
#define  bit    7112
uint16 IR_code;//红外遥控键码 
uint8  OK_read;//读码完毕标志
uint8  sign;   //半位记录
uint8  sign_i;

#pragma interrupt_handler timer1_capt_isr:iv_TIMER1_CAPT 
void timer1_capt_isr(void) 
{       
   OCR1A=bit/4; //第一次中断bit/4
   TCNT1=0;
   TIFR|=BIT(OCF1A);
   TIMSK&=~BIT(TICIE1);//清输入捕捉中断使能
   TIMSK|=BIT(OCIE1A);//输出比较 A 匹配中断使能 
   sign=1;
   sign_i=1;
     
}
//定时器T1匹配中断A服务程序
#pragma interrupt_handler timer1_compa_isr:iv_TIMER1_COMPA 
void timer1_compa_isr(void)
{ 
  static uint8  times;//记录捕捉次数 	
  
  OCR1A=bit/2;
  
  switch (sign_i)     
       {
		       case 0: 
		       	      if(PINB&BIT(PB0)) sign=1;
		       	      else sign=0;	
		       	      sign_i=1;	
		       break;
		       case 1:
		       	     sign_i=0;
		       	     sign<<=1;
		       	     if(PINB&BIT(PB0)) sign|=1;
		       	     IR_code<<=1; 
		       	     if(sign==0B10) IR_code|=1; 
		       	     times++;
		       	     if(times>13)
  	                {
  	                  times=0;
  	                  OK_read=1;
  	                  IR_code&=0xfff;
  	                  TIFR|=BIT(ICF1);
  		                TIMSK|=BIT(TICIE1);//输入捕捉中断使能
  		                TIMSK&=~BIT(OCIE1A);//清输出比较 A 匹配中断使能
  	                 }	
  	              if((sign==0B11)||(sign==0B00)) //错误重启
		       	     	  {
		       	     		  times=0; 
 		                  TIFR|=BIT(ICF1);
  		                TIMSK|=BIT(TICIE1);//输入捕捉中断使能
 		                  TIMSK&=~BIT(OCIE1A);//清输出比较 A 匹配中断使能
		       	     	  }  
		       break;
		     }
}

//工作转换
void SYS(void)
{ 
  if((KEY!=0)&&(OK_read!=0)) OK_read=0;
  switch (KEY)     
    {
		   case 0:
		   	     	if(OK_read)
		           {
		             LED_time=6000;
		             IR_code_old_time=100;
		             OK_read=0;
		   	     	   estate=IR_code&0x7ff;
		   	     	   if(IR_code!=IR_code_old)
		   	     	   	{
		   	     	     switch (estate)     
                    {
		                 case 1: //1档
		                 	      PORTD=(PORTD|(BIT(PD7)|BIT(PD6)))&(~BIT(PD5)); 
		                 	      BUZZER_time=10;
		                 	      career=1;
		                 	      nature_time=20000;
		                 	      career2_ONOFF=1;
		                 	      LED|=BIT(2);
		                 break;
		                 case 2: //2档
		                 	      PORTD=(PORTD|(BIT(PD7)|BIT(PD5)))&(~BIT(PD6)); 
		                 	      BUZZER_time=10;
		                 	      career=2;
		                 	      nature_time=20000;
		                 	      career2_ONOFF=1;
		                 	      LED|=BIT(2);
		                 break;	
		                 case 3: //3档
		                 	      PORTD=(PORTD|(BIT(PD6)|BIT(PD5)))&(~BIT(PD7));  
		                 	      BUZZER_time=10;
		                 	      career=3;
		                 	      nature_time=20000;
		                 	      career2_ONOFF=1;
		                 	      LED|=BIT(2); 
		                 break;	
		                 case 0: //0	
		                 case 12: //开关
		                 	       PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5);  
		                 	       BUZZER_time=10;
		                 	       timing=0;
		                 	       nature_sign=0;
		                 	       career=0;
		                 	       LED=0; 
		                 break;
		                 case 34: //自然风
		                 	       	switch (nature_sign)     
                                 {
		                               case 0:
		                               	      nature_sign++;
		                               	      nature_time=10000;
		                 	       		          LED|=BIT(1); 
		                               break;
		                               case 1:
		                               	      nature_sign++;
		                               	      nature_time=10000;
		                               	      career2_ONOFF=1;
		                               	      if(career==0)
		                               	      	{
		                 	       		              PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5);
		                 	       		              PORTD&=~BIT(5);
		                 	       		            }
		                 	       		          LED|=BIT(1); 
		                               break;
		                               case 2:
		                               	      nature_sign=0;
		                               	      PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5);  
		                 	       		          if(career>0) PORTD&=~BIT(career+4);     		
		                 	       		          LED&=~BIT(1);
		                               break;
		                              } 
		                 	       	BUZZER_time=10;   
		                 break;	
		                 case 38:   //定时
		                 	       if(timing<180) 
		                 	       	{
		                 	       		timing+=30;
		                 	       		BUZZER_time=10;
		                 	       		LED|=BIT(0); //定时指示
		                 	       	}
		                 break;	
		                 case 16:   //音+
		                 break;	
		                 case 17:   //音-
		                 break;	
		                 case 32:   //频+
		                 break;	
		                 case 33:   //频-
		                 break;								
		               }
		              }
                  IR_code_old=IR_code;
		            }
       break;
       case 1: PORTD=(PORTD|(BIT(PD7)|BIT(PD6)))&(~BIT(PD5));//按键1档
       	       career=0;
       	       timing=0;
       	       nature_sign=0;
       	       LED=0;
       break;	                      
       case 2: PORTD=(PORTD|(BIT(PD7)|BIT(PD5)))&(~BIT(PD6));//按键2档
       	       career=0;
       	       timing=0;
       	       nature_sign=0;
       	       LED=0;
       break;	
       case 3: PORTD=(PORTD|(BIT(PD6)|BIT(PD5)))&(~BIT(PD7));//按键3档
       	       career=0;
       	       timing=0;
       	       nature_sign=0;
       	       LED=0;          
       break;
       case 10: 
       	       PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5);
       	       career=0;
       	       timing=0;
       	       nature_sign=0;
       	       LED=0;
       	       KEY=0;                   
       break;
     }
}
//自然风
void nature(void) 
{
 if(nature2_time==0)
  	{
  		 nature2_time=rand()%150+200;
  		 career2++;
  	}
 if(career2>3) career2=1;
 if(nature_time==0)
  	{
  		 nature_time=rand()%12000+2000;
  		 switch (nature_sign)     
             {
		            case 1: 
		            	     if(career>0)
  		 	                  {
		            	          if(PORTD&BIT(career+4)) PORTD&=~BIT(career+4);	
  		 		                  else                    PORTD|=BIT(career+4);
  		 		                }
		            break;
		            case 2: 
		            	     PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5);
		            	     if(career2_ONOFF==1) career2_ONOFF=0;
		            	     else 
		            	     	{
		            	         career2_ONOFF=1;
		            	         PORTD&=~BIT(career2+4);	
  		 		               }
		            break;
		          }
  	}
 
}

  
//主程序
void main(void) 
{ 
  uint8 i;
  intit();
  TEST_USART_init();
  LED_time=6000;
  BUZZER_time=10;
  KEY=10;
  while(1)
  {
    WDR();       //看门狗计数清零
	  LED_KEY();
    SYS();
    nature(); 
    
//	 if(OK_read==1) //调试用
//	 {
//	    printf("%u",IR_code);
//	    printf("\r\n\r\n");    
//      OK_read=0;
//      IR_code=0;
//	  }     
   }   
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -