; CC7A Version 0.5A, Copyright (c) B Knudsen Data ; C compiler for the PIC18 microcontrollers ; ************ 15. Jul 2003 11:06 ************* processor PIC17C766 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 ; ;/* C files that contains function 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 MOVPF WREG,b16 MOVLR 0 MOVFP a16+1,WREG MOVLR 2 MOVPF WREG,b16+1 ; bank2 uns24 a24, b24; ; ; b24.high16 = a24.low16; MOVFP a24,WREG MOVPF WREG,b24+1 MOVFP a24+1,WREG MOVPF WREG,b24+2 ; ; a = bx; MOVLR 0 MOVFP bx_2,WREG MOVPF WREG,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; m007 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 m008 MOVLW 208 SUBWF i,W MOVLW 7 SUBWFB i+1,W BTFSC 0x04,Carry GOTO m009 ; 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 m008 ; return rs; m009 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 m010 CLRF INDF0,1 INCFSZ FSR0,1 GOTO m010 MOVLW 16 ADDWF BSR,1 MOVLW 32 MOVWF FSR0 MOVLW 64 CPFSEQ BSR GOTO m010 ; ; subr(); MOVLB 0 MOVLR 0 CALL subr ; sub1(); MOVLB 0 CALL sub1 ; ; bank2 uns24 s = accumulate(); MOVLR 0 CALL accumulate MOVLR 2 MOVPF WREG,s MOVLR 0 MOVFP rs+1,WREG MOVLR 2 MOVPF WREG,s+1 MOVLR 0 MOVFP rs+2,WREG MOVLR 2 MOVPF WREG,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 m011 ; a &= 0xF0; // mask bits MOVLW 240 ANDWF a,1 ; ; // uns16 is 16 bit (unsigned long) ; bank1 uns16 aa16 = 1000; // local variable m011 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 m012 MOVLW 184 SUBWF aa16,W MOVLW 11 SUBWFB aa16+1,W BTFSC 0x04,Carry GOTO m013 ; 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 m012 ; ; if (acc24 == 0) m013 MOVFP acc24,WREG IORWF acc24+1,W IORWF acc24+2,W BTFSS 0x04,Zero_ GOTO m014 ; acc24 = 0xFFFF; SETF acc24,1 SETF acc24+1,1 CLRF acc24+2,1 ; ; aa16 = i * 200; m014 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 m015 BTFSC 0x22E,bt GOTO m016 ; a1 -= 33; m015 MOVLW 33 SUBWF a1,1 ; if (!a.7) // test single bit m016 MOVLR 1 BTFSC a,7 GOTO m017 ; b0 += a1 + b1; MOVLR 2 MOVFP b1,WREG ADDWF a1,W MOVLR 0 ADDWF b0,1 ; ; nop(); // delay 1 instruction cycle m017 NOP ; ; W = 10; MOVLW 10 ;} SLEEP GOTO main END ; *** KEY INFO *** ; 0x0008 P0 42 word(s) 0 % : iServer ; 0x0032 P0 28 word(s) 0 % : subr ; 0x0050 P0 23 word(s) 0 % : accumulate ; 0x0067 P0 5 word(s) 0 % : sub1 ; 0x006C P0 124 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 223 code words (1 %)