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

📄 mnet.c

📁 一个完整的用AVR写的电话交换机程序 希望对从事安防的开发者有用
💻 C
字号:
// M-Net Communication Rountine
// Ver: 1 
// Brian Lam 2006-6-3
// Timer 2 to Calu the Input Wave
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
//#include <avr/signal.h>
#include <inttypes.h>
#include "main.h"
#include <avr/eeprom.h>


extern unsigned char Id1_Eeprom[cIDMax] __attribute__((section(".eeprom")));
extern unsigned char Id2_Eeprom[cIDMax] __attribute__((section(".eeprom")));
extern unsigned char Key_Eeprom[cIDMax] __attribute__((section(".eeprom")));
extern unsigned char Path_Eeprom[cIDMax] __attribute__((section(".eeprom")));
extern unsigned char Path2_Eeprom[cIDMax] __attribute__((section(".eeprom")));
extern unsigned char RecodeNM_Eeprom __attribute__((section(".eeprom")));
extern unsigned char LeftNM_Eeprom[4] __attribute__((section(".eeprom")));
//extern unsigned char RightNM_Eeprom[4] __attribute__((section(".eeprom")));
extern unsigned char ID_HEeprom __attribute__((section(".eeprom")));
extern unsigned char ID_LEeprom __attribute__((section(".eeprom")));
//extern unsigned char RFKey_Eeprom __attribute__((section(".eeprom")));



  // INT0 的下降沿产生异步中断请求
struct MNetBuff MNetRxTmp;
struct MNetBuff MNetTx;


unsigned int mRandomTm;		// Genera Random Timing
//----------------- Function List -----------------------------------
void  fnCpTxFifoToTm(void);  //  Copy  FIFO Buffer NetTxBuf to MNetTx
void 	MNetTxMod(void);

unsigned char mRq232TxStatus;
#define mRqRx	0

unsigned char MNetRxErr =0;
#define MNetOverFlow

unsigned char MNetRxFlag =0;
#define MRxBitV			0
#define MRxFErr			1
#define MRxBitF			2


unsigned char MNetTxFlag;
#define MTxBuzz			0
#define MTxErr			1		// Packet Transmit Fault
#define MTxTmOver		2		// Network too buzzy or Net Work Fault



unsigned char MNetIdle=0;	// Set When Transmition is Idle 


unsigned char MRxStatus = 0;


#define Timer2Off()	(TCCR2B &= 0b11111000)
#define Timer2On()	(TCCR2B |= 0b1)		//clkI/O/1 ( 无预分频)

#define cBitCheck	100
#define cBit1Tx		240		// n /8 us = 30us (3.3k) 
#define cBit0Tx		400		// n /8 us = 50us (20k)

#define cBit1RxLw	120		// n /8 us 
#define cBit1RxUp	320		// n /8 us 
#define cBit0RxLw	320		// n /8 us 
#define cBit0RxUp	500		// n /8 us 

#define cNetIdleTm		10000	// n us  = 10ms
#define cNetIdelTm_Tx	2000	// n us	 = 2ms


#define	cTxRdDelay   19		// 3 x N Mach Cycle

const unsigned char tbOddParity[] PROGMEM=  {\
	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,\
	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,\
	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,\
	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,\
	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,\
	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,\
	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,\
	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1
};


void  fnMNetDetermine(void)
{
	//unsigned char i;
 	switch ( MNetRxTmp.Buf[1] )
	{

	    case 1: // 系统 ---------------------------------------------------------
			 break;

		case 2: // 通讯设备 ------------------------------------------------------
			 break;

		case 4: // 安防 -------------------------------------------------------------
		      break;
			
		case 8: // 设备控制
           {
             switch ( MNetRxTmp.Buf[2] )
			 {
			  case 0x01: fnRx0801_Code();
			             break;//目标名称控制  
			  case 0x02: 
			             break;//目标ID控制
			  case 0x11: fnRx0811_Code();
			             break;//ID间接控制
              case 0x03: 
			             break;//状态反馈
              }
           }break;
     }
}


void fnRx0801_Code(void)
{

}

void fnRx0811_Code(void)
{

}




void MNetInitRx(void)
{
	// 	信号输出 PB1 OC1A/PCINT1
	//  信号输入 PB0 PCINT0/ICP1	= PD2	(PCINT18/INT0) 

	MNetIdle = 0;
	PORTB &= 0b11111100;			
	DDRB &=  0b11111100;

	EICRA |= _BV(ISC01);  // INT0 的下降沿产生异步中断请求
	SetBit(EIFR,INTF0); //标志位也可以通过写入”1” 来清零
	SetBit(EIMSK,INT0); //外部中断请求0 使能

}



void MNetRxTmCapture_On(void)
{
	TCCR1A &= ~(_BV(COM1A1)|_BV(COM1A0));  // 普通端口操作,非OC1A/OC1B 功能
//	TCCR1B =  _BV(ICNC1)|  _BV(CS10); // 捕捉噪声抑制, 下降沿触发, 普通模
	TCCR1B =   _BV(CS10); // 捕捉噪声抑制, 下降沿触发, 普通模

	TCNT1 =0;
	OCR1A = cBit1RxLw; 	// Set Hig Feq
	OCR1B = cBit1RxUp;	
	ICR1  = cBit0RxUp;	// Lowwer Feq.

	SetBit( TIMSK1,ICIE1); // 输入捕捉中断使能

	TIFR1 = _BV(ICF1)|_BV(OCF1B)|_BV(OCF1A)|_BV(TOV1); // 清除该标志 ICF1 – – OCF1B OCF1A TOV1 

}


void MNetInitClose()
{
	// 	信号输出 PB1 OC1A/PCINT1
	//  信号输入 PB0 PCINT0/ICP1	= PD2	(PCINT18/INT0) 
	ClrBit(EIMSK,INT0); //外部中断请求0 屏蔽
	ClrBit(TIMSK1,ICIE1); // 输入捕捉中断屏蔽

	TCCR1A &= ~(_BV(COM1A1)|_BV(COM1A0));  // 普通端口操作,非OC1A/OC1B 功能
	TCCR1B =  0; //无时钟源 (T/C 停止)

	TCNT1 =0;
	OCR1A = cNetIdleTm; 	// Set Hig Feq
	OCR1B = cNetIdleTm + cNetIdelTm_Tx + (mRandomTm & 0x07FF) ;
	TIFR1 = _BV(ICF1)|_BV(OCF1B)|_BV(OCF1A)|_BV(TOV1); // 清除该标志 ICF1 – – OCF1B OCF1A TOV1 
	
	MNetIdle =1;
	
}


void MNetInitIdel()
{
	// 	信号输出 PB1 OC1A/PCINT1
	//  信号输入 PB0 PCINT0/ICP1	= PD2	(PCINT18/INT0) 
	ClrBit(EIMSK,INT0); //外部中断请求0 屏蔽
	ClrBit(TIMSK1,ICIE1); // 输入捕捉中断屏蔽

	TCCR1A &= ~(_BV(COM1A1)|_BV(COM1A0));  // 普通端口操作,非OC1A/OC1B 功能
//	TCCR1B =  _BV(ICNC1)| _BV(CS11); // 捕捉噪声抑制, 下降沿触发, clkI /8 
	TCCR1B =  _BV(CS11); // 捕捉噪声抑制, 下降沿触发, clkI /8 

//	PORTB &= 0b11111100;				//
//	DDRB &=  0b11111100;				//

	TCNT1 =0;
	OCR1A = cNetIdleTm; 	// Set Hig Feq
	OCR1B = cNetIdleTm + cNetIdelTm_Tx + (mRandomTm & 0x07FF) ;
	TIFR1 = _BV(ICF1)|_BV(OCF1B)|_BV(OCF1A)|_BV(TOV1); // 清除该标志 ICF1 – – OCF1B OCF1A TOV1 
	
	MNetIdle =1;
	
}



#define cRxTmOver	200

#define mcDecodeBit() mTm = cRxTmOver; while (bit_is_clear(MNetRxFlag,MRxBitF)) { if   (!(--mTm))  goto lbMNetRxErrOver; } if (bit_is_set(MNetRxFlag,MRxFErr))   goto lbMNetRxErrShort; ClrBit(MNetRxFlag,MRxBitF)

SIGNAL(SIG_INTERRUPT0) // M-Net Data Input Interrupt, Use to Cal the Wave Len with Timer 2
{

	unsigned char mTm;
	unsigned char mi;
	unsigned char *mj;
	unsigned char mRxData;
	unsigned char Parity;
	unsigned char mCheckSum;
	unsigned char mLen;

	ClrBit(EIMSK,INT0); //外部中断请求0 屏蔽

	MNetRxTmCapture_On();
	sei();
	mTm = cRxTmOver;
	while (bit_is_clear(MNetRxFlag,MRxBitF))			//第一位不要
	 {
		if  (!(--mTm))  break; 			// Time Out 
	 }
	MNetRxFlag=0;


	while (bit_is_clear(MNetRxFlag,MRxBitF))			//第2位不要
	 {
		if  (!(--mTm))  goto lbMNetRxErr; 			// Time Out 
	 }
	MNetRxFlag=0;


	mi = 8;

	while(1)						// Wait Start Bit
	{
		mTm = cRxTmOver;
		while (bit_is_clear(MNetRxFlag,MRxBitF))			//第一位不要
	 		{
				if  (!(--mTm))  goto lbMNetRxErr; 			// Time Out 
			}
		if (bit_is_set(MNetRxFlag,MRxFErr))   goto lbMNetRxErr;
		ClrBit(MNetRxFlag,MRxBitF);	

		if (bit_is_set(MNetRxFlag,MRxBitV)) break; // If Start Bit then Break

		if (!(--mi)	) goto  lbMNetRxErrSB;			// No Start Bit
	 }

	
	mRxData=0;
	for(mi=2; mi>0; mi--)
	{
		mcDecodeBit();
  		mRxData <<=1;
	   if (bit_is_set(MNetRxFlag,MRxBitV)) mRxData++;
	}
	MNetRxTmp.Try = mRxData;

	mLen=0;
	for(mi=6; mi>0; mi--)
	{
		mcDecodeBit();
  		mLen <<=1;
	   if (bit_is_set(MNetRxFlag,MRxBitV)) mLen++;
	}
	mRxData = mRxData + mLen;
	Parity = (unsigned char) pgm_read_byte_near(tbOddParity+mRxData);
	mcDecodeBit();
	if	(Parity	)
	{
		if (bit_is_clear(MNetRxFlag,MRxBitV))	goto lbMNetRxErr;		
	}
	else	if (bit_is_set(MNetRxFlag,MRxBitV))	goto lbMNetRxErr ;
	
	if (mLen >40 ) 	goto lbMNetRxErr; 
	MNetRxTmp.Buf[0] = mLen;
	
	mj = &MNetRxTmp.Buf[1];
	
	mCheckSum = 0;
	do 
	{
		mRxData=0;
		for(mi=8; mi>0; mi--)
		{
			mcDecodeBit();
  			mRxData <<=1;
	   		if (bit_is_set(MNetRxFlag,MRxBitV)) mRxData++;
		}

		Parity = (unsigned char) pgm_read_byte_near(tbOddParity+mRxData);
		mcDecodeBit();
		if	(Parity	)
		{
			if (bit_is_clear(MNetRxFlag,MRxBitV))	goto lbMNetRxErrPar;		
		}
			else	if (bit_is_set(MNetRxFlag,MRxBitV))	goto lbMNetRxErrPar ;
	
		*mj = mRxData;
		mCheckSum+=mRxData;
		mj++;
		mLen--;		

	}while (mLen);
	
	if (mCheckSum) goto lbMNetRxErrCS;		// CheckSum Err
	SetBit (MNetRxFlag,cNetRx);	//  Bit Set and the Main Rountine will copy MNetRx[j].Buf[i] =MNetRxTmp.Buf[i];
	MNetInitIdel();
 	mcLed2Tg();
	return;

lbMNetRxErrShort:
lbMNetRxErrOver:
lbMNetRxErrPar:
lbMNetRxErrCS:
lbMNetRxErrSB:
lbMNetRxErr:

	mcLed1Tg();
	MNetInitIdel();


}

extern void (*RS232TxPt)(void);		// Point to Job
extern void RS232TxData(void);
extern unsigned char RS232Flag;
#define RSTxRq 	0			// If Set, Tx Request ( M-Net Receive Data)
#define RxTxFn	1			// If Set, One Tx to PC Complete and Wait PC FeedBack
#define RSEr 	2			
#define RSComp	3			// 补码







void MNetTxMod()
{
	// 	信号输出 PB1 OC1A/PCINT1
	//  信号输入 PB0 PCINT0/ICP1	= PD2	(PCINT18/INT0) 

unsigned char i,k;
unsigned char mData,Parity;
unsigned char mLen;

	ClrBit(TIMSK1,ICIE1); // 输入捕捉中断屏蔽
	ClrBit(EIMSK,INT0); //外部中断请求0 屏蔽

	TCNT1 =0;
	OCR1A = cBit0Tx/2;
	OCR1B = cBitCheck /2;

	TCCR1B =  _BV(ICNC1)| _BV(WGM12)| _BV(CS10); // 捕捉噪声抑制, 下降沿触发, clkI
	SetBit(TCCR1A,COM1A0);  // 比较匹配时OC1A 电平取反
	SetBit(PORTB,PB1);	// Output Hight
	SetBit(DDRB,DDB1);	// Set PB1 Output Mode
	TIFR1 = _BV(ICF1)|_BV(OCF1B)|_BV(OCF1A)|_BV(TOV1); // 清除该标志 ICF1 – – OCF1B OCF1A TOV1 
	
	
	if (bit_is_clear(PINB,PB1)) SetBit(TCCR1C,FOC1A);			//Match OC1A Output  *** Cannot Read (bit_is_set(PINB,1))

	// Send Syn Bit

	mData =  0x1;
	i = 8;
	do
	{
		if (bit_is_set(mData,7)) OCR1A = cBit1Tx/2;
			else OCR1A = cBit0Tx/2;
		mData<<=1;

		while (bit_is_clear(TIFR1,OCF1A));  	// O/P H to L
			SetBit(TIFR1,OCF1A);
		
			_delay_loop_1(cTxRdDelay); 			// 1+ 3xn 
		 if ( bit_is_clear(PINB,0) ) goto lbMNetTxErr1;

		while (bit_is_clear(TIFR1,OCF1A));  	// O/P L to H
			SetBit(TIFR1,OCF1A);
		
	}while (--i);


	k=0;
	mLen = MNetTx.Buf[0] + 1;
	MNetTx.Buf[0] = (MNetTx.Try<<6) + MNetTx.Buf[0];
	do
	{
		mData	 = MNetTx.Buf[k];
		Parity = (unsigned char) pgm_read_byte_near(tbOddParity+mData);
		i = 8;
		do
		{
			if (bit_is_set(mData,7)) OCR1A = cBit1Tx/2;
				else OCR1A = cBit0Tx/2;
			mData<<=1;	

			while (bit_is_clear(TIFR1,OCF1B));
			 if ( bit_is_set(PINB,0) ) goto lbMNetTxErr2 ;  	// O/P H to L
			SetBit(TIFR1,OCF1B);

			while (bit_is_clear(TIFR1,OCF1A)); // O/P H to L				
			SetBit(TIFR1,OCF1A);		

			while (bit_is_clear(TIFR1,OCF1B));
			 if ( bit_is_clear(PINB,0) ) goto lbMNetTxErr2;  	// O/P L to H
			SetBit(TIFR1,OCF1B);
								 		
			while (bit_is_clear(TIFR1,OCF1A));  	// O/P L to H
			SetBit(TIFR1,OCF1A);
			
		}while (--i);

			if (Parity) OCR1A = cBit1Tx/2;
				else OCR1A = cBit0Tx/2;

			while (bit_is_clear(TIFR1,OCF1B));
			 if ( bit_is_set(PINB,0) ) goto lbMNetTxErr2 ;  	// O/P H to L
			SetBit(TIFR1,OCF1B);

			while (bit_is_clear(TIFR1,OCF1A));  	// O/P H to L
				SetBit(TIFR1,OCF1A);						

			while (bit_is_clear(TIFR1,OCF1B));
			 if ( bit_is_clear(PINB,0) ) goto lbMNetTxErr2;  	// O/P L to H
			SetBit(TIFR1,OCF1B);
			
			while (bit_is_clear(TIFR1,OCF1A));  	// O/P L to H
				SetBit(TIFR1,OCF1A);	

	  k++;
	} while (--mLen);

	while (bit_is_clear(TIFR1,OCF1A));  	// End Bit
	SetBit(TIFR1,OCF1A);

	ClrBit(PORTB,PB1);	// Output Hight				
	ClrBit(DDRB,DDB1);				// 
	SetBit (TCCR1C,FOC1A);			//Match OC1A Output 


	MNetTx.Buf[0] = MNetTx.Buf[0] & 0b111111;
	MNetTxFlag = 0;				// Tx Sucess
	MNetTx.Try = 0;
	MNetInitIdel();
	mRq232TxStatus =1;

	ClrBit(MNetStatus,cNet_Tx);		// Set Tx Flag
	if (bit_is_set(PINB,2))  SPDR = MNetStatus;	
 	mcLed3Tg();

	return;

lbMNetTxErr1:	// Start Err
lbMNetTxErr2:	// Data err	

	OCR1A = cBit0Tx/2;
	i = 16;
	if (bit_is_set(PINB,PB1)) i--;
	do
	{
		while (bit_is_clear(TIFR1,OCF1A));  	// O/P H to L
			SetBit(TIFR1,OCF1A);
	}while (--i);

	
	MNetTx.Buf[0] = MNetTx.Buf[0] & 0b111111;

	ClrBit(PORTB,PB1);	// Output Hight				
	ClrBit(DDRB,DDB1);				// 

	MNetInitIdel();
	MNetTx.Try++ ; 
	 if ( MNetTx.Try > 3 ) 
	 	{
			MNetTxFlag = _BV(MTxErr);	// Set Transmit Err
			ClrBit(MNetStatus,cNet_Tx);		// Set Tx Flag
			mRq232TxStatus =1;
		}

	mcLed1Tg();

}


void  fnCpTxFifoToTm(void)  //  Copy  FIFO Buffer NetTxBuf to MNetTx
{
	unsigned char i,j;
	mMNetTxCn--;
	
	j=mMNetTxPt;	
	mMNetTxPt++;
	if (mMNetTxPt>= cMNetTxPacketNm ) mMNetTxPt=0;

    i = mMNetTxBuf[j].Buf[0] + 1;
		do 
		{
			i--;
				MNetTx.Buf[i] = mMNetTxBuf[j].Buf[i];
		} while (i);
	  
	  SetBit(MNetTxFlag,0);

}

	

⌨️ 快捷键说明

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