/********************************************************************** * ISO 7816 Synchronous Memory Card Emulator * * Programmed by SNG. All rights reserved. * * (c) SNG - (99,2000) sng@newmail.ru * * Partially (c) Stephane BAUSSON - (93,94,95) * **********************************************************************/ #include <pic.h> /* * Pin assignment * * Port A * RA4 - I/O * * Port B * RB6 - CLK * RB7 - RST */ __CONFIG(UNPROTECT | FOSC0 | FOSC1 | PWRTE); // Fuses // Card data. Write to EEPROM. #asm psect eedata,delta=2,abs,ovrld org 2100h db 0xe8,0x30,0xcf,0x0f,0x05,0x0a,0x31,0xc4 db 0x00,0x00,0x00,0x00,0x0f db 0xff,0x12,0x04 #endasm #define DATABIT(adr, bit) ((unsigned)(&adr)*8+(bit)) #define INTBITS 0x88 static bit out @ DATABIT(PORTA, 4); static bit clk @ DATABIT(PORTB, 6); // Clock input static bit rst @ DATABIT(PORTB, 7); // Reset input static unsigned char cbit = 0, cbyte = 0, status = 0, data, temp; /* status: * 0 - read * 1 - write * 2 - write complete * 3 - carry */ void incbit(void) // next address and prepared current bit { status = 0; if (cbit < 7) { cbit++; #asm bcf _STATUS,0 rlf _data,f btfsc _STATUS,0 incf _data,f #endasm } else { if (cbyte < 63) cbyte++; else cbyte = 0; cbit = 0; if (cbyte < 16) { data = EEPROM_READ(cbyte); #asm swapf _data,f bcf _STATUS,0 rlf _data,f btfsc _STATUS,0 incf _data,f #endasm } else data = 0xff; } return; } void setbit(void) // write current bit { status = 2; if (cbyte < 8) return; if (cbyte > 12) return; data = EEPROM_READ(cbyte); temp = 0x80; temp >>= cbit; temp ^= 0xff; data &= temp; EEPROM_WRITE(cbyte, data); return; } void carry(void) // carry after write { status = 0; if (cbyte < 8) return; if (cbyte > 11) return; EEPROM_WRITE(cbyte+1, 0xff); return; } interrupt void event(void) // interrupt { if (!rst) // RST - low { PORTA = data; // output current data if (clk) // CLK - high (Next address or write bit or carry after write) { switch (status) { case 1: setbit(); break; case 3: carry(); break; default: incbit(); } } } else // RST - high { if (clk) // CLK - high (Reset card) { cbit = 0; cbyte = 0; status = 0; data = EEPROM_READ(0); #asm swapf _data,f bcf _STATUS,0 rlf _data,f btfsc _STATUS,0 incf _data,f #endasm } else // CLK - low (Write or carry mode) { if (cbyte != 0) { if (status == 2) status = 3; else status = 1; } } PORTA = 0x00; } RBIF = 0; // Clear PORTB interrupt flag return; } void main(void) { CLRWDT(); PORTB = 0x00; INTCON = INTBITS; TRISA = 0x00; // PORT A - set to output TRISB = 0xc0; // RB6, RB7 - set to input data = EEPROM_READ(0); #asm swapf _data,f bcf _STATUS,0 rlf _data,f btfsc _STATUS,0 incf _data,f movf _data,w movwf _PORTA #endasm while (1); }

Комментарии (0) | Подписаться

Статью еще никто не комментировал. Вы можете стать первым.
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется напряжение?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

вверх