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

📄 trans628.c

📁 使用PIC16F628和U2280构建的门禁控制机,有原理图
💻 C
📖 第 1 页 / 共 2 页
字号:
	 if (j == MAX_CODES)
	  	return 0;
	  else
	   return (j+1);		// returns the code that matches
								// if 0 - no match
								// if 1 - master code
								// if 2-25 - normal codes

}




_OSLabel(_TASK_Comparator1)		// define labels
_OSLabel(_TASK_Comparator1a)		// define labels
_OSLabel(_TASK_Comparator1b)		// define labels
_OSLabel(_TASK_Comparator2)		// define labels
_OSLabel(_TASK_Comparator2a)		// define labels
_OSLabel(_TASK_Comparator2b)		// define labels
_OSLabel(_TASK_Comparator2c)		// define labels
_OSLabel(_TASK_Comparator3)		// define labels
_OSLabel(_TASK_Comparator4)		// define labels
_OSLabel(_TASK_Comparator5)		// define labels
/***********************************************************************************************/
void TASK_Comparator(void)      // compares if the value fits data in EEPROM and takes decisions
/***********************************************************************************************/
{
	static byte match_CODE,i,j;
	static byte addr_target;			// used for speed up the address location
	static word counter_RESET_ALL;	 // this timer will erase whole EEPROM, except master
  	static byte prescal_1s;				// will produce 1s delay to make short beeps on buzzer


	flag_NO_MASTER_CARD = find_PLACE()? 0: 1;		// if the place is >0 master exists

	while (TRUE)						// main loop of the task
	 {
	 	OS_WaitBinSem(BINSEM_Found, OSNO_TIMEOUT, _TASK_Comparator1);
		
		match_CODE = compare_CODE();		// get the match code

//------ code is scanned - now time for actions
	 	 
	 	if (match_CODE)				// were match of code
	 	 {
	 	 	if (match_CODE > 1)		// it's a card, but not master
	 	 	 {
	 	 	 	if (counter_PROGRAM_MODE)	
				 {	 	 	 													// if still in program mode - delete cards
		 	 	 	counter_PROGRAM_MODE = AUTO_OFF_PROGRAM_MODE;	// prolongs time with additional delay
					
//============== remove cards in EEPROM memory      ======================
					addr_target = (match_CODE-1)*5;			// where is the target address
					
		 	 	 	for (i = 0; i<5; i++)
		 	 	 	 {
		 	 		 	while (WR)					// wait until EEPROM write finish
		 	 		 	 {
		 	 		 	 	OS_Yield(_TASK_Comparator1a);
		 	 		 	 }
	 	 		 	 
		 	 		 	 write_EEPROM(i+addr_target,0xFF);	//clears the location for that card
		 	 	 	 	
					 }

					counter_BUZZER = BEEP_100ms;	// when removing short beep
					OS_Delay(time_350ms,_TASK_Comparator1b);
					counter_BUZZER = BEEP_100ms;	// when removing short beep
					
					
					while (flag_PRESENSE)	// wait until card removed from receiver
					 {
			 	 	 	counter_PROGRAM_MODE = AUTO_OFF_PROGRAM_MODE;
	 	 		 	 	OS_Yield(_TASK_Comparator2);
					 }

					OSTryBinSem(BINSEM_Found); 	// clears events, if accumulated 
		

				 }
				 else
				 {
//***********************************************************************
//***********************************************************************
//***********************************************************************
//************* THIS IS THE NORMAL OPERATION - UNLOCK THE DOOR **********				 	
//***********************************************************************
//***********************************************************************
//***********************************************************************
					if (!counter_ACTIVE_OUT)		// only once
				 	 	counter_BUZZER = BEEP_1s;	// very long beep

					counter_AUTO_CLOSE = TIME_AUTO_CLOSE;	// to avoid locking, until card exists
					counter_ACTIVE_OUT = 50;	// 5s after card removed will keep door opened
					flag_OPEN = 1;			// opens the door (in other task is OUTPUT control)					 	

				 }	// was not program mode and card fits
	 	 	 }
	 	 	 else
	 	 	 {
// ======= it's master card - switch ON the program MODE (or if switched on - prolong it)
	
	 	 	 	counter_BUZZER = BEEP_500ms;		// makes sound middle length

				counter_RESET_ALL = TIME_RESET_ALL;		// this timer will erase whole EEPROM, except master
 	 	 	  	prescal_1s = 10;		// will produce 1s delay to make short beeps on buzzer

				while (flag_PRESENSE)			// WAITS UNTIL card is in the coild field
				 {
		 	 	 	counter_PROGRAM_MODE = AUTO_OFF_PROGRAM_MODE;
		 	 	 	OS_Delay(time_100ms, _TASK_Comparator2a);
		 	 	 	
		 	 	 	if (prescal_1s)
		 	 	 	  prescal_1s--;
		 	 	 	 else
		 	 	 	  {
		 	 	 	  	prescal_1s = 10;		// will produce 1s delay to make short beeps on buzzer

						if (counter_RESET_ALL < TIME_RESET_SOUNDS)
						  counter_BUZZER = BEEP_500ms;	// 10s before the end the sound is changed
						 else
		 	 	 	  		counter_BUZZER = BEEP_100ms;
		 	 	 	  }
		 	 	 	
					if (counter_RESET_ALL)
					 {
					 	if (counter_RESET_ALL == 1)	// to erase only once the content
					 	 {
					 	 	counter_BUZZER = BEEP_5s;	// very long beep
					 	 	
					 	 	for (i=5; i<128; i++)
					 	 	 {
					 	 	 	while (WR)
					 	 	 	 {
					 	 	 	 	OS_Yield(_TASK_Comparator2b);	// wait until EEPROM write is complete
					 	 	 	 }
					 	 	 	
								write_EEPROM(i,0xFF);	// erases the all memory locations except master						 	 	 	
					 	 	 }
					 	 }	// counter is equal to 1 - only in this case will do erasing 

				 	  counter_RESET_ALL--;	// decrement timer

					 }
					 else
					 {
					 	while (flag_PRESENSE)		// block counting
					 	 {
					 	 	 counter_PROGRAM_MODE = AUTO_OFF_PROGRAM_MODE;	// to avoid making sounds
						 	 OS_Yield(_TASK_Comparator2c);

					 	 }

 	 		 	 	 	 counter_PROGRAM_MODE = 5;			// force fast ending the mode after 0.5 s

					 }
		 	 	 	
				 }	// loop until card exist on the sensor
				// card is removed - have to clear the BINSEM, if exists
				 
				OSTryBinSem(BINSEM_Found); 	// clears events, if accumulated 
			
	 	 	 }
	 	 }
	 	 else		// nothing matches the code, but if this si the first power up - record master
	 	 {
	 	 	if (flag_NO_MASTER_CARD)		// seems that this is the first card, so
	 	 	 {		
	 	 	 										// it should be tooken like master card
				flag_NO_MASTER_CARD = 0; 	// now there is a master card
													// and should be recorded into EEPROM	
	 	 		for (i=0; i<5; i++)
	 	 		 {
	 	 		 	while (WR)					// wait until EEPROM write finish
	 	 		 	 {
	 	 		 	 	OS_Yield(_TASK_Comparator3);
	 	 		 	 }
	 	 		 	 
	 	 		 	 write_EEPROM(i,CODE_ARRAY[i]);	// writes the master code like first location
	 	 		 }
	 	 	 	
	 	 	 }	// there was master card
	 	 	 else
	 	 	 {
	 	 	 	if (counter_PROGRAM_MODE)			// in program mode - record CODE
				 {
				 	
					j = find_PLACE();				// get the first free location

					addr_target = j*5;			// where is the target address
					
					if (j < 25)						// still free locations
					 {
		 		 	 	for (i = 0; i<5; i++)
		 		 	 	 {
		 	 			 	while (WR)					// wait until EEPROM write finish
		 	 			 	 {
		 		 		 	 	OS_Yield(_TASK_Comparator4);
			 	 		 	 }
	 	 		 	 
			 	 		 	 write_EEPROM(i+addr_target,CODE_ARRAY[i]);	//saves the location for that card
						 }
						 
						counter_BUZZER = BEEP_1s;	// long beep

						while (flag_PRESENSE)		// wait until card removed from receiver
						 {
				 	 	 	counter_PROGRAM_MODE = AUTO_OFF_PROGRAM_MODE;
	 		 		 	 	OS_Yield(_TASK_Comparator5);
						 }

						OSTryBinSem(BINSEM_Found); 	// clears events, if accumulated 

					 } // were free locations, records data in EEPROM
				 	
				 }	  // was program mode - card added
	 	 	 	
	 	 	 }	// it was not the master card
	 	 	
	 	 }		// the code didn't match the tables

	 }			// main loop

}



_OSLabel(_TASK_Executer1)		// define labels
_OSLabel(_TASK_Executer2)		// define labels
/***********************************************************************************************/
void TASK_Executer(void)      // controls LED/BUZZER/OUTPUTS
/***********************************************************************************************/
{


	static bit flag_OPEN_old;
	
	while (TRUE)						// main loop of the task
	 {

		if (flag_PRESENSE)
		 flag_PRESENSE--;

		if (counter_BUZZER)
		 {	
// to make smooth action of buzzer - synchronization with variable
		 	
		 	count_BUZZER = counter_BUZZER;
		 	counter_BUZZER = 0;
		 }
	
	
		if (count_BUZZER)			// control of BUZZER trought counter_BUZZER
		  {

			BUZZER = 0;						// makes clear sound
		  	count_BUZZER--;

		  }					// sound OUT
		 else
	  		BUZZER = 1;						// set buzzer in 1 to prevent high currents
		  
		  
//--------- when change in status of flag_OPEN - issue motor control (OPEN/CLOSE door)
		if (flag_OPEN != flag_OPEN_old)						// general flag for OPEN/CLOSE system door
		 {
			if (flag_OPEN)			// door opened
			  {
				counter_ACTIVE_OPEN = TIME_OPEN_ON;			// how long to turns motor OPEN	
				counter_AUTO_CLOSE = TIME_AUTO_CLOSE;		// and immediately start process of count down to close it
			  }
			 else
			   counter_ACTIVE_CLOSE = TIME_CLOSE_ON;		// how long to turns motor CLOSE
		 	
		 }	// was change in the status of flag_OPEN

		flag_OPEN_old = flag_OPEN;




//------- AUTO close the door after some time
		if (flag_OPEN)
		 	{
		 		if (!DOOR)					// only when door is close can start counting
		 		 {
			 		if (counter_AUTO_CLOSE)
			 		  	counter_AUTO_CLOSE--;
			 		 else
		 			  flag_OPEN = 0;			//	after time expired - door closes automatically

		 		 }	// door was closed, elsewise nothing counts until somebody close the door
				else
			 	 counter_AUTO_CLOSE = TIME_AUTO_CLOSE;		// if open - wates some time before auto close
				
		 	}	// flag_OPEN DOOR


//------- OUTPUT 0 control
	  	if (counter_ACTIVE_OUT)
	  	 {
	  	 	counter_ACTIVE_OUT--;
	  	 	OUT0 = 1;
	  	 }
	  	 else
	  	  OUT0 = 0;


//------- OUTPUT 1 control
		if (counter_ACTIVE_OPEN)		// time for open the door motors
		 {
		 	counter_ACTIVE_OPEN--;
			OUT1 = 1;
		 }
		 else
		 	OUT1 = 0;
		 	
//------- OUTPUT 2 control
		if (counter_ACTIVE_CLOSE)		// time for close the door motors
		 {
		 	 if (DOOR)									// if accidentally somebody opens the door
		 	  {
		 	  	 OUT2 = 0;								// stops the execution of opening
		 	  	 counter_ACTIVE_CLOSE = 0;			// immediately stops the process of closing
		 	  	 flag_OPEN = 1;						// start opening the door again (system is closed
		 	  	 											// and will issue again autolock algorythm
		 	  }
		 	  else
		 	  {
			 	 counter_ACTIVE_CLOSE--;
			 	 OUT2 = 1;
		 	  }
		 }
		 else
		 	OUT2 =0;
		 	
//------- Auto OFF program mode counter support
		if (counter_PROGRAM_MODE)
		  {
		 	counter_PROGRAM_MODE--;

			if (counter_PROGRAM_MODE == 1)
			  	counter_BUZZER = BEEP_100ms;
		  }


		OS_Delay(time_100ms, _TASK_Executer1);		// time to wake up

	 }
}



/***********************************************************************************************/
#include <reader.c>					// hardware capture of codes
/***********************************************************************************************/




/***********************************************************************************************/
void main(void)
/***********************************************************************************************/
{
// ----------- TMR0 control  -----------------------------

	OPTION = 0b00000101;	//Pull UPS,prescaller 1:64 every 10 ms synchronize (with compensation - 99)


	TMR0 = adjust_10ms;			// initial timer dalay of 10ms
	T0IF = 0;						// reset timer to bring intial TMR0 delay
	
	INTCON = 0b01000000;			// GIE disable   T0IE disable


//=========== PWM control for buzzer ===============
	
	T1CON =  0b00000000;
	


// ----------- USART control  -----------------------------
   
//	SPBRG = 25 ;					// SET SPEED TO 9600 bps /4 MHz clock generator
//	TXSTA = 0b10100100;			// set data for USART enable transmitter, but no interrupts/no receive
//	RCSTA = 0b10000000;			// SPEN=1 data for USART setting,ADEN = 0,CREN = 0!!!!


	PIE1 = 0b00000000;			// no interrupts from periferal


// ------ tristate control ---------------------------------------

	CMCON = 0x07;				// enable ports for digital
	TRISA = 0b00000000;		// PORTA TRIS control  

	TRISB = 0b00010111;		// PORTB TRIS control


// ---------- definitions of the registers -----------------------

	PORTA = 0b00001000;		// no sound and LIGHT
	
	PORTB = 0b00000000;		

//=========== initialization of flags
	counter_BUZZER = 10;		// 1s initial beep
	flag_OPEN = 0;
 	flag_DETECTED = 0;


//----------- OSInit should stay before any other SALVO commands !!!!
   OSInit();						// initialize RTOS kernel
//----------- OSInit should stay before any other SALVO commands !!!!

// creates semaphores with their values
	
	 OSCreateBinSem(BINSEM_Found,	0);			// create message for displaying
	 
// creates the tasks that will be used in the program
    
    OSCreateTask( TASK_Acceptor,		OSTCBP(1),		5);
    OSCreateTask( TASK_Comparator,	OSTCBP(2),		5);
    OSCreateTask( TASK_Executer,		OSTCBP(3),		5);	
  

    OSEi(); 		// enable global interrupts


	//--------------- MAIN LOOP -------------------------------

	for (;;)						// non stopping loop of the main program
    {

	if (T0IF)					// no Interrupt timer routine
		{
			TMR0 += adjust_10ms;	// adjusts the value of timer	
			T0IF = 0;				// clear the flag
			OSTimer();
		}


		OSSched();					// run the RTOS kernel

    }
		

 

}

⌨️ 快捷键说明

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