; CC7A Ver 1.0D, Copyright (c) B Knudsen Data ; C compiler for the PIC18 microcontrollers ; ************ 24. Feb 2011 12:28 ************* processor 17C766 radix DEC PRODL EQU 0x18 PRODH EQU 0x19 INDF0 EQU 0x00 FSR0 EQU 0x01 PCLATH EQU 0x03 ALUSTA EQU 0x04 WREG EQU 0x0A BSR EQU 0x0F Carry EQU 0 Zero_ EQU 2 DDRB EQU 0x11 DDRC EQU 0x110 b0 EQU 0x29 a1 EQU 0x22C b1 EQU 0x22D a EQU 0x1C bx EQU 0x1D bt1 EQU 0 bt EQU 1 sBSR EQU 0x1A sALUSTA EQU 0x1B sWREG EQU 0x20 sPCLATH EQU 0x21 a_2 EQU 0x22 bx_2 EQU 0x23 c EQU 0x24 d EQU 0x25 a16 EQU 0x26 b16 EQU 0x224 a24 EQU 0x226 b24 EQU 0x229 i EQU 0x22 rs EQU 0x24 s EQU 0x220 aa16 EQU 0x120 bb EQU 0x122 i_2 EQU 0x223 acc24 EQU 0x124 GOTO main ; FILE 17\demo.c ;// DEMO.C : contains recommended program structure ; ;#pragma chip PIC17C766 // 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 ; ;/* ; It is RECOMMENDED to move definitions to header files (.h) and ; use #include on these. Also, because no linker is available, it ; is recommended to group related functions on separate files (.c) ; and use #include one these. ;*/ ; ; ;// ************************************************ ;// ************************************************ ;// MACRO DEFINITIONS AND CONSTANTS ; ;#define MY_CONSTANT1 10 ;#define MY_CONSTANT2 (MY_CONSTANT1 * 100L - 50) // nested definition ; ; ;// ************************************************ ;// ************************************************ ;// IO PORT DEFINITIONS ; ;bit pinA @ PORTB.1; // port B, bit 1 ;bit pinB @ PORTC.2; ; ; ;// ************************************************ ;// ************************************************ ;// GLOBAL VARIABLE DEFINITIONS ; ;#pragma rambank 0 ;char a0, b0; // located in ram bank 0 ; ;#pragma rambank 2 ;char a1, b1; // located in ram bank 2 ; ;#pragma rambank - ;char a, bx; // located in shared ram locations ; ;// a bank type modifier overrides the current rambank ;bank3 uns16 u16, table1[3]; // located in ram bank 3 ; ;bank2 bit bt1, bt; // located in ram bank 2 ; ; ;#define DefaultRamBank 0 ;#pragma rambank DefaultRamBank // change to default rambank ; ; ; ;// ************************************************ ;// ************************************************ ;// PROTOTYPES AND CODEPAGES ; ;/* Prototypes are needed when a function is called before it ;is defined. It can also be used for fine tuning the code ;layout (i.e. which codepage to use for a function). */ ; ;char function1( void); ;page1 char function2( void); ;#pragma location 1 ;void function3( void); ;void function4( char aa); ;void function5( int16); ;#pragma location - ; ; ;// ************************************************ ;// ************************************************ ;// INTERRUPT SUPPORT ; ;/* The RECOMMENDED interrupt service routine have the following ; characteristics: ; ; 1) A single interrupt routine is used for ALL vectors. This ; simplifies register saving. It is possible to use separate ; functions for the interrupt vectors, but this is more ; complicated and requires global variables only. ; ; 2) Interrupts should preferably not be nested (GLINTD should not be ; cleared inside the interrupt service routine). The main reason ; for this is the need for recursive saving of registers. A nested ; interrupt can be allowed if NO REGISTERS NEED TO BE SAVED. There ; are several instructions that can be executed without modifying ; any of the special purpose registers (see "int17xxx.h"). ; ; 3) The register save and resore sequences can be modified according ; to the recommendations in "int17xxx.h". ;*/ ; ;#include "int17xxx.h" ; ;// the interrupt routines must be located first on codepage 0 ;#pragma origin 0x8 ORG 0x0008 ; ;interrupt iServer(void) ;{ iServer ; multi_interrupt_entry_and_save MOVFP BSR,sBSR MOVFP ALUSTA,sALUSTA CLRF BSR,1 MOVPF PCLATH,sPCLATH MOVWF sWREG CLRF PCLATH,1 GOTO m004 NOP MOVFP BSR,sBSR MOVFP ALUSTA,sALUSTA CLRF BSR,1 MOVPF PCLATH,sPCLATH MOVWF sWREG CLRF PCLATH,1 GOTO m002 NOP MOVFP BSR,sBSR MOVFP ALUSTA,sALUSTA CLRF BSR,1 MOVPF PCLATH,sPCLATH MOVWF sWREG CLRF PCLATH,1 GOTO m003 NOP MOVFP BSR,sBSR MOVFP ALUSTA,sALUSTA CLRF BSR,1 MOVPF PCLATH,sPCLATH MOVWF sWREG CLRF PCLATH,1 ; ; PERIPHERAL_service: ; // save on demand: PRODL,PRODH,TBLPTRH,TBLPTRL,FSR0,FSR1 ; /* process periferal interrupt */ ; nop(); // .. m001 NOP ; // the right peripheral interrupt flag must be cleared manually ; // restore on demand: PRODL,PRODH,TBLPTRH,TBLPTRL,FSR0,FSR1 ; goto RESTORE_and_return; GOTO m005 ; ; ; TMR0_service: ; // save on demand: PRODL,PRODH,TBLPTRH,TBLPTRL,FSR0,FSR1 ; /* process Timer 0 interrupt */ ; nop(); // .. m002 NOP ; // T0IF is automatically cleared when the CPU vectors to 0x10 ; // restore on demand: PRODL,PRODH,TBLPTRH,TBLPTRL,FSR0,FSR1 ; ; goto RESTORE_and_return; GOTO m005 ; ; ; T0CKI_service: ; // save on demand: PRODL,PRODH,TBLPTRH,TBLPTRL,FSR0,FSR1 ; /* process T0CKI pin interrupt */ ; nop(); // .. m003 NOP ; // T0CKIF is automatically cleared when the CPU vectors to 0x18 ; // restore on demand: PRODL,PRODH,TBLPTRH,TBLPTRL,FSR0,FSR1 ; ; goto RESTORE_and_return; GOTO m005 ; ; ; INT_service: ; // save on demand: PRODL,PRODH,TBLPTRH,TBLPTRL,FSR0,FSR1 ; /* process INT pin interrupt */ ; nop(); // .. m004 NOP ; // INTF is automatically cleared when the CPU vectors to 0x8 ; // restore on demand: PRODL,PRODH,TBLPTRH,TBLPTRL,FSR0,FSR1 ; ; ; RESTORE_and_return: ; ; interrupt_exit_and_restore m005 MOVFP sWREG,WREG MOVFP sPCLATH,PCLATH MOVFP sALUSTA,ALUSTA MOVFP sBSR,BSR RETFIE ;} ; ; ; ;// ************************************************ ;// ************************************************ ;// INCLUDED C FILES AND MATH ROUTINES ; ;/* Functions located in codepage 0 need to be included after the ;interrupt routine. However, if the functions are not located in ;codepage 0, then they can be included before the interrupt routine. ;Using #pragma codepage ensures that functions not yet located (by ;page modifier or #pragma location) are put on certain codepages */ ; ; ;/* ;#pragma codepage 1 ; #include "math16.h" // 16 bit integer math routines ; #include "mm1.c" ; #include "mm2.c" ;#pragma codepage 0 ; #include "mm3.c" ;#pragma codepage 1 ; #include "mm4.c" ;#pragma codepage 0 ; #include "mm5.c" ;*/ ; ;#pragma codepage 0 ; ; ; ;// ************************************************ ;// ************************************************ ;// C FUNCTIONS ; ; ;void subr( void) ;{ subr ; bank0 char a, bx, c, d; ; bank0 uns16 a16; ; bank2 uns16 b16 = a16; MOVFP a16,WREG MOVLR 2 MOVWF b16 MOVLR 0 MOVFP a16+1,WREG MOVLR 2 MOVWF b16+1 ; bank2 uns24 a24, b24; ; ; b24.high16 = a24.low16; MOVFP a24,WREG MOVWF b24+1 MOVFP a24+1,WREG MOVWF b24+2 ; ; a = bx; MOVLR 0 MOVFP bx_2,WREG MOVWF a_2 ; c = 10; MOVLW 10 MOVWF c ; ; do { ; nop(); m006 NOP ; a --; DECF a_2,1 ; } while ( --d > 0); DECFSZ d,1 GOTO m006 ; ; a = 10 | bx | d; MOVLW 10 IORWF bx_2,W IORWF d,W MOVWF a_2 ; nop(); NOP ; ; #asm ; DW 0xFFFF ; any data or instruction DW 0xFFFF ; DW 0x0000 DW 0x0 ; #endasm ;} RETURN ; ; ;uns24 accumulate( void) ;{ accumulate ; bank0 uns16 i; ; bank0 uns24 rs = 0; CLRF rs,1 CLRF rs+1,1 CLRF rs+2,1 ; ; // add all numbers from 1 to 1999 ; for (i = 1; i < 2000; i++) MOVLW 1 MOVWF i CLRF i+1,1 m007 MOVLW 208 SUBWF i,W MOVLW 7 SUBWFB i+1,W BTFSC 0x04,Carry GOTO m008 ; rs += i; MOVFP i,WREG ADDWF rs,1 MOVFP i+1,WREG ADDWFC rs+1,1 MOVLW 0 ADDWFC rs+2,1 INCF i,1 ADDWFC i+1,1 GOTO m007 ; return rs; m008 MOVFP rs,WREG RETURN ;} ; ; ;void sub1( void) ;{ sub1 ; DDRB = 0x20; MOVLW 32 MOVWF DDRB ; DDRC = 0x20; MOVLB 1 MOVWF DDRC ;} RETURN ; ; ;void main(void) ;{ main ; clearRAM(); // built in function MOVLW 26 MOVWF FSR0 CLRF BSR,1 m009 CLRF INDF0,1 INCFSZ FSR0,1 GOTO m009 MOVLW 16 ADDWF BSR,1 MOVLW 32 MOVWF FSR0 MOVLW 64 CPFSEQ BSR GOTO m009 ; ; subr(); MOVLB 0 MOVLR 0 CALL subr ; sub1(); MOVLB 0 CALL sub1 ; ; bank2 uns24 s = accumulate(); MOVLR 0 CALL accumulate MOVLR 2 MOVWF s MOVLR 0 MOVFP rs+1,WREG MOVLR 2 MOVWF s+1 MOVLR 0 MOVFP rs+2,WREG MOVLR 2 MOVWF s+2 ; ; bt1 = 0; // clear bit BCF 0x22E,bt1 ; a.7 = 1; // set bit BSF a,7 ; bt = !bt; // bit toggle BTG 0x22E,bt ; ; if (a > bx) MOVFP a,WREG MOVLB 0 CPFSLT bx GOTO m010 ; a &= 0xF0; // mask bits MOVLW 240 ANDWF a,1 ; ; // uns16 is 16 bit (unsigned long) ; bank1 uns16 aa16 = 1000; // local variable m010 MOVLW 232 MOVLR 1 MOVWF aa16 MOVLW 3 MOVWF aa16+1 ; bank1 uns16 bb = aa16+10000; MOVLW 16 ADDWF aa16,W MOVWF bb MOVLW 39 ADDWFC aa16+1,W MOVWF bb+1 ; aa16 |= 0x10F; // set bits BSF aa16+1,0 MOVLW 15 IORWF aa16,1 ; bb &= 0x7F; // clear bits CLRF bb+1,1 BCF bb,7 ; ; bank2 char i = 10; // 8 bit unsigned MOVLW 10 MOVLR 2 MOVWF i_2 ; ; aa16 -= i; MOVLR 1 SUBWF aa16,1 MOVLW 0 SUBWFB aa16+1,1 ; ; bank1 uns24 acc24 = 0; // 24 bit unsigned CLRF acc24,1 CLRF acc24+1,1 CLRF acc24+2,1 ; for (aa16 = 0; aa16 < 3000; aa16++) { CLRF aa16,1 CLRF aa16+1,1 m011 MOVLW 184 SUBWF aa16,W MOVLW 11 SUBWFB aa16+1,W BTFSC 0x04,Carry GOTO m012 ; acc24 += aa16; MOVFP aa16,WREG ADDWF acc24,1 MOVFP aa16+1,WREG ADDWFC acc24+1,1 MOVLW 0 ADDWFC acc24+2,1 ; nop(); NOP ; } INCF aa16,1 ADDWFC aa16+1,1 GOTO m011 ; ; if (acc24 == 0) m012 MOVFP acc24,WREG IORWF acc24+1,W IORWF acc24+2,W BTFSS 0x04,Zero_ GOTO m013 ; acc24 = 0xFFFF; SETF acc24,1 SETF acc24+1,1 CLRF acc24+2,1 ; ; aa16 = i * 200; m013 MOVLW 200 MOVLR 2 MULWF i_2 MOVLR 1 MOVPF PRODL,aa16 MOVPF PRODH,aa16+1 ; ; acc24 ++; // increment INCF acc24,1 MOVLW 0 ADDWFC acc24+1,1 ADDWFC acc24+2,1 ; aa16 --; // decrement DECF aa16,1 SUBWFB aa16+1,1 ; ; if (aa16 == 0 || !bt) MOVFP aa16,WREG IORWF aa16+1,W MOVLR 2 BTFSC 0x04,Zero_ GOTO m014 BTFSC 0x22E,bt GOTO m015 ; a1 -= 33; m014 MOVLW 33 SUBWF a1,1 ; if (!a.7) // test single bit m015 MOVLR 1 BTFSC a,7 GOTO m016 ; b0 += a1 + b1; MOVLR 2 MOVFP b1,WREG ADDWF a1,W MOVLR 0 ADDWF b0,1 ; ; nop(); // delay 1 instruction cycle MOVLR 1 m016 NOP ; ; W = 10; MOVLW 10 ; ; W = aa16.low8; MOVFP aa16,WREG ; ;} SLEEP GOTO main END ; *** KEY INFO *** ; 0x0008 P0 42 word(s) 0 % : iServer ; 0x0032 P0 28 word(s) 0 % : subr ; 0x004E P0 23 word(s) 0 % : accumulate ; 0x0065 P0 5 word(s) 0 % : sub1 ; 0x006A P0 126 word(s) 1 % : main ; RAM usage: 44 bytes (29 local), 858 bytes free ; Maximum call level: 1 (+1 for interrupt) ; Codepage 0 has 225 word(s) : 2 % ; Codepage 1 has 0 word(s) : 0 % ; Total of 225 code words (1 %)