Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

Вот, если не лень разбираться... Формат карточки сведен в таблицу... Подчсет контрольных сумм и укладывание битов производится на проходе бит-детектора... SPI - к делу не относится(ридер двухпроцессорный)... Давно дело было, вопросы нежелателтьны...

Отправлено ETM 22 октября 2008 г. 17:48
В ответ на: Не - мне надо для простеньких карточек на 125кГц Em Marine (ангстремовские КИБИ-001). отправлено Гудвин 22 октября 2008 г. 15:45

#include "io8515.h"
#include "ina90.h"

#define ID_SLAVE 0xFE

#define byte unsigned char
#define word unsigned int
#define longint unsigned long

#define TC1_RELOADBYCOMPARE 0x08

#define TC_PRESCALER_0 0x00
#define TC_PRESCALER_1 0x01
#define TC_PRESCALER_8 0x02
#define TC_PRESCALER_64 0x03
#define TC_PRESCALER_256 0x04
#define TC_PRESCALER_1024 0x05

#define BITSIZE 8
#define MAJOR 3
#define LINE_Rx 2

// defOCR1A_TC1=7372800./1./(1953.*2)/8.-1 = 235 = 0x00EB
#define defOCR1AH 0x00
#define defOCR1AL 0xEB

// 10 mSek
// defTCNT0=0xff-7372800./1024./100.+3 = 186
#define defTCNT0 186
#define NO_KARTA_TIME 100
#define SAVE_KARTA_TIME 250

#define TC0_Stop(); TCCR0 = TC_PRESCALER_0;
#define TC0_Start(); {TCNT0=defTCNT0;TCCR0 = TC_PRESCALER_1024;}

#define TC1_Stop(); TCCR1B = TC_PRESCALER_0+TC1_RELOADBYCOMPARE;
#define TC1_Start(); TCCR1B = TC_PRESCALER_1+TC1_RELOADBYCOMPARE;

#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<(BIT)))
#define CLRBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<(BIT)))
#define TSTBIT(ADDRESS,BIT) (ADDRESS & (1<<(BIT)))

#define GET_RX(INDEX) TSTBIT(PIND,INDEX)
#define GET_FRONT_RX(line); ch->frontRx=GET_RX(line);

#define FIND_NEXT_MARKER();\
{\
ch->cntbitRx=0;\
SETBIT(ch->flag,FLAG_Rx_MARKER_ON);\
CLRBIT(ch->flag,FLAG_ERROR_KS);\
for(it=0;it<14;it++) gv.ks[it]=0;\
}

#define SOUND_OFF(); {\
CLRBIT(DDRC,4);CLRBIT(PORTC,4); \
}
#define SOUND_ON(); {\
SETBIT(DDRC,4);SETBIT(PORTC,4); \
}

#define TST_Rs232_ENABLE() (!(TSTBIT(PINB,0)))

//#define TST_FLAG_HM_TIMEOUT() !(TSTBIT(PINB,0))
#define TST_FLAG_HM_TIMEOUT() (1)

#define SET_IRQ(VECT); {\
SPDR=VECT; CLRBIT(PORTC,0); _NOP(); SETBIT(PORTC,0);\
}

#define FLAG_Rx_MARKER_ON 0
#define FLAG_KARTA_ON 1
#define FLAG_PUT_DATA_BUF_Rx 2
#define FLAG_ERROR_KS 3

#define FLAG_HM_BUSY 0
#define FLAG_HM_TIMEOUT 1
#define FLAG_SOUND_DELAY 2
#define FLAG_HM_START 3
#define FLAG_HM_KARTA 4

#define BUFSIZERX 7
#define SIZEBITRXBUF 54
#define SIZEMARKERRX (10<<1)
#define MARKERRX 0x03fe
#define BUFSIZEHM 14


#define INVERSIA 0
#if INVERSIA
#define OPERATE_BY_INVERSIA_MODE(marker_val) ~marker_val
#define LEVEL_1 0
#define LEVEL_0 1
#endif
#if !INVERSIA
#define OPERATE_BY_INVERSIA_MODE(marker_val) marker_val
#define LEVEL_1 1
#define LEVEL_0 0
#endif

#define GET_ID_SPI 0x01
#define GET_IRQ_SPI 0x02
#define START_BYTE_SPI 0x05
#define STOP_BYTE_SPI 0xFE

#define GET_CONFIG_VECTOR 0x01
#define PUT_CONFIG_VECTOR 0x02
#define PUT_KARTA_VECTOR 0x03

typedef union {
byte b[4];
longint l;
} lbTyp;

typedef union {
byte b[2];
word w;
} wbTyp;

typedef struct {

byte flag;
byte statusRx;

byte frontRx;
byte cfrontRx;
byte tikRx;

byte dRx;
byte cntbitRx;
byte cntbit2Rx;
byte dRxBuf[BUFSIZERX];
lbTyp markerRx;

} ChanelTyp;

#define SIZEDATAPAK 6
typedef struct {
byte status;
byte len;
byte code;
byte data[SIZEDATAPAK];
wbTyp ks;
} PacketTyp;

#define SIZEDATASPI 6
typedef struct {
byte status;
byte code;
byte len;
byte data[SIZEDATASPI];
byte out[SIZEDATASPI];
} SPITyp;

typedef struct {
byte flagLines;
byte statusHM;
byte flagHM;
byte szHM;
byte szHMdef;
ChanelTyp chanel;
ChanelTyp tiny *prtChanel;
byte ks[14];
byte timeout1;
byte timeout2;
byte tikTC0;
byte id;
byte speed;
lbTyp SN;
byte dHMBuf[BUFSIZEHM];
byte karta[5];
} GlobalVar_typ;

// Defines formats of "ANGSTREAM" karta
flash byte idxByteBitHLP[SIZEBITRXBUF]={
0x07,0x06,0x05,0x04, 0x50,
0x03,0x02,0x01,0x00, 0x51,
0x17,0x16,0x15,0x14, 0x52,
0x13,0x12,0x11,0x10, 0x53,
0x27,0x26,0x25,0x24, 0x54,
0x23,0x22,0x21,0x20, 0x55,
0x37,0x36,0x35,0x34, 0x56,
0x33,0x32,0x31,0x30, 0x57,
0x47,0x46,0x45,0x44, 0x60,
0x43,0x42,0x41,0x40, 0x61,

0x62,0x63,0x64,0x65
};

flash byte idxByteKS[SIZEBITRXBUF]={
0x0a,0x0b,0x0c,0x0d, 0x0f,
0x1a,0x1b,0x1c,0x1d, 0x1f,
0x2a,0x2b,0x2c,0x2d, 0x2f,
0x3a,0x3b,0x3c,0x3d, 0x3f,
0x4a,0x4b,0x4c,0x4d, 0x4f,
0x5a,0x5b,0x5c,0x5d, 0x5f,
0x6a,0x6b,0x6c,0x6d, 0x6f,
0x7a,0x7b,0x7c,0x7d, 0x7f,
0x8a,0x8b,0x8c,0x8d, 0x8f,
0x9a,0x9b,0x9c,0x9d, 0x9f,

0xaf,0xbf,0xcf,0xdf
};

// Const to Manchester Code Detectors Handle
flash unsigned long maskap[32]={
0x00000001,0x00000002,0x00000004,0x00000008,
0x00000010,0x00000020,0x00000040,0x00000080,
0x00000100,0x00000200,0x00000400,0x00000800,
0x00001000,0x00002000,0x00004000,0x00008000,
0x00010000,0x00020000,0x00040000,0x00080000,
0x00100000,0x00200000,0x00400000,0x00800000,
0x01000000,0x02000000,0x04000000,0x08000000,
0x10000000,0x20000000,0x40000000,0x80000000
};


GlobalVar_typ tiny gv;
PacketTyp tiny pak;
SPITyp tiny spi;

//***********************************************************
void PrepareRxLine(ChanelTyp tiny *ch)
{
ch->cfrontRx=0;
ch->cntbitRx=0;
ch->dRx=0;
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DeCompress(word x,longint *y)
{
byte it;
*y=0;
for(it=0;it<16;it++) {
if((x & 0x01)!=0) *y|=0x40000000;
else *y|=0x80000000;
x>>=1;
if(it<15) *y>>=2;
}
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Manchester Code Detector
interrupt [TIMER1_COMPA_vect] void INT_TIMER1()
{
ChanelTyp tiny *ch;
byte detectedBit;
byte valueBit;
byte markerBit;
byte nbyte;
byte nbit;
byte idx1_ks;
byte idx2_ks;
byte it;
ch=gv.prtChanel;
GET_FRONT_RX(LINE_Rx);
ch->tikRx--;
if(ch->frontRx!=ch->cfrontRx) {
detectedBit=ch->cfrontRx;
ch->cfrontRx=ch->frontRx;
if(ch->tikRx<=MAJOR)
goto BIT_DETECTED_RX;
else
ch->tikRx=BITSIZE;
}
else {
if(ch->tikRx==0) {
detectedBit=ch->cfrontRx;
goto BIT_DETECTED_RX;
}
}
goto FINIS;
BIT_DETECTED_RX:
ch->tikRx=BITSIZE;
if(!TSTBIT(ch->flag,FLAG_Rx_MARKER_ON)){
if(detectedBit) ch->dRx|=0x04;
ch->dRx>>=1;
ch->cntbit2Rx--;
if(ch->cntbit2Rx==0) {
ch->cntbit2Rx=2;
if((ch->dRx & 0x03)==0x01)
valueBit=LEVEL_1;
else
if((ch->dRx & 0x03)==0x02) {
valueBit=LEVEL_0;
}
else {
FIND_NEXT_MARKER();
if(TSTBIT(ch->flag,FLAG_KARTA_ON)){
TC1_Stop();
gv.timeout1=0;
}
goto FINIS;
}
ch->dRx=0;
nbyte = idxByteBitHLP[ch->cntbitRx]>>4;
nbit = idxByteBitHLP[ch->cntbitRx] & 0x0f;
if(valueBit) {
SETBIT(ch->dRxBuf[nbyte],nbit);
} else {
CLRBIT(ch->dRxBuf[nbyte],nbit);
}
idx1_ks = idxByteKS[ch->cntbitRx]>>4;
idx2_ks = idxByteKS[ch->cntbitRx] & 0x0f;
if(idx2_ks==0x0f){
if(valueBit!=gv.ks[idx1_ks]){
SETBIT(ch->flag,FLAG_ERROR_KS);
}
} else {
gv.ks[idx1_ks]^=valueBit;
gv.ks[idx2_ks]^=valueBit;
}
ch->cntbitRx++;
if(ch->cntbitRx==SIZEBITRXBUF) {
ch->cntbitRx=0;
ch->dRx=0;
if(TST_FLAG_HM_TIMEOUT()){
if(!TSTBIT(ch->flag,FLAG_ERROR_KS))
if(!TSTBIT(ch->flag,FLAG_KARTA_ON)){
gv.karta[4]=ch->dRxBuf[0];
gv.karta[3]=ch->dRxBuf[1];
gv.karta[2]=ch->dRxBuf[2];
gv.karta[1]=ch->dRxBuf[3];
gv.karta[0]=ch->dRxBuf[4];
SOUND_ON();
SETBIT(ch->flag,FLAG_PUT_DATA_BUF_Rx);
SETBIT(ch->flag,FLAG_KARTA_ON);
}
} else {
if(!TSTBIT(ch->flag,FLAG_ERROR_KS)){
SETBIT(ch->flag,FLAG_PUT_DATA_BUF_Rx);
}
FIND_NEXT_MARKER();
}
}
}
}
else {
if(detectedBit) detectedBit=1;
if(ch->markerRx.l & maskap[ch->cntbitRx])
markerBit=1;
else
markerBit=0;
if(detectedBit==markerBit) {
ch->cntbitRx++;
if(ch->cntbitRx==SIZEMARKERRX) {
ch->cntbitRx=0;
ch->cntbit2Rx=2;
ch->dRx=0;
CLRBIT(ch->flag,FLAG_Rx_MARKER_ON);
}
}
else {
if(detectedBit==(0x01 & ch->markerRx.b[0]))
ch->cntbitRx=1;
else
ch->cntbitRx=0;
}
}
FINIS:;
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Servise of timeout save KARTA
interrupt [TIMER0_OVF0_vect] void INT_TIMER0()
{
ChanelTyp tiny *ch;
TCNT0=defTCNT0;
gv.tikTC0++;
if(gv.timeout1<NO_KARTA_TIME) {
gv.timeout1++;
if(gv.timeout1>=NO_KARTA_TIME) {
ch=gv.prtChanel;
CLRBIT(ch->flag,FLAG_KARTA_ON);
TC1_Start();
}
}
if(gv.timeout2<SAVE_KARTA_TIME) {
gv.timeout2++;
if(gv.timeout2>=SAVE_KARTA_TIME) {
CLRBIT(gv.flagHM,FLAG_HM_KARTA);
}
}
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Rs232 transmitter Handle
interrupt [UART_TX_vect] void Uart_TX_complete_Interrupt()
{
if(gv.statusHM!=0){
if(gv.szHM==0) gv.szHM=gv.szHMdef;
gv.szHM--;
UDR=gv.dHMBuf[gv.szHM];
if(gv.szHM==0) {
gv.statusHM=0;
}
return;
}
CLRBIT(gv.flagHM,FLAG_HM_BUSY);
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Rs232 receiver Handle
interrupt [UART_RX_vect] void Uart_RX_complete_Interrupt()
{
byte in;
in=UDR;
if(!TST_Rs232_ENABLE()) return;
switch (pak.status) {
case 0:
if(in==0x05) {
pak.ks.w=0;
pak.status=1;
}
break;
case 1:
if(in==ID_SLAVE) {
pak.ks.w+=ID_SLAVE;
pak.status=2;
}
else pak.status=0;
break;
case 2:
if((in>0) && (in<=SIZEDATAPAK)) {
pak.len=in;
pak.ks.w+=in;
pak.status=3;
}
else pak.status=0;
break;
case 3:
if((in>=0xF0)) {
pak.code=in;
pak.ks.w+=in;
pak.status=4;
}
else pak.status=0;
break;
case 4:
pak.len--;
pak.data[pak.len]=in;
pak.ks.w+=in;
if(pak.len==0){
pak.status=5;
}
break;
case 5:
if((in==pak.ks.b[1])) {
pak.status=6;
}
else pak.status=0;
break;
case 6:
if((in==pak.ks.b[0])) {
pak.status=7;
}
else pak.status=0;
break;
case 7:
if(in==0xFE) {
switch (pak.code) {
case 0xF0:
SET_IRQ(GET_CONFIG_VECTOR);
break;
case 0xF1:
spi.out[4]=pak.data[4];
spi.out[3]=pak.data[3];
spi.out[2]=pak.data[2];
spi.out[1]=pak.data[1];
spi.out[0]=pak.data[0];
SET_IRQ(PUT_CONFIG_VECTOR);
break;
case 0xF2:
if(TSTBIT(gv.flagHM,FLAG_HM_BUSY)) break;
if(!TSTBIT(gv.flagHM,FLAG_HM_KARTA)) break;
gv.statusHM=1;
SETBIT(gv.flagHM,FLAG_HM_BUSY);
gv.timeout2=255;
CLRBIT(gv.flagHM,FLAG_HM_KARTA);
gv.szHM=0;
gv.szHMdef=5;
gv.dHMBuf[4]=gv.karta[4];
gv.dHMBuf[3]=gv.karta[3];
gv.dHMBuf[2]=gv.karta[2];
gv.dHMBuf[1]=gv.karta[1];
gv.dHMBuf[0]=gv.karta[0];
UDR=0x02;
break;
}
}
pak.status=0;
break;
}
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// SPI handle
interrupt [SPI_STC_vect ] void SPI_RX_complete_Interrupt()
{
byte in;
byte cnt;
in=SPDR;
if(spi.status==3) {
cnt=spi.len;
cnt--;
SPDR=spi.out[cnt];
spi.data[cnt]=in;
if(cnt==0){
spi.status=4;
}
spi.len=cnt;
return;
}
switch (spi.status) {
case 0:
if(in==START_BYTE_SPI) {
spi.status=1;
break;
}
if(in==GET_ID_SPI) {
SETBIT(gv.flagHM,FLAG_HM_START);
}
break;
case 1:
spi.len=in;
spi.status=2;
break;
case 2:
spi.code=in;
spi.status=3;
break;
case 4:
if(spi.code==0xF0) {
if(TSTBIT(gv.flagHM,FLAG_HM_BUSY)) break;
gv.statusHM=1;
SETBIT(gv.flagHM,FLAG_HM_BUSY);
gv.szHM=0;
gv.szHMdef=6;
gv.dHMBuf[5]=spi.data[5];
gv.dHMBuf[4]=spi.data[4];
gv.dHMBuf[3]=spi.data[3];
gv.dHMBuf[2]=spi.data[2];
gv.dHMBuf[1]=spi.data[1];
gv.dHMBuf[0]=spi.data[0];
UDR=0x01;
}
//...................................................
spi.status=0;
break;
}
}

// Main function ********************************************
void C_task main()
{
ChanelTyp tiny *ch;
wbTyp mark;
byte it;
word cntDelay;

// Prepare Sofrwear......................................
gv.flagLines=0;
gv.statusHM=0;
gv.flagHM=0;
gv.id=0;
gv.speed=0;
gv.SN.l=0;

// Prepare Hardwear......................................
_CLI();
TC0_Stop();
TC1_Stop();

TIMSK = 0x42;
OCR1AH = defOCR1AH;
OCR1AL = defOCR1AL;

DDRA = 0x00; // All pins : in

DDRB = 0x40; // 0: SW8 = 0: in
// 1: = 0: in
// 2: = 0: in
// 3: = 0: in
// PORTB.4,5,6,7 - pins SPI
// (setup by bit MSTR of SPCR)
//.........................................
// 4: SPI(slave) SS = 0: in
// 5: SPI(slave) MOSI = 0: in
// 6: SPI(slave) MISO = 1: out
// 7: SPI(slave) SCK = 0: in
PORTB=0x00;

DDRC = 0xc1; // 0: Query to SPI = 1: out
// 1: = 0: in
// 2: = 0: in
// 3: = 0: in
// 4: SPEEK = 0: in (1:ON)
// 5: = 0: in
// 6: CPE = 1: out
// 7: MS = 1: out
PORTC=0xc1;

DDRD = 0x02; // 0: RxD UART = 0:in
// 1: TxD UART = 1:out
// 2: Rx code = 0:in (manchester)
// 3: Rx1 code = 0:in (shtrich code)
// 4: = 0:in
// 5: = 0:in
// 6: = 0:in
// 7: = 0:default

// UART config
UCR = 0x58;
UBRR = 47; // 9600 with 7.3728 Mhz crystal

_SEI();


// Prepare Manchester Code Detectors...............
for(it=0;it<14;it++) gv.ks[it]=0;
ch=(ChanelTyp tiny *)&gv.chanel;
gv.prtChanel=ch;
ch->flag=0;
ch->statusRx=0x10;

mark.w=OPERATE_BY_INVERSIA_MODE(MARKERRX);
DeCompress(mark.w,(longint *)&ch->markerRx);
gv.timeout1=250;
gv.timeout2=255;


// Wait commutation noise finis.......................
gv.tikTC0=0;
TC0_Start();
while(gv.tikTC0<100) {;}

// Start SPI.........................................
_CLI();
// SPI config
SPCR=0xC0; // 0: MASTER mode Clock Rate = 0 (not used)
// 1: MASTER mode Clock Rate = 0 (not used)
// 2: CPHA (Clock Phase) = 0 (manual)
// 3: CPOL (Clock Polarity) = 0 (LOW )
// 4: MSTR (Master/Slave mode) = 0 (SLAVE)
// 5: DORD (Data Order) = 0 (MSB )
// 6: SPE (SPI ENABLED) = 1 (ENABLED)
// 7: SPIE (SPI INTERRUPT EN.) = 1 (ENABLED)
spi.status=0;
SPDR=ID_SLAVE;
_SEI();

// Wait selftest correct flag
//while (!TSTBIT(gv.flagHM,FLAG_HM_START)) {;}

pak.status=0;
// UART config..................................
UCR = 0xd8;
UBRR = 47; // 9600 with 7.3728 Mhz crystal

// Timers ON
TC1_Start();

// Handle reader karta.........................
for(;;){
if(TST_FLAG_HM_TIMEOUT()) {
if(TSTBIT(gv.flagHM,FLAG_SOUND_DELAY)){
spi.out[4]=gv.karta[4];
spi.out[3]=gv.karta[3];
spi.out[2]=gv.karta[2];
spi.out[1]=gv.karta[1];
spi.out[0]=gv.karta[0];
SET_IRQ(PUT_KARTA_VECTOR);
for(cntDelay=0;cntDelay<50000;cntDelay++);
CLRBIT(gv.flagHM,FLAG_SOUND_DELAY);
SOUND_OFF();
for(cntDelay=0;cntDelay<1000;cntDelay++);
SOUND_ON();
for(cntDelay=0;cntDelay<3000;cntDelay++);
SOUND_OFF();
}
}
if(!TSTBIT(ch->flag,FLAG_PUT_DATA_BUF_Rx)) continue;
SETBIT(gv.flagHM,FLAG_HM_KARTA);
gv.timeout2=0;
CLRBIT(ch->flag,FLAG_PUT_DATA_BUF_Rx);
if(TST_FLAG_HM_TIMEOUT()) {
SETBIT(gv.flagHM,FLAG_SOUND_DELAY);
}
}
}
//***********************************************************



Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
введите число 34:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru