;--------------------------------------------------------------------------- ; ; Programmer : Larry Aamodt ; ; File name : demo_ad_subs.s ; Class : CPTR-215 ; Language : ARM assembly ; Assembler : Keil ; Target MCU : NXP LPC-2148 on Embedded Artists board ; Date Written: 12/06/10 LDA ; change history: ; ; Description : Program to demonstrate: ; Subroutines to initialize and use two A/D ports with ; with the WWU simple vehicle. ; ; Inputs : AD1.6 & AD1.7 (P0.21 & P0.22) ; ; Outputs : LEDs P0.15 down to P0.9 ; ; Special : Embedded artists LPC-2148 education board ; requirements ; ; ; NOTES: ; ; ; ;--------------------------------------------------------------------------- ; Put equates for this program here AD0CR EQU 0xE0034000 ; AD 0 control register AD0DR1 EQU 0xE0034014 ; AD 0 channel 1 data register AD1CR EQU 0xE0060000 ; AD 1 control register AD1DR6 EQU 0xE0060028 ; AD 1 data register for channel 6 AD1DR7 EQU 0xE006002C ; AD 1 data regieter for channel 7 PINSEL1 EQU 0xE002C004 ; Pin function selection register 1 ; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs Mode_USR EQU 0x10 Mode_FIQ EQU 0x11 Mode_IRQ EQU 0x12 Mode_SVC EQU 0x13 Mode_ABT EQU 0x17 Mode_UND EQU 0x1B Mode_SYS EQU 0x1F I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled ; Memory addresses for standard GPIO definitions IO0PIN EQU 0xE0028000 IO0SET EQU 0xE0028004 IO0DIR EQU 0xE0028008 IO0CLR EQU 0xE002800C ; Stack size definitions UND_Stack_Size EQU 0x00000000 SVC_Stack_Size EQU 0x00000008 ABT_Stack_Size EQU 0x00000000 FIQ_Stack_Size EQU 0x00000000 IRQ_Stack_Size EQU 0x00000080 USR_Stack_Size EQU 0x00000400 ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ FIQ_Stack_Size + IRQ_Stack_Size) AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE USR_Stack_Size __initial_sp SPACE ISR_Stack_Size Stack_Top ; Area Definition and Entry Point ; Startup Code must be linked first at Address at which it expects to run. AREA RESET, CODE, READONLY ARM ; Exception Vectors ; Mapped to Address 0. ; Absolute addressing mode must be used. ; Dummy Handlers are implemented as infinite loops which can be modified. Vectors LDR PC, Reset_Addr LDR PC, Undef_Addr LDR PC, SWI_Addr LDR PC, PAbt_Addr LDR PC, DAbt_Addr NOP ; Reserved Vector ; LDR PC, IRQ_Addr LDR PC, [PC, #-0x0FF0] ; Vector from VicVectAddr LDR PC, FIQ_Addr Reset_Addr DCD Reset_Handler Undef_Addr DCD Undef_Handler SWI_Addr DCD SWI_Handler PAbt_Addr DCD PAbt_Handler DAbt_Addr DCD DAbt_Handler DCD 0 ; Reserved Address IRQ_Addr DCD IRQ_Handler FIQ_Addr DCD FIQ_Handler Undef_Handler B Undef_Handler SWI_Handler B SWI_Handler PAbt_Handler B PAbt_Handler DAbt_Handler B DAbt_Handler IRQ_Handler B IRQ_Handler FIQ_Handler B FIQ_Handler ; Reset Handler EXPORT Reset_Handler Reset_Handler ; Initialise Interrupt System ; ... ; Setup Stack for each mode LDR R0, =Stack_Top ; Enter Undefined Instruction Mode and set its Stack Pointer MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit MOV SP, R0 SUB R0, R0, #UND_Stack_Size ; Enter Abort Mode and set its Stack Pointer MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit MOV SP, R0 SUB R0, R0, #ABT_Stack_Size ; Enter FIQ Mode and set its Stack Pointer MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit MOV SP, R0 SUB R0, R0, #FIQ_Stack_Size ; Enter IRQ Mode and set its Stack Pointer MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit MOV SP, R0 SUB R0, R0, #IRQ_Stack_Size ; Enter Supervisor Mode and set its Stack Pointer MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit MOV SP, R0 SUB R0, R0, #SVC_Stack_Size ; Enter User Mode and set its Stack Pointer MSR CPSR_c, #Mode_USR MOV SP, R0 SUB SL, SP, #USR_Stack_Size ; User program code goes here main LDR r5,=IO0SET ; load address of I/O port 0 set register LDR r6,=IO0CLR ; load address of I/O port 0 clear register LDR r7,=0xFF00 ; a mask - bit positions for display LDR r1,=IO0DIR ; load address of I/O port 0 direction register STR r7,[r1] ; configure port pins for output to LEDs ; ports P0.15, 14, 13, 12, 11, 10, 9, 8 BL ad_init ; initialize the A/D loop1 BL ad_read ; read data from A/D 1 channels 6 & 7 STR r7,[r5] ; set output pins to 1 to turn off LEDs via IO0SET ; just channel 6, left sensor, will now be displayed MOV r0,r0,LSL #6 ; shift bits left to display on P0.15 - P0.9 STR r0,[r6] ; turn on LEDs per one's in the data using IO0CLR B loop1 ; endless loop ;***************************************************************************** ; Subroutines follow ;***************************************************************************** ;***************************************************************************** ; A/D converter initialization subroutine. Sets up for reading A/D ; channels AD1.6 and AD1.7 to which vehicle sensors left and right are ; connected. ; ; Inputs: none ; Returned Values: none ; Registers used: ro, r1 ; ; NOTES: ; This routine written for the simple vehicle. Call it once. ; analog sensor inputs come in on AD1.6 and AD1.7 (P0.21 & P0.22) ; (A/D converter #1 on channels 6 and 7) ; Use AD1CR register at 0xE0060000 ; sets the following bits to one in AD1CR: (0xE0060000) (pg 267) ; bit 21 (A/D on) ; bit 16 (burst mode, i.e. A/D continously does conversions) ; bit 6 (turns on channel 6) ; bit 7 (turns on channel 7) ; Reads data from AD1DR6 at 0xE0060028 and AD1DR7 at 0xE006002C (pg 266) ; Sets I/O pins P0.21 & P0.22 for analog input (AD1 ch 6 & 7 respectively) ; by setting bits 11 and 12 in PINSEL1 (0xE002C004) (pg 78) ; (page numbers above refer to the NXP LPC2148 users manual) ;***************************************************************************** ad_init STMFD sp!,{lr} LDR r1,=PINSEL1 ; load address of Pin Function selection reg #1 LDR r0,=0x1800 ; set bits 11 & 12 for pins P0.21 & P0.22 as input STR r0,[r1] LDR r1,=AD1CR ; get address of AD 1 control register LDR r0,=0x2100C0 ; A/D on, burst mode, chs 6 & 7 to be converted STR r0,[r1] end_ad_init LDMFD sp!,{pc} ;***************************************************************************** ; Read vehicle photo sensors. ; Reads channels AD1.6 and AD1.7 to which vehicle sensors left ; and right are connected. ; ; Inputs: none ; Returned Values: ro = left sensor voltage. 0 to 3FF (3FF =2 volts) ; r1 = right sensor voltage. 0 to 3FF ; ; Registers used: ro, r1, r2 ; ; Note: ad_init must be called once prior to calling ad_read ;***************************************************************************** ad_read STMFD sp!,{lr} LDR r2,=AD1DR6 ; channel 6 data register address LDR r0,[r2] ; read left sensor voltage LDR r2,=AD1DR7 ; channel 7 data register address LDR r1,[r2] ; read right sensor voltage MOV r0,r0,ASR #6 ; shift right to justify the value MOV r1,r1,ASR #6 LDR r2,=0x3FF ; 10 bit mask AND r0,r0,r2 ; set upper bits to zero if set AND r1,r1,r2 end_ad_read LDMFD sp!,{pc} ; User data area definition follows AREA appdata, DATA, NOINIT, READWRITE END