#define __12f675 #include "pic12f675.h" static unsigned int __at 0x2007 __CONFIG = _CP_OFF & _CPD_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF; #define GPIO_OUT GPIO2 #define GPIO_CAL GPIO4 #define GPIO_FRQ (1<<5) // GPIO5 #define clrwdt() _asm CLRWDT _endasm #define gotoAddr(Addr) do { \ _asm PAGESEL Addr _endasm; \ _asm GOTO Addr _endasm; \ } while (0) #define nextStep(_pass, _high, _new) do { \ clrwdt(); \ if ((pass == _pass) && (TMR1H == _high)) GPIO_OUT = _new; \ } while (0) #define lastStep(_pass, _high, _new, _lpass, _lhigh) do { \ clrwdt(); \ if ((pass == _pass) && (TMR1H == _high)) { \ GPIO_OUT = _new; \ pass = _lpass; \ TMR1H = _lhigh; \ TMR1L = 0; \ T1IF = 0; \ if (calMode & 128) calMode++; \ } \ } while (0) #ifdef WITH_OSCCAL /* * Simple SDCC workaround that puts the RETLW instruction on 0x3FF. It * results in an 0x34FF. The correct calibration value is replaced by * the pic programmer. Since this area is reserved GPLINK will * complain about code outside of address range. */ const unsigned char __code __at 0x3FF _OSCVAL = 0xFF; #endif unsigned char getCalib() { EEADR = 0x00; // 0000 0000 RD = 1; if (EEDATA == 0xFF) gotoAddr(0x3FF); /* Does not return */ return EEDATA; } void saveCalib() { do clrwdt(); while (WR); WREN = 1; EEADR = 0x00; // 0000 0000 EEDATA = OSCCAL; EECON2 = 0x55; // 0101 0101 EECON2 = 0xAA; // 1010 1010 WR = 1; } static unsigned char pass; static unsigned char calMode; void main() { /* Bank 2 */ clrwdt(); ANSEL = 0x00; // 0000 0000 TRISIO = 0x1B; // 0001 1011 WPU = 0x10; // 0001 0000 OPTION_REG = 0x07; // 0000 0111 előosztó 1:256 /* Bank 1 */ clrwdt(); GPIO = 0x00; // 0000 0000 CMCON = 0x07; // 0000 0111 ADCON0 = 0x00; // 0000 0000 /* Prepare calibration */ clrwdt(); if (!GPIO_CAL) { OSCCAL = 0; calMode = 128; } else { OSCCAL = getCalib(); calMode = 0; } /* Init timer */ clrwdt(); TMR1L = 0; TMR1H = 0; T1CON = 0x31; // 0011 0001 1:8 előosztó be T1IF = 0; pass = 0; /* Main loop */ while (1) { if (calMode & 128) { if (GPIO_CAL) { calMode = 0; saveCalib(); } if (calMode & 4) { calMode = 128; OSCCAL += 8; } } while (TMR1L) clrwdt(); if (T0IF) { T0IF = 0; GPIO ^= GPIO_FRQ; // GPIO5 vált 1*256*256=65536 us-ként 7,63 Hz-es frekvencia } if (T1IF) { T1IF = 0; pass++; //pass=pass+1 1*8*65635=525080 us=525,08ms omkémt } /* Sequence */ nextStep(0, 98, 0); // 1 // 0*525,08ms+98*8*256us=200,704ms időnél GPIO2 0 nextStep(1, 218, 1); // 2 // 1*525,08ms+218*8*256us=971,544ms időnél GPIO2 1 nextStep(2, 16, 0); // 3 // 2*525,08ms+16*8*256us=1082,928ms időnél GPIO2 0 nextStep(2, 43, 1); // 4 // 2*525,08ms+43*8*256us=1138,224ms időnél GPIO2 1 nextStep(2, 69, 0); // 5 // 2*525,08ms+69*8*256us=1191,472ms időnél GPIO2 0 nextStep(2, 96, 1); // 6 // 2*525,08ms+96*8*256us=1246,768ms időnél GPIO2 1 nextStep(2, 231, 0); // 7 // 2*525,08ms+231*8*256us=1523,248ms időnél GPIO2 0 nextStep(4, 93, 1); // 8 // 4*525,08ms+93*8*256us=2290,784ms időnél GPIO2 1 /* Loop */ lastStep(5, 105, 0, 0, 98); // 9 // 5*525,08ms+105*8*256us=2840,44ms időnél GPIO2 0 és az 1-es feltételt beállítja, tehát ahogy újrakezi a ciklust a 2.ra lép } }