?? trans628.c
字號:
/*
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 + -