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

📄 trans628.c

📁 使用PIC16F628和U2280构建的门禁控制机,有原理图
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
TRANSPONDER PROGRAM
== IMPLEMENTATION of SALVO 3.0 RTOS kernel
== TARGET ORIGINAL MODULE with 16F628/4 processor
== design - c:\1654\sheets\trans\trans.opj	- scheme of module and transconnections


01/06/2002 -- 18:00		// STARTING THE PROJECT
03/06/2002 -- 09:00		// experimenting over real object
03/06/2002 -- 12:00 		// buzzer is moved on PWM pin for better performance
04/06/2002 -- 14:00		// get codes from cards
04/06/2002 -- 19:00		// sort codes by value (to avoid shift of codes)
05/06/2002 -- 07:00		// sorting codes new algorythm (get header, check parity, etc,)
06/06/2002 -- 14:00		// adjusting real times on etalon 512 uS generator of data
07/06/2002 -- 05:00		// improved algorythm for Manchester decoding
07/06/2002 -- 12:30		// read CODE TESTED !!! OK	- checksums - OK!!! RELIABLE operations
08/06/2002 -- 05:00		// finalization of project /DOOR control /sounds /times
08/06/2002 -- 11:00		// tested OK - RELIABLE OPERATIONS on all tests!!!
08/06/2002 -- 14:00		// ported to 16F628 - PORTA settings should take care

run on 4 MHz quartz
Watch DOG 	ON
BOD			OFF
*/

//========= DEFINITION of events in RTOS
#define BINSEM_Found		OSECBP(1)	// binary semaphore - code appeared

#include "pic.h"			// include main library of HiTech

__CONFIG(0x0305);			// configure processor
__IDLOC(0003);				// write the version in location
#include "salvokrn.h"	// include SALVO functionality


// some standard definitions
/***********************************************************************************************/
typedef	unsigned char byte;			// creates new type of data - byte==unsigned char
typedef	unsigned int  word;			// creates new type of data - word==unsigned int
#define nop() asm("nop")				// defines NOP command



/***********************************************************************************************/
//	definitions of some CONSTANTS
/***********************************************************************************************/
/* 4MHz CLOCK COMPENSATIONS
10ms	- 99		OPTION = 0b10000101	//prescaller 1:64 Every 10 ms synchronize (16ms)
20ms	- 99		OPTION = 0b10000110	//prescaller 1:128 Every 20 ms synchronize (32ms)


*/

/***********************************************************************************************/
// VARIABLES
/***********************************************************************************************/
static bit flag_OPEN;			// if 1 - the system should be opened
static bit flag_NO_MASTER_CARD;	// if =1 in the system there is no master card at all
static byte flag_PRESENSE;					// if there is a card or NOT (has some memory time 300ms)
static bit flag_DETECTED;					// in the coild field were a card
static bit flag_ERROR;						// to calculate row and column parities

static byte counter_BUZZER;				// controls beeps
static byte  count_BUZZER;
static byte CODE_ARRAY[5];					// array with codes that should be compared with EEPROM
static byte STAC[8];							// long stack for DATA up to 64 bit codes
static byte column_parity[4];				// calculates column checksums
static byte val;								// used in conversions
static word position, danni;				// used in conversion from native data to real one
static byte counter_bits;					// how many bits were captured
static byte counter_PROGRAM_MODE;		// how longs stays program mode without cards
static byte splitter;						// used in ISR to get the sequence of detection
static byte datas;							// used in ISR to clear RBIF event
static byte	 counter_ACTIVE_OUT,counter_ACTIVE_CLOSE,counter_ACTIVE_OPEN;
static word  counter_AUTO_CLOSE;


#define AUTO_OFF_PROGRAM_MODE	250		// 25s and auto OFF programing mode

#define adjust_10ms 	99			//TMR0 adjustment

#define time_10ms		1					// 10ms delay
#define time_20ms		2					// 20ms delay
#define time_30ms		3					// 30ms delay
#define time_40ms		4					// 40ms delay
#define time_50ms		5					// 50ms delay
#define time_60ms		6					// 60ms delay
#define time_80ms		8					// 80ms delay
#define time_90ms		9					// 90ms delay
#define time_100ms	10					// 100ms delay
#define time_150ms	15					// 150ms delay
#define time_200ms	20					// 200ms delay
#define time_300ms	30					// 300ms delay
#define time_350ms	35					// 350ms delay
#define time_500ms	50					// 500ms delay
#define time_1s		100				// 1s delay

#define TIME_ACTIVE_ON	50				// 5s minimal time to stay OUT0 active 
#define TIME_OPEN_ON		15				// 1.5s motor activity
#define TIME_CLOSE_ON	15				// 1.5s motor activity
#define TIME_AUTO_CLOSE	 300			// 0.5min auto close time  	
#define BEEP_100ms		1				// 100ms short beep
#define BEEP_500ms		5				// 500ms short beep
#define BEEP_1s			10				// 1s beep time
#define BEEP_5s			50				// 5s beep


#define TIME_RESET_ALL 			1200		// after 2min holding the master will erase whole EEPROM, except master
#define TIME_RESET_SOUNDS		100		// will change the sound when near to end

#define MAX_CODES			25				// maximal number of CODES in EEPROM (0..24)
#define MASK_INPUT		0x10			// used to read the input status

//---------- definitions for times for MANCHESTER decoding ----------
//---------- for ELATEK & FUTUREL transponders with baut rate 1:64 of Fosc (125KHz)
// --------- middle times short = 256 uS  long=512 uS +/- 60uS tolerance


#define TIME_L1	480					// time long minimum 512 - 60uS
#define TIME_L2	550					// time long maximum	512 + 60uS
#define TIME_LONG 230					// how long after overflow of 350 accumulated
#define TIME_S2	350					// time short maximum 256 + 60us	// will stop the sequence if wrong

// was working with FED0
#define COUNT_TIME_NEXTA	0xFEA0	// direct time in TMR1 (65565-360)us with 70uS compensation
												// to get next edge used in main procedure for reading

#define COUNT_TIME_NEXTB	0xFEA0	// direct time in TMR1 (65565-360)us with 70uS compensation
												// used in procedure of syncro

static word TMR1 @ 0xE;					// defines the TMR1 registers like a pair

/***********************************************************************************************/
// PIN descriptions
/***********************************************************************************************/
#define BUZZER	RA3		//PWM register -  to modulate piezo BUZZER with low frequency
#define OUT0	RB5
#define OUT1	RB6
#define OUT2	RB7
#define CFE		RA2		// carrier frequency enable input
#define DOOR	RB2		// door switch

/***********************************************************************************************/
unsigned char read_EEPROM(unsigned char ADDR)		// read byte from EEPROM
/***********************************************************************************************/
{	//tested 29.04.2000 - OK


	EEADR = ADDR;		// write address
	RD = 1;

	nop();
	
	return(EEDATA);		// return read value

}


/***********************************************************************************************/
void write_EEPROM(unsigned char ADDR, unsigned char DATAS)		// read byte from EEPROM
/***********************************************************************************************/
{	//tested 29.04.2000 - OK

	
	EEADR = ADDR;		// write address
	EEDATA = DATAS;		// write data
	WREN = 1;
	
	GIE = 0;			// disable interrupts
//------------ required sequence
	EECON2 = 0x55;		// unlock protection
	EECON2 = 0xAA;
	
	WR = 1;				// enable WRITE
//------------ required sequence
	GIE = 1;			// enable INTERRUPTS
	WREN = 0;			// disable write	
}
	



/***********************************************************************************************/
void extractor(void)      // gets 4 bits of code from the initial byte
/***********************************************************************************************/
{
	// in position is kept the initial position of the mask 1 for reading
	// in danni is the value for extracting
	// in val is the result

	byte  i, parity;
	
	parity = 0;
	
	for (i=0; i<4; i++)			// loop for extracting 4 bits of code and get checksum
	 {

	 	val <<= 1;					// shift right data
		if (danni & position)
	 	 {
	 	 	column_parity[i]++;	// array of parity bits for columns
	 	 	parity++;				// count ones for parity check	
	 		val++;			// set bit
	 	 }
	 	
	 	position >>=1;				// shif right mask
	 }
	 
	 if (danni & position)
	  	parity++;

	 if (parity & 1)
	  flag_ERROR = 1;			// row parity error detected
	  	
}


_OSLabel(_TASK_Acceptor1)		// define labels
_OSLabel(_TASK_Acceptor1a)		// define labels
_OSLabel(_TASK_Acceptor2)		// define labels
_OSLabel(_TASK_Acceptor3)		// define labels
/***********************************************************************************************/
void TASK_Acceptor(void)      // controls CFE and gets the codes from ISR when ready
/***********************************************************************************************/
{
	static byte i;
	static byte CODE_DAT[5];	      // comparision of new to old values
	static byte flag_ROWS_PARITY;		// to calculate row and column parities

	while (TRUE)
	 {


		if (!flag_ERROR)	// when error found - start faster scanning to prevent malfunctions
		 {
			CFE = 0;				// disable carrier frequency (start accepting data) to save power
		 	OS_Delay(time_150ms, _TASK_Acceptor3);		// time between read codes
		 }
// -------- every 100ms activates the process for 10ms		

		CFE = 1;				// enable carrier frequency (start accepting data)

		OS_Delay(time_10ms,_TASK_Acceptor1a);	// brings some time to settle down the transponder
															// after 5ms it begans to generate good sequence	

   	i = PORTB;			// to clear data and to avoid setting of RBIF
		splitter = 0;		// to make sinchronization
  		RBIF = 0;
		RBIE = 1;			// enable RBIF again

//------------ within 20ms the transponder should catch the code, elsewise no card
		OS_Delay(time_80ms,_TASK_Acceptor1);	// within 50ms should get the code
		
		RBIE = 0;		// disable ISR

//		CFE = 0;				// disable CARRIER, stop watching for code
		if (flag_DETECTED)
		 {
		 	flag_PRESENSE = 8;					// when card is on the coil - keep 800ms active status
		 	flag_DETECTED = 0;


//----------------- GET THE HEARDER of teh transponder ------------------------------

			for (i=64; i!=0; i--)	// will try all 64 combination of data
			 {
				if (STAC[0] == 0xFF && ((STAC[7] & 0x3) == 0x1))		// this is the header 9 ones
				  break;
				 else
				 {					 
				 	 CARRY = (STAC[7] & 0x1)? 1:0;
				 	 STAC[0] = STAC[0];		// this will force the bank settings
				 	 asm("rrf _STAC+0,f");
				 	 asm("rrf _STAC+1,f");
				 	 asm("rrf _STAC+2,f");
				 	 asm("rrf _STAC+3,f");
				 	 asm("rrf _STAC+4,f");
				 	 asm("rrf _STAC+5,f");
				 	 asm("rrf _STAC+6,f");
				 	 asm("rrf _STAC+7,f");
				 }
			 }

	 	   OS_Yield(_TASK_Acceptor2);		// to avoid WDT and for smoot operations of other tasks

			if (i == 0)							// there was no header - wrong code
			 continue;

//------------ header found, now it's time to calculate checksums			
// and if possible to correct errors
			column_parity[0]=0;	// column parity bits initial reset
			column_parity[1]=0;	// because it takes the header data too - one 1 more
			column_parity[2]=0;
			column_parity[3]=0;
	
			flag_ERROR = 0;	// row parity control error flag (no separate control)

//------ start calculating for LOW part of byte 1
			danni = STAC[1]*256 + STAC[2];	// get data for first byte
			position = 0x8000;							
			val = 0;									// where to get data
			
			extractor();							// get bits
			position = 0x0400;					// locator of bits
			extractor();
			CODE_DAT[0] = val;

//------ start calculating for LOW part of byte 2

			danni = STAC[2]*256 + STAC[3];	// get data for first byte
			position = 0x2000;							
			val = 0;									// where to get data
			
			extractor();							// get bits
			position = 0x0100;					// locator of bits
			extractor();
			
			CODE_DAT[1] = val;

//------ start calculating for LOW part of byte 3

			danni = STAC[3]*256 + STAC[4];	// get data for first byte
			position = 0x0800;							
			val = 0;									// where to get data
			
			extractor();							// get bits
			position = 0x0040;					// locator of bits
			extractor();
			
			CODE_DAT[2] = val;

//------ start calculating for LOW part of byte 4

			danni = STAC[4]*256 + STAC[5];	// get data for first byte
			position = 0x0200;							
			val = 0;									// where to get data
			
			extractor();							// get bits
			
			position = 0x0010;					// locator of bits
			extractor();
			CODE_DAT[3] = val;

//------ start calculating for LOW part of byte 5

			danni = STAC[6]*256 + STAC[7];	// get data for first byte
			position = 0x8000;							
			val = 0;									// where to get data
			
			extractor();							// get bits
			position = 0x0400;					// locator of bits
			extractor();
			CODE_DAT[4] = val;
			
			
			flag_ROWS_PARITY = flag_ERROR;	// to calculate row and column parities
														// but record data into new variable
														// the last row don't have parity, so it could return wrong parity
			
			position = 0x0020;					// to calculate column parities
			extractor();

			flag_ERROR = flag_ROWS_PARITY;	// restores original value

//----------- ALL BITS extracted now should check if the parity is correct or not
			if (column_parity[0] & 1)
			 flag_ERROR = 1;

			if (column_parity[1] & 1)
			 flag_ERROR = 1;

			if (column_parity[2] & 1)
			 flag_ERROR = 1;

			if (column_parity[3] & 1)
			 flag_ERROR = 1;

//--------- the code should be received twice the same, before it's proceeded




			if (!flag_ERROR)
			 {
			  CODE_ARRAY[0] = CODE_DAT[0];	// moves data to compare aray, only if checksum is OK
			  CODE_ARRAY[1] = CODE_DAT[1];	// checksums are row and column
			  CODE_ARRAY[2] = CODE_DAT[2];	// so there is impossible to get
			  CODE_ARRAY[3] = CODE_DAT[3];	// wrong code
			  CODE_ARRAY[4] = CODE_DAT[4];
			  
			  OSSignalBinSem(BINSEM_Found);		// signals event to comparator task
			 }

		 }		// flag detected secuence
	 }			// endless loop
}


/***********************************************************************************************/
byte find_PLACE(void)      // gets the first cell that where FF only (empty)
/***********************************************************************************************/
{
	byte i,j,k;

	k = 0;
 	for (j=0; j<MAX_CODES; j++)		// scan all EEPROM for matches
 	 {
 	 	for (i=0; i<5; i++)
 	 	 {
 	 	 	if (read_EEPROM(i+k) != 0xFF)
 	 	 	  break;					// the card is not empty
 	 	 }
 	 	
 	 	if (i == 5)					// only when all codes matched were MATCHED event
 	 	 {								// there is no need to scan more the eeprom
 	 	 	break;
 	 	 }
 	 	 
 	 	k+=5;							// get next address 

 	 }
 	 
	
 	 return j;			// returns the address of fisrt empty block for records
}


/***********************************************************************************************/
byte compare_CODE(void)      // compares the current code with all etalons in EEPROM
/***********************************************************************************************/
{
	byte i,j,k;
	
	k=0;
 	for (j=0; j<MAX_CODES; j++)		// scan all EEPROM for matches
 	 {
 	 	
 	 	for (i=0; i<5; i++)
 	 	 {
 	 	 	if (CODE_ARRAY[i] != read_EEPROM(i+k))
 	 	 	  break;					// no match of the card, take next card code in EEPROM
 	 	 }
 	 	
 	 	if (i == 5)					// only when all codes matched were MATCHED event
 	 	 {								// there is no need to scan more the eeprom
 	 	 	break;
 	 	 }
 	 	 
 	 	k+= 5;						// next address
 	 	
 	 }

⌨️ 快捷键说明

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