; CC8E Version 1.3, Copyright (c) B Knudsen Data ; C compiler for the PIC18 microcontrollers ; ************ 24. Jun 2009 9:08 ************* processor PIC18C242 radix DEC PRODH EQU 0xFF4 PRODL EQU 0xFF3 POSTINC0 EQU 0xFEE FSR0H EQU 0xFEA FSR0 EQU 0xFE9 WREG EQU 0xFE8 BSR EQU 0xFE0 STATUS EQU 0xFD8 Carry EQU 0 GIEL EQU 6 GIEH EQU 7 b0 EQU 0x81 a1 EQU 0x100 b1 EQU 0x101 a EQU 0x1F bx EQU 0x20 bt1 EQU 0 bt EQU 1 svrSTATUS EQU 0x00 svrBSR EQU 0x01 svrWREG EQU 0x02 a_2 EQU 0x0E bx_2 EQU 0x0F c EQU 0x10 d EQU 0x11 a16 EQU 0x12 b16 EQU 0x14 a24 EQU 0x16 b24 EQU 0x19 i EQU 0x0E rs EQU 0x10 s EQU 0x03 aa EQU 0x06 bb EQU 0x08 i_2 EQU 0x0A acc24 EQU 0x0B GOTO main ; FILE 18\demo.c ;// DEMO.C : demonstrates implemented features ; ;#pragma chip PIC18C242 // select device ; ;// OTHER SAMPLE CODE: ;// demo-ins.c : generating single instructions using C code ;// demo-mat.c : integer math operations ;// demo-fpm.c : floating point math ;// demo-fxm.c : fixed point math ;// demo-rom.c : const data and DW ;// demo-ptr.c : indexed tables and pointers ;// demo-var.c : defining RAM variables ; ;#pragma rambank 0 ;char a0, b0; ; ;#pragma rambank 1 ;char a1, b1; ; ;#pragma rambank - ;char a, bx; ; ;bit bt1, bt; ; ; ; ;// ************************************************ ;// ************************************************ ;// INTERRUPT SUPPORT ; ;#include "int18XXX.h" ; ;void _highPriorityInt(void); ; ;#pragma origin 0x8 ORG 0x0008 ;interrupt highPriorityIntServer(void) ;{ highPriorityIntServer ; // W, STATUS and BSR are saved to shadow registers ; ; // handle the interrupt ; // 8 code words available including call and RETFIE ; _highPriorityInt(); RCALL _highPriorityInt ; ; // restore W, STATUS and BSR from shadow registers ; #pragma fastMode ;} RETFIE 1 ; ;#pragma origin 0x18 ORG 0x0018 ;interrupt lowPriorityIntServer(void) ;{ lowPriorityIntServer ; // W, STATUS and BSR are saved by the next macro. ; int_save_registers MOVFF STATUS,svrSTATUS MOVFF BSR,svrBSR MOVWF svrWREG,0 ; ; /* NOTE : shadow registers are updated, but will be ; overwritten in case of a high-priority interrupt. ; Therefore #pragma fastMode should not be used on ; low-priority interrupts. */ ; ; // save remaining registers on demand (error/warning) ; //uns16 sv_FSR0 = FSR0; ; //uns16 sv_FSR1 = FSR1; ; //uns16 sv_FSR2 = FSR2; ; //uns8 sv_PCLATH = PCLATH; ; //uns8 sv_PCLATU = PCLATU; ; //uns8 sv_PRODL = PRODL; ; //uns8 sv_PRODH = PRODH; ; //uns24 sv_TBLPTR = TBLPTR; ; //uns8 sv_TABLAT = TABLAT; ; ; // handle the interrupt ; // .. ; ; // restore registers that are saved ; //FSR0 = sv_FSR0; ; //FSR1 = sv_FSR1; ; //FSR2 = sv_FSR2; ; //PCLATH = sv_PCLATH; ; //PCLATU = sv_PCLATU; ; //PRODL = sv_PRODL; ; //PRODH = sv_PRODH; ; //TBLPTR = sv_TBLPTR; ; //TABLAT = sv_TABLAT; ; ; int_restore_registers // W, STATUS and BSR MOVFF svrBSR,BSR MOVFF svrSTATUS,STATUS ;} RETFIE ; ;/* IMPORTANT : GIEH/GIE or GIEL should normally NOT be ; set or cleared in the interrupt routine. GIEH/GIEL are ; AUTOMATICALLY cleared on interrupt entry by the CPU ; and set to 1 on exit (by RETFIE). Setting GIEH/GIEL to ; 1 inside the interrupt service routine will cause ; nested interrupts if an interrupt is pending. Too deep ; nesting may crash the program ! */ ; ; ;void _highPriorityInt(void) ;{ _highPriorityInt ; // save registers on demand ; ; // restore registers on demand ;} RETURN ; ; ; ; ;void subr( void) ;{ subr ; char a, bx, c, d; ; uns16 a16; ; uns16 b16 = a16; MOVFF a16,b16 MOVFF a16+1,b16+1 ; uns24 a24, b24; ; ; b24.high16 = a24.low16; MOVFF a24,b24+1 MOVFF a24+1,b24+2 ; ; a = bx; MOVFF bx_2,a_2 ; c = 10; MOVLW 10 MOVWF c,0 ; a = 10 | bx | d; IORWF bx_2,W,0 IORWF d,W,0 MOVWF a_2,0 ; ; do { ; nop(); m001 NOP ; a --; DECF a_2,1,0 ; } while ( --d > 0); DECFSZ d,1,0 BRA m001 ; ; a = bx * 100; MOVLW 100 MULWF bx_2,0 MOVFF PRODL,a_2 ; a16 = (uns16)bx*c; MOVF c,W,0 MULWF bx_2,0 MOVFF PRODL,a16 MOVFF PRODH,a16+1 ; ; #asm ; DW 0xFFFF ; any data or instruction DW 0xFFFF ; DW 0x0000 DW 0x0 ; DW /*CLRF*/ 0x6A00 + /*UNBANKED*/ 0x000 + /*PRODL*/ 0xF3 DW 0x6AF3 ; #endasm ; PRODL = 0; CLRF PRODL,0 ;} RETURN ; ; ;uns24 accumulate( void) ;{ accumulate ; uns16 i; ; uns24 rs = 0; CLRF rs,0 CLRF rs+1,0 CLRF rs+2,0 ; ; // add all numbers from 1 to 1999 ; for (i = 1; i < 2000; i++) MOVLW 1 MOVWF i,0 CLRF i+1,0 m002 MOVLW 208 SUBWF i,W,0 MOVLW 7 SUBWFB i+1,W,0 BC m003 ; rs += i; MOVF i,W,0 ADDWF rs,1,0 MOVF i+1,W,0 ADDWFC rs+1,1,0 MOVLW 0 ADDWFC rs+2,1,0 INCF i,1,0 ADDWFC i+1,1,0 BRA m002 ; return rs; m003 MOVF rs,W,0 RETURN ;} ; ; ;void main(void) ;{ main ; clearRAM(); // built in function CLRF FSR0,0 CLRF FSR0+1,0 MOVLB 1 m004 CLRF POSTINC0,0 BTFSS FSR0H,1,0 BRA m004 ; ; subr(); MOVLB 0 RCALL subr ; ; GIEL = 1; // enable low priority interrupt BSF 0xFF2,GIEL,0 ; GIEH = 1; // enable high priority interrupt BSF 0xFF2,GIEH,0 ; ; uns24 s = accumulate(); RCALL accumulate MOVFF rs,s MOVFF rs+1,s+1 MOVFF rs+2,s+2 ; ; bt1 = 0; // clear bit BCF 0x21,bt1,0 ; a.7 = 1; // set bit BSF a,7,0 ; bt = !bt; // bit toggle BTG 0x21,bt,0 ; ; if (a > bx) MOVF a,W,0 MOVLB 1 CPFSLT bx,0 BRA m005 ; a &= 0xF0; // mask bits MOVLW 240 ANDWF a,1,0 ; ; // uns16 is 16 bit (unsigned long) ; uns16 aa = 1000; // local variable m005 MOVLW 232 MOVWF aa,0 MOVLW 3 MOVWF aa+1,0 ; uns16 bb = aa+10000; MOVLW 16 ADDWF aa,W,0 MOVWF bb,0 MOVLW 39 ADDWFC aa+1,W,0 MOVWF bb+1,0 ; aa |= 0x10F; // set bits BSF aa+1,0,0 MOVLW 15 IORWF aa,1,0 ; bb &= 0x7F; // clear bits CLRF bb+1,0 BCF bb,7,0 ; ; char i = 10; // 8 bit unsigned MOVLW 10 MOVWF i_2,0 ; ; aa -= i; SUBWF aa,1,0 MOVLW 0 SUBWFB aa+1,1,0 ; ; uns24 acc24 = 0; // 24 bit unsigned CLRF acc24,0 CLRF acc24+1,0 CLRF acc24+2,0 ; for (aa = 0; aa < 3000; aa++) { CLRF aa,0 CLRF aa+1,0 m006 MOVLW 184 SUBWF aa,W,0 MOVLW 11 SUBWFB aa+1,W,0 BC m007 ; acc24 += aa; MOVF aa,W,0 ADDWF acc24,1,0 MOVF aa+1,W,0 ADDWFC acc24+1,1,0 MOVLW 0 ADDWFC acc24+2,1,0 ; nop(); NOP ; } INCF aa,1,0 ADDWFC aa+1,1,0 BRA m006 ; ; if (acc24 == 0) m007 MOVF acc24,W,0 IORWF acc24+1,W,0 IORWF acc24+2,W,0 BNZ m008 ; acc24 = 0xFFFF; SETF acc24,0 SETF acc24+1,0 CLRF acc24+2,0 ; ; aa = i * 200; m008 MOVLW 200 MULWF i_2,0 MOVFF PRODL,aa MOVFF PRODH,aa+1 ; ; acc24 ++; // increment INCF acc24,1,0 MOVLW 0 ADDWFC acc24+1,1,0 ADDWFC acc24+2,1,0 ; aa --; // decrement DECF aa,1,0 SUBWFB aa+1,1,0 ; ; if (aa == 0 || !bt) MOVF aa,W,0 IORWF aa+1,W,0 BZ m009 BTFSC 0x21,bt,0 BRA m010 ; a1 -= 33; m009 MOVLW 33 SUBWF a1,1,1 ; if (!a.7) // test single bit m010 BTFSC a,7,0 BRA m011 ; b0 += a1 + b1; MOVF b1,W,1 ADDWF a1,W,1 MOVLB 0 ADDWF b0,1,1 ; ; nop(); // delay 1 instruction cycle m011 NOP ; ; // W and WREG is the same register (for compatibility) ; W = 10; MOVLW 10 ; WREG >>= 1; // shift right BCF 0xFD8,Carry,0 RRCF WREG,W,0 ;} SLEEP RESET END ; *** KEY INFO *** ; 0x00002C 1 word(s) 0 % : _highPriorityInt ; 0x000008 2 word(s) 0 % : highPriorityIntServer ; 0x000018 10 word(s) 0 % : lowPriorityIntServer ; 0x00002E 34 word(s) 0 % : subr ; 0x000072 22 word(s) 0 % : accumulate ; 0x00009E 104 word(s) 1 % : main ; RAM usage: 38 bytes (31 local), 474 bytes free ; Maximum call level: 1 (+2 for interrupt) ; Total of 175 code words (2 %)