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

📄 main.c

📁 以SMARTARM2200开发平台
💻 C
字号:
/****************************************************************************
* 文 件 名:main.c
* 功    能:使用外部中断3进行B1的控制,每当有一次中断时,即取反B1控制口,以便指示中断输入。
*           使用非向量中断方式。
* 说    明:将跳线器JP2 JP4短接,JP7断开,然后反复按下与释放KEY1。
****************************************************************************/
#include  "config.h"
#define     LEDCON        0Xf0000000    
#define	  BEEPCON	1<<7				// P0.7引脚控制B1,低电平蜂鸣,1<<7 等价于 0x80
#define   IRIN           (1<<20)        //P0.20为红外接收器数据线 

uint8  Time_Count=0;                   //IR接收基准计数 
uint8  DisPlay_Flag=0;                 //显示标志
uint8  rcv_stat;                       //当前接收状态(00--06)
uint8  Arrayj,Arrayk=0;                //数据接收寄存器的J与K
uint8  IrCount=0;                      //IR每位接收时间计数 
uint8  IRCOM[]={0xff,0xff,0xff,0xff,0x10,0x10};  //数据接收寄存器

void   DelayNS(uint32  dly);
void   DelayMS(uint8 ms);
void   Display(void);
void   F_ServiceIRDecode(void); 
/****************************************************************************
* 名称:IRQ_Time0()
* 功能:定时器0中断服务程序,取反LEDCON控制口。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq  IRQ_Time0(void)
{  
   if(Time_Count<255)
   {
   Time_Count++;} 
   else 
   {
   Time_Count=0;}
   
   F_ServiceIRDecode();
   
   T0IR = 0x01<<1;	    			         // 清除中断标志
   VICVectAddr = 0x00;				        // 通知VIC中断处理结束
}

/****************************************************************************
* 名    称:IRQ_Eint3()
* 功    能:外部中断EINT3服务函数,取反B1控制口。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void   __irq IRQ_Eint3(void)
{  
   EXTINT = 1<<3;		    // 清除EINT3中断标志   
   if(rcv_stat==0)
   {
    Time_Count=0;
    rcv_stat=01;
    Arrayj=0;
    Arrayk=0;
    IrCount=0;
   } 
 VICVectAddr = 0x00;  
}
/****************************************************************************
* 名称:DelayNS()
* 功能:长软件延时
* 入口参数:dly		延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void  DelayNS(uint32  dly)
{  uint32  i;

   for(; dly>0; dly--) 
      for(i=0; i<50000; i++);
}
/****************************************************************************
* 名称:DelayMS()
* 功能:Timer0延时
* 入口参数:dly		延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void  DelayMS(uint8 ms)
{  Time_Count=0;
  while(Time_Count<ms);
}
	
/****************************************************************************
* 名称:Time0Init()
* 功能:初始化定时器0,定时时间为0.5S,并打开中断。 
* 入口参数:无
* 出口参数:无
****************************************************************************/
void  Time0Init(void)
{  /* 初始化定时器0,实现0.14MS定时
      Fcclk = Fosc*4 = 11.0592MHz*4 = 44.2368MHz
	  Fpclk = Fcclk/4 = 44.2368MHz/4 = 11.0592MHz
   */
   T0PR = 99;			    				// 设置定时器0分频为100分频,得110592Hz
   T0MCR = 0x03<<3;		 					// 匹配通道1匹配中断并复位T0TC
   T0MR1 = 16;	    				        // 设置MR1比较值(0.14MS定时值)

   
   T0TCR = 0x03;		   					// 启动并复位T0TC
   T0TCR = 0x01; 
   
}
    

/*******************************************************************
  显示码值函数
*******************************************************************/
void  Display(void)
{
   IO2SET=0xffffffff;
   IO2CLR =(IRCOM[4]&0x0000000f)<<28; 
   DelayNS(1);
}
/*******************************************************************
  红外解码函数
*******************************************************************/		
void  F_ServiceIRDecode(void)
{
   switch(rcv_stat)
   {
   case 00:break;
   case 01:if(Time_Count>=15)
           {if (!(IRIN&IO0PIN)==0) 
            { rcv_stat=00;
	          return;
	        }
	        rcv_stat=02;
	       }
	       break;
   case 02:	if (IRIN&IO0PIN)     //等IR变为高电平,跳过9ms的前导低电平信号。 
            { rcv_stat=03;
	        }
	        break;
   case 03:	if (!(IRIN&IO0PIN))  //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
            { rcv_stat=04;
	        }
	        break;  
   case 04:if (IRIN&IO0PIN)      //等 IR 变为高电平  
           { IrCount=0;
             rcv_stat=05;
	        }                    
	        break; 
	        
   default:break;         
   }
   
   if(rcv_stat==05) 
   {	
   if(IRIN&IO0PIN)              //测量高电平时间 
     { IrCount++;
       if (IrCount>=30)
	   {rcv_stat=00; 
	   }                       //0.14ms计数过长自动离开。
	   return;  
	 } 
   else                        //高电平计数完毕    
     {          
     if(Arrayj<4)                    //收集四组数据
      {IRCOM[Arrayj]=IRCOM[Arrayj] >> 1;                  //数据最高位补“0”
      if (IrCount>=8) {IRCOM[Arrayj] = IRCOM[Arrayj] | 0x80;}  //数据最高位补“1”	  
       Arrayk++;
      if (Arrayk>=8) {Arrayk=0;  Arrayj++; }  //每组数据有8位	
      }
     if(Arrayj>=4)                 //接收数据完成
      {rcv_stat=06;
      IrCount=0;   
	if (IRCOM[2]!=((~IRCOM[3])&0xff))   //接收时间是否正确
         { 
         rcv_stat=00;
	 IrCount=0;
         return; 
        }
      if(IRCOM[0]!=0x00)         //比较用户码
        { 
         rcv_stat=00;
	 IrCount=0;
         return; 
        }
         IRCOM[4]=IRCOM[2] & 0x0F;     //取键码的低四位
         IRCOM[5]=IRCOM[2] >> 4;       //右移4次,高四位变为低四位  
         rcv_stat=00;                  //准备下次接收  
         DisPlay_Flag=01;
         return;      
	  }
	                             
          rcv_stat=03;
	  IrCount=0;
	  return;
     
	 }                   
   }	
 }                  
/****************************************************************************
* 名    称:main()
* 功    能:初始化外部中断3(EINT3)为非向量中断,并设置为电平触发模式,然后等待外部中断。
* 说    明:在STARTUP.S文件中使能IRQ中断(清零CPSR中的I位)。
****************************************************************************/
int  main(void)
{  
    IO2DIR = LEDCON;
    PINSEL1 = 3<<8;			        	// 设置管脚连接,P0.20设置为EINT3
                                    	// 3<<8 等价于 0x00000180
                                   
     //IO0SET  = IRIN;                 I/O口初始化  
    EXTMODE = 0x0F;					// 设置EINT3中断为边沿触发方式
    EXTPOLAR= 0x00;                  // 设置EINT3中断为下降沿触发 
                                    
    
    VICIntSelect = 0x00;				// 所有中断通道设置为IRQ中断
    /* 设置定时器0*/
   Time0Init();						// 定时器0初始化
   VICVectCntl0 = 0x20|04;			// 定时器0中断通道分配最高优先级(向量控制器0)
   VICVectAddr0 = (uint32)IRQ_Time0;// 设置中断服务程序地址向量 
   /* 打开EINT3中断(使用向量IRQ) */	
   VICVectCntl1 = 0x20|17;			// 分配EINT3中断到向量中断0
   VICVectAddr1 = (int)IRQ_Eint3; 	// 设置中断服务程序地址
   EXTINT = 1<<3;				// 清除EINT3中断标志					
  VICIntEnable = (1<<4)|(1<<17);	// 使能定时器、EINT3中断 
  while(1)							// 等待中断
  {
  if(DisPlay_Flag==0x01)
  {
   Display();
   DisPlay_Flag=00;
  }
  }   
  return(0);
}

⌨️ 快捷键说明

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