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

📄 main.c

📁 一个完整的用AVR写的电话交换机程序 希望对从事安防的开发者有用
💻 C
字号:
#include "main.h"

void System_init(void);
unsigned char DTMF_Decode(void);
void fnTelRountineDoorphone(void);

unsigned int mLEDTm;
unsigned int StopCallTime;
unsigned char Mark[] PROGMEM= { " First Sun SRE-300TL-34 Ver:1.0 (20080303) Edit:Houdeping " };
unsigned char Mark2[] PROGMEM= { " ATMEG48/Int 8Mhz./BrownOut 4.3V/WatchDog " };

int main(void)
{ 
	System_init();	
	wdt_enable(WDTO_2S); 
	sei();

	while(1)
	{
	  if(bit_is_set( TIFR0, OCF0A))        // 1ms  
       { 
	    SetBit( TIFR0, OCF0A);
        fnTelRountineDoorphone();
		}

	wdt_reset();
	}
	return (0);
}



void System_init(void)
{
 DDRB=0b10000100;   //PB7:DoorRing  PB6:CheckHoldDoor  PB2:led
 PORTB=0b11000000;

 DDRC=0b100000;   //PC5:DTMF_OE    PC4:DTMF_DV  PC3:DTMF_D3  PC2: DTMF_D2  PC1:DTMF_D1  PC0:DTMF_D0
 PORTC=0b011111;  //
 
 DDRD=0b1111011;    //PD6:CTR/AIN  PD5:CTR/AOUT  PD3:POWER  PD2:SING  PD1:HOOK  PD0:OPEN
 PORTD=0b0000000;  
 
 
 
 // Time 0 Setting
 TCCR0A = _BV(WGM01); //clkT2S/64 ( 来自预分频器)
 TCCR0B = _BV(CS01)|_BV(CS00);
 OCR0A = 125;		                       // 64 * N =     1ms
 TCNT0 =0;
 
}				


void fnDoorphone_Free(void)
{

   //呼叫中心

    CallCenterRd=PINB & 0x40;	    //PD6:CTR/AIN  PD5:CTR/AOUT  PD3:POWER  PD2:SING  PD1:HOOK  PD0:OPEN
 	if(CallCenterRd != CallCenterPre )       //除抖动
	{	
		CallCenterPre=CallCenterRd;
		return;
     }	   
	if (!CallCenterPre)        //jump to key          
	{
        Doorphone_FunPt=1;
        ClrBit(PORTB,DoorRing);

        SetBit(PORTD,POWER);
        SetBit(PORTD,AOUT);     //开输出模拟开关
        ClrBit(PORTD,AIN);      //开输入模拟开关
        mLEDTm=500;
        StopCallTime=5000;   

        SetBit(PORTD,HOOK);
        SetBit(PORTD,OPEN);
        return;	  
     } 
 
 
   //门口机呼叫
    DoorRingRd=PIND & 0x04;	    //PD6:CTR/AIN  PD5:CTR/AOUT  PD3:POWER  PD2:SING  PD1:HOOK  PD0:OPEN
 	if(DoorRingRd!= DoorRingPre)       //除抖动
	{	
		DoorRingPre=DoorRingRd;
		return;
     }		   
	if (!DoorRingPre)        //jump to key          
	{  
	    Doorphone_FunPt=2;
        mLEDTm = 500;
        ClrBit(PORTB,DoorRing);
	    SetBit(PORTD,AOUT);     //开输出模拟开关
	    ClrBit(PORTD,AIN);      //开输入模拟开关
        SetBit(PORTD,POWER); 
        return;	
     } 
}


void fnCallCenter_WaitRing(void)//呼叫中心
{
  if (!(--mLEDTm) )
	{  
	   mLEDTm = 500;
	   SetBit(PINB,2);
	 }

  if(!(--StopCallTime))     //每隔1S检测中心机是否挂机
	{
       StopCallTime=5000;
	   if(PIND & 0x04)
       {	 
	     SetBit(PORTB,DoorRing);    
        } 
     }
  
  
  CallCenterRd=PINB & 0x40;	    //PD6:CTR/AIN  PD5:CTR/AOUT  PD3:POWER  PD2:SING  PD1:HOOK  PD0:OPEN
  if(CallCenterPre!=CallCenterRd)  //去抖动
	{
	  CallCenterPre=CallCenterRd;	//更新寄存值  OutsideRingRd: 1=Nothing 0=Ring
	  return; 	
	 }	 
   if(CallCenterRd)            //每隔1S检测中心机是否挂机
    {
	   Doorphone_FunPt=0;
	   
	   SetBit(PORTB,DoorRing);    
	   ClrBit(PORTD,HOOK);	
	   ClrBit(PORTD,OPEN);   	   	   
	   ClrBit(PORTD,AOUT);     //关输出模拟开关
	   SetBit(PORTD,AIN);      //关输入模拟开关
       ClrBit(PORTD,POWER);
	   ClrBit(PORTB,2);	 
	   while(!(PIND & 0x04));  
	   return;
      }
}

void fnDoorphone_WaitRing(void)//门口机呼叫
{
  unsigned char i;

  if (!(--mLEDTm) )
	{  
	   mLEDTm = 500;
	   SetBit(PINB,2);
	 }

   DoorRingRd=PIND & 0x04;	    //PD6:CTR/AIN  PD5:CTR/AOUT  PD3:POWER  PD2:SING  PD1:HOOK  PD0:OPEN
   if(DoorRingRd!= DoorRingPre)       //除抖动
	{	
		DoorRingPre=DoorRingRd;
		return;
     }		   
   if (DoorRingPre)        //jump to key          
	{
	   Doorphone_FunPt=0;
	   SetBit(PORTB,DoorRing);
	   ClrBit(PORTD,AOUT);     //关输出模拟开关
	   SetBit(PORTD,AIN);      //关输入模拟开关
       ClrBit(PORTD,POWER);
	   ClrBit(PORTB,2);
	   while(!(PINB & 0x40));
        return;	
     } 


  CallCenterRd=PINB & 0x40;	    //PD6:CTR/AIN  PD5:CTR/AOUT  PD3:POWER  PD2:SING  PD1:HOOK  PD0:OPEN
  if(CallCenterRd != CallCenterPre )       //除抖动
	{	
	  CallCenterPre=CallCenterRd;
	  return;
     }     
  if(!CallCenterPre)
   {
      i= DTMF_Decode();
      if(i==cXin)           //接听
      {
   	    SetBit(PORTD,HOOK);
   	    Doorphone_FunPt=3;
       }
    } 
}


void fnDoorphone_LinkExtPhoneHook(void)				//3
{
  unsigned char i;

  if (!(--mLEDTm) )
  {	 mLEDTm = 500;
     SetBit(PINB,2);
   }

  DoorRingRd=PIND & 0x04;	    //PD6:CTR/AIN  PD5:CTR/AOUT  PD3:POWER  PD2:SING  PD1:HOOK  PD0:OPEN
  if(DoorRingPre!=DoorRingRd)  //去抖动
	{
	  DoorRingPre=DoorRingRd;	//更新寄存值  OutsideRingRd: 1=Nothing 0=Ring
	  return; 	
	 }
 
  CallCenterRd=PINB & 0x40;	    //PD6:CTR/AIN  PD5:CTR/AOUT  PD3:POWER  PD2:SING  PD1:HOOK  PD0:OPEN
  if(CallCenterRd != CallCenterPre )       //除抖动
	{	
	  CallCenterPre=CallCenterRd;
	  return;
     }

  if(CallCenterPre || DoorRingPre)
  {	
	   Doorphone_FunPt=0;
	   
	   SetBit(PORTB,DoorRing); 
	   ClrBit(PORTD,HOOK);	   	   
	   ClrBit(PORTD,AOUT);     //关输出模拟开关
	   SetBit(PORTD,AIN);      //关输入模拟开关
       ClrBit(PORTD,POWER);
	   ClrBit(PORTB,2);	
	   while(!(PINB & 0x40));
	   return;   
   }


  i= DTMF_Decode();
  if(i==cJing)   //开锁
   {
       SetBit(PORTD,OPEN);		
       Doorphone_time =1000;
    }
  if (Doorphone_time)
	{
		if (!(--Doorphone_time))
		{
			ClrBit(PORTD,OPEN); 
		}
	}
}



const void (*Doorphone_FunTab[]) PROGMEM=
{
 	fnDoorphone_Free,  		    	//0 
	fnCallCenter_WaitRing,          //1
    fnDoorphone_WaitRing,			//2
	fnDoorphone_LinkExtPhoneHook,   //3
};


void fnTelRountineDoorphone(void)
{
	void (*pp)(void);
		pp=  (void *) pgm_read_word_near(Doorphone_FunTab+Doorphone_FunPt);
		pp();
}


unsigned char DTMF_Decode(void)
{
 unsigned char i;
   
   if(bit_is_clear(PINC,DTMF_DV))  
	 {		
	 	i=mDTMF1_Pre;
	 	mDTMF1_Pre =0;
		return i;	 

	 }else
	 	{	 		
			SetBit(PORTC,DTMF_OE);
	 		nop();nop();nop();nop();
			nop();nop();nop();nop();
			mDTMF1_Pre=PINC & 0x0f;
	 		ClrBit(PORTC,DTMF_OE);
	 		return 0;
		}

}

⌨️ 快捷键说明

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