Modular Programming Simplifies All of These Tasks
Total Page:16
File Type:pdf, Size:1020Kb
LHO 18 11/5/08 Modular Programming In a real world-programming task the actual coding requires considerable less time than the design, debug, and maintenance of the program. Modular programming simplifies all of these tasks. Programming becomes much simpler when the task is divided into small functional units or modules i.e subroutines. Correctly designed modular programs are easier to code, debug, and change than monolithic programs. Divide the program into small functional units that perform a well-designed task while hiding the details from the rest of the program. Simplify the connection between modules. Collected related subroutines into a common file.
Consider UDC.ASM as an example. NAME UDC ; VERSION 10/30/08 - Version 1 ;Additional subroutines and updates will be added later ;UDC.ASM - Basic subroutines for using the Silico Labs ;Tool Stick University Daughter Card ; By Dr. Jerry H. Tucker ; [email protected] ; School of Engineering ; Virginia Commonwealth University ; Richmond, VA. $include (c8051f020.inc); Register definition file. PUBLIC INIT ; Initilize system PUBLIC DELAY ; DELAY FOR SHORT TIME PUBLIC RD_BTNS ; READ PUSH BUTTONS PUBLIC WR_LEDS ; WRITE TO LEDS PUBLIC RD_LEDS ; READ LEDS PROG SEGMENT CODE ; SEGMENT FOR PROGRAM IN ROM DVAR SEGMENT DATA ; SEGMENT FOR VARIABLES IN RAM RSEG PROG LED EQU P5 ; lEDS ARE CONNECTED TO P5.7-P5.4 BTN EQU P5 ;PUSH BUTTONS ARE CONNECTED TO P5.3-P5.0 ;PUBLIC SUBROUTINES
1 ;*************************************************************** ; FUNCTION: INIT - Initialize UNI DAUGHTER CARD ; INPUTS: NONE ; OUTPUTS: NONE ; CALLS: INIT_CROSSBAR, INIT_PORTS ; DESTROYS: SFR's ;*************************************************************** ; INIT: CLR EA ;Disable interrupts MOV WDTCN,#0DEH ;DISABLE WATCH DOG TIMER MOV WDTCN,#0ADH ;DISABLE WATCH DOG TIMER CALL INIT_CROSSBAR ;ENABLE CROSS BAR CALL INIT_PORTS ; CALL INIT_OSC ;ENABLE EXTERNAL XTAL RET ;*************************************************************** ; FUNCTION: RD_BTNS - READ STATUS OF BUTTONS.CONNECTED TO ; P5.3 - P5.0 INTO LOW NIBBLE OF ACC ; INPUTS: NONE ; OUTPUTS: ACC(3..0) - BITS ARE SET IF BUTTON IS PRESSED ; ACC(7..0) = 0000 ; CALLS: NONE ; DESTROYS: ACC ;*************************************************************** ; RD_BTNS: MOV A,P5 ;READ PUSH BUTTONS CPL A ;CHANGE PRESSED FROM 0 TO 1 ANL A,#0FH ;MAST OFF LED BITS RET ;*************************************************************** ; FUNCTION: WR_LEDS - OUTPUT LOW NIBBLE OF ACC TO LED'S.CONNECTED ; TO P5.7 - P5.4 ; INPUTS: ACC(3..0) - A '1' WILL TURN LED ON. ; OUTPUTS: NONE ; CALLS: NONE ; DESTROYS: NONE ;*************************************************************** ; WR_LEDS: PUSH PSW ;SAVE FLAGS PUSH ACC ;SAVE ACC 2 SWAP A ;MOVE INPUT TO HIGH NIBBLE ORL A,#0FH ;SET LOW NIBBLE TO ALL 1'S MOV P5,A ;OUTPUT TO LED PORT POP ACC ;RESTORE ACC POP PSW ;RESTORE PSW RET ;*************************************************************** ; FUNCTION: RD_LEDS - RETURN IN ACC STATUS OF LED'S CONNECTED ; TO P5.7 - P5.4 ; INPUTS: NONE ; OUTPUTS: ACC(3..0) - IF LED IS ON THAT BIT IS SET TO '1' ; ACC(7..0) - SET TO ALL 0'S. ; CALLS: NONE ; DESTROYS: NONE ;*************************************************************** ; RD_LEDS: MOV A,P5 ;GET LED'S SWAP A ;PUT LED BITS IN LOW NIBBLE ANL A,#0FH ;KEEP ONLY LED BITS RET ;*************************************************************** ; FUNCTION: RD_SWTS - READ SWITCHES ON UNI TS BOART ; INPUTS: NONE ; OUTPUTS: A - DIP SWITCH VALUE ; CALLS: NONE ; DESTROYS: NONE ;*************************************************************** ; RD_SWTS: MOV A,P4 ;READ SWITCHES RET ;LOCAL SUBROUTINES ;*************************************************************** ; FUNCTION: INIT-CROSSBAR - Initialize crossbar ; UART 0 TX and RX enabled ; SYS CLK brought out to P0.2 ; INPUTS: NONE ; OUTPUTS: NONE ; CALLS: NONE ; DESTROYS: SFR's ;*************************************************************** ;
3 INIT_CROSSBAR: MOV XBR0,#00000100B ;UART 0 TX TO P0.0, RX TO P0.1 MOV XBR1,#10000000B ;SYSCLK OUT MOV XBR2,#01000000B ;ENABLE THE CROSSBAR RET ;*************************************************************** ; FUNCTION: INIT-PORTS - Initialize I/O ports ; INPUTS: NONE ; OUTPUTS: NONE ; CALLS: NONE ; DESTROYS: SFR's ;*************************************************************** ; INIT_PORTS: MOV P0MDOUT,#00000101B ;SET TX, P0.2 PINS TO PUSH PULL MOV P1MDOUT,#00H ;SET P1 TO OPEN DRAIN MOV P2MDOUT,#00H ;SET P2 TO OPEN DRAIN MOV P3MDOUT,#00H ;SET P3 TO OPEN DRAIN MOV P74OUT,#08H ;SET P5 LOW NIBBLE TO PUSH PULL MOV P4,#0FFH ;SET SWT INPUTS TO ALL 1'S RET ;*************************************************************** ; FUNCTION: INIT_OSC - SWITCHES FROM 2 MHZ STARTUP CLOCK TO ; 22.114 MHZ EXTENAL XTAL ; INPUTS: NONE ; OUTPUTS: NONE ; CALLS: NONE ; DESTROYS: ACC, SFR's ;*************************************************************** ; INIT_OSC: MOV OSCXCN,#01100111B ;ENABLE 22.1184 MHZ.XTAL OSC CLR A ;CLEAR COUNT TO WAIT > 1 ms DJNZ ACC,$ ;DELAY FOR 256*4CPI/2MHZ=512 us DJNZ ACC,$ ;DELAY FOR 256*4CPI/2MHZ=512 us XWAIT: MOV A,OSCXCN ;GET XTAL OSC VALID BIT JNB ACC.7,XWAIT ;LOOP TILL XTAL OSC VALID ORL OSCICN,#08H ;SEL XTAL OSC ORL OSCICN,#80H ;ENABLE MISSING CLK DETECTION RET
4 ;*************************************************************** ; FUNCTION: DELAY - Delay for a short time ; NOTE: USING THE 22.1184 MHz XTAL OSC A CLOCK CYCLE = 45.2ns ; CLOCK CYCLES FOR PROGRAM EXECUTIN 4730957 FOR A ; TOTAL TIME OF .256 SEC ; INPUTS: NONE ; OUTPUTS: NONE ; CALLS: NONE ; DESTROYS: NONE ;*************************************************************** ; USING 0 ;TELL ASSEMBLY WE ARE USING REG BANK 0 ; SEE TABLE 12.1 OF C8051F02x.pdf FOR INSTRUCTION TIMES DELAY: ; CPI TOTAL CLKS PUSH PSW ;SAVE FLAGS 2 2 PUSH AR3 ;SAVE R3 (DM(3)) 2 2 PUSH AR4 ;SAVE R4 2 2 PUSH AR5 ;SAVE R5 2 2 MOV R3,#0 ;CLEAR R3 2 2 MOV R4,#0 ;CLEAR R4 2 2 MOV R5,#24 ;OUTER LOOP COUNT 2 2 D1: DJNZ R3,D1 ;LOOP 256*256*25 TIMES 2/3 (255*3+2)*256*24 DJNZ R4,D1 ;LOOP 256*25 TIMES 2/3 (255*3+2)*24 DJNZ R5,D1 ;LOOP 25 TIMES 2/3 24*3+1*2 POP AR5 ;RESTORY R5 2 2 POP AR4 ;RESTORE R 2 2 POP AR3 ;RESTORE R3 2 2 POP PSW ;RESTORE FLAGS 2 2 RET ; 5 5 ; TOTAL = 4730957 END
5 IO – Ports on the University Tool Stick Port 0
P0.0 and P0.1 are used for the UART. P0.2 through P0.7 are brought to the PORT_0 connector.
6 Port 1 and Port 2.
All pins are available on PORT_1 and PORT_2 connector. PORT 3
Pins usage has been assigned such as for the DAC and ADC.
7 Port 4 – Connected to dip switches. Port 5 – Connected to LED’s and push button switches. Port 6 and 7 – Not used. Pins are not brought out for access by user.
8 Setting up the ports
9 10 11 12 13 14 15 ;********************************************************** ; FUNCTION: INIT-PORTS - Initialize I/O ports ;********************************************************** INIT_PORTS: MOV P0MDOUT,#01H ;SET TX PIN TO PUSH PULL MOV P1MDOUT,#00H ;SET P1 TO OPEN DRAIN MOV P2MDOUT,#00H ;SET P2 TO OPEN DRAIN MOV P3MDOUT,#00H ;SET P3 TO OPEN DRAIN MOV P74OUT,#08H ;SET P5 OUT AS PUSH PULL MOV P4,#0FFH ;SET SWT INPUTS TO ALL 1'S RET
16 The Oscillator
X 110 X 111
17 INIT_OSC: MOV OSCXCN,#01100111B ;ENABLE 22.1184 MHZ.XTAL OSC CLR A ;CLEAR COUNT TO WAIT > 1 ms DJNZ ACC,$ ;DELAY FOR 256*4CPI/2MHZ=512 us DJNZ ACC,$ ;DELAY FOR 256*4CPI/2MHZ=512 us XWAIT: MOV A,OSCXCN ;GET XTAL OSC VALID BIT JNB ACC.7,XWAIT ;LOOP TILL XTAL OSC VALID ORL OSCICN,#08H ;SEL XTAL OSC ORL OSCICN,#80H ;ENABLE MISSING CLK DETECTION RET
18 Timers
19 20 ;*************************************************************** ; FUNCTION: INIT_TIMER3 - SET TIMER 3 TO INTERRUPT EVERY 10 ms ; SET COUNTER TO BE INCREMENTED BY SYS CLK/12 = 1.842833 MHz THEN ; FOR 10 ms DELAY NUMBER OF COUNTS = 1.842833 * 10000 = 18428 ; RELOAD VALUE = 2^16 - 18428 = 47108 ;*************************************************************** INIT_TIMER3: MOV TMR3CN,#0 ;BE SURE TIMER 3 IS STOPED MOV TMR3RLL,#LOW 47108 ;LOW BYTE OF RELOAD VALUE MOV TMR3RLH,#HIGH 47108 ;HIGH BYTE OF RELOAD VALUR MOV TMR3L,#0FFH ;RELOAD IMMEDIATELY MOV TMR3H,#0FFH MOV TMR3CN,#100B ;COUNTER INC BY SYS CLK/12 RET Another example interrupt every 100 us. ;*************************************************************** ; FUNCTION: INIT_TIMER3 - SET TIMER 3 TO INTERRUPT EVERY 100 us. ; SET COUNTER TO BE INCREMENTED BY SYS CLK = 22.1184 MHz. ; FOR 100us DELAY NUMBER OF COUNTS = 22.1184 * 100 = 2212 ; INPUTS: NONE ; OUTPUTS: NONE ; CALLS: NONE ; DESTROYS: NONE ;*************************************************************** ; RLCNT EQU 10000H - 2212 INIT_TIMER3: MOV TMR3CN,#0 ;BE SURE TIMER 3 IS STOPED MOV TMR3RLL,#LOW RLCNT ;LOW BYTE OF RELOAD VALUE MOV TMR3RLH,#HIGH RLCNT ;HIGH BYTE OF RELOAD VALUR MOV TMR3L,#0FFH ;RELOAD IMMEDIATELY MOV TMR3H,#0FFH MOV TMR3CN,#110B ;COUNTER INC BY SYS CLK RET
21 Interrupts Interrupts cause temporary suspension of the current program. Control is then passed to a special subroutine called an interrupt service routine (ISR). After the ISR is complete control is returned to the regular program at the point where it was interrupted. Special care must be exercised when dealing with common resources shared between the ISR and the main program. The C8051F020 supports 22 interrupt sources both internal and external. Each interrupt can be individually enabled and disabled using bits in the SFR’s. The global interrupt must be enabled before any interrupt will be serviced. This is done be setting the EA bit. When an enabled interrupt occurs the processor transfers control to an interrupt vector location for that specific interrupt and executes the instruction at that location. Typically the instruction at the interrupt vector location is a JUMP to the ISR for that interrupt. An interrupt summary table is shown below.
22 23 ;INTERRUPT VECTOR LOCATINS CSEG AT 0 ; absolute Segment at Address 0 RESET: LJMP MAIN ;ON RESET JUMP TO START OF PROGRAM ORG 73H ; TIMER 3 OVERFLOW INTERRUPT LOC T3OVF: JMP ISRT3 ; JUMP TO ISR FOR TIMER 3 RSEG PROG ; SWITCH TO CODE SEGMENT ;MAIN PROGRAM STARTS HERE MAIN: MOV SP,#STACK-1 ; Initialize stack pointer CALL INIT ; Initialize system ;ENABLE INTERRUPTS ORL EIE2,#ET3 ; ENABLE TIMERE 3 INTERRUPT SETB EA ; ENABLE INTERRUPTS ;DO FOREVER LOOP LOOP: MOV R3,#BLINKRATE ; SET FREQ OF SHIFT ANL A,#0FH ; CLEAR MOST SIG NIBBLE OF COUNT CALL HW12 ; GET NEXT COUNT CALL WR_LEDS ; OUTPUT COUNT TO LEDS WAIT: CJNE R3,#0,WAIT ; WAIT FOR 10 TIMER 3 INTERUPTS JMP LOOP ; LOOP FOREVER ;*********************************************************** ; FUNCTION: ISRT3 - TIMER 3 OVERFLOW ISR SETS GO FLAG ; INPUTS: NONE ; OUTPUTS: GO ; CALLS: NONE ; DESTROYS: GO, TMR3CN ;************************************************************ ISRT3: PUSH PSW ;SAVE FLAGS ANL TMR3CN,#7FH ;CLEAR T3 OVERFLOW FLAG SETB GO ;SET GO SIGNAL POP PSW ;RESTORE PSW RETI
24 INIT: CLR EA ;Disable interrupts MOV WDTCN,#0DEH ;DISABLE WATCH DOG TIMER MOV WDTCN,#0ADH ;DISABLE WATCH DOG TIMER CALL INIT_CROSSBAR ;ENABLE CROSS BAR CALL INIT_PORTS ; CALL INIT_OSC ;ENABLE EXTERNAL XTAL CALL INIT_ADC0 CALL INIT_DACS CALL INIT_TIMER3 ;SET TIMER 3 TO INTERRUPT EVERY 10 ms CALL INIT_TIMER1 CALL INIT_UART0 RET ;********************************************************** ; FUNCTION: INIT_DACS - Initialize DAC0 AND DAC1 ;*********************************************************** INIT_DACS: MOV REF0CN,#07H ;USE INTERNAL VREF MOV DAC0CN,#10000000B ;EN DAC0, UPDATE ON WR, ;LEFT JUSTIFIED MOV DAC1CN,#10000000B ;EN DAC1, UPDATE ON WR, ;LEFT JUSTIFIED RET
25 ;************************************************************* ; FUNCTION: WR_DAC0 - WRITE DAC 0 ; INPUTS: R6|R7 - CONTAINS 12 BIT OUTPUT TO DAC0 ; OUTPUTS: NONE ; CALLS: NONE ; DESTROYS: DAC0L, DAC0H ;************************************************************ WR_DAC0: MOV DAC0L,R7 ;OUTPUT LOW BYTE MOV DAC0H,R6 ;OUTPUT HIGH BYTE RET
26