;--------------------------------------------------------------------------- ; ; Programmer : Larry Aamodt ; ; File name : demo_ad.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 : Uses A/D zero channel 1 (AD0.1) to read a voltage ; produced by the left potentiometer on the LPC-2148 board ; and displays the upper 8 bits on the LEDs ; ; Inputs : AD0.1 ; ; 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 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 r1,=IO0DIR ; load address of I/O port 0 direction register LDR r2,=IO0SET ; load address of I/O port 0 set register LDR r3,=IO0CLR ; load address of I/O port 0 clear register LDR r4,=IO0PIN ; load address of I/O port 0 pins LDR r5,=AD0CR ; load address of A/D 0 control register LDR r6,=AD0DR1 ; load address of A/D 0 chan 1 data register LDR r7,=PINSEL1 ; load address of Pin Function selection reg #1 LDR r0,=0xFF00 STR r0,[r1] ; configure port pins for output to LEDs ; ports P0.15, 14, 13, 12, 11, 10, 9, 8 STR r0,[r2] ; set output pins to 1 (turns off LEDs) via IO0SET LDR r0,=0x1000000 ; set bit 24 to set pin P0.28 as analog input pin STR r0,[r7] LDR r0,=0x210006 ; A/D on, burst mode, chs 1 & 2 to be converted STR r0,[r5] LDR r0,=0xff00 ; mask for A/D data (data on bits 15 -> 6) loop1 LDR r11,[r6] ; read data from A/D 0 chan 1 BIC r11,r0,r11 ; complement the data and mask out non-data bits ; recall, BIC complements the third operand ; and then ANDs that with the second operand ; complementing here is needed because to light an ; LED a zero needs to be written STR r11,[r4] ; write data to the LEDs. Note: it is assumed ; that the only port 0 bits configured for output ; are the LEDs. If other bits are used then it ; would be better to write 0's with IO0CLR followed ; by writing the data with IO0SET ; B loop1 ; endless loop ; User data area definition follows AREA appdata, DATA, NOINIT, READWRITE END ; ; For the robot vehicle, modify the code above as follows: ; sensor analog inputs come in on AD1.6 and AD1.7 (P0.21 & P0.22) ; (A/D converter 1 and channels 6 and 7) ; Use AD1CR register at 0xE0060000 rather than AD0CR ; set the following bits to one in AD1CR: (pg 267) ; bit 21 (A/D on) ; bit 16 (burst mode) ; bit 6 (convert channel 6) ; bit 7 (convert channel 7) ; Read data from AD1DR6 at 0xE0060028 and AD1DR7 at 0xE006002C (pg 266) ; Set I/O pins P0.21 & P0.22 for analog input (AD1 ch 6 & 7 respectively) ; by setting bits 11 and 12 in IOSEL1 (rather than bit 24 as done above) ; (pg 78) ; NOTE: page numbers above refer to the NXP LPC2148 users manual ; In the example above, the converter runs continually converting and putting ; data into the data register. The application program simply reads from ; the data registers when it wants current data. Simple at that point.