;------------------------------------------------- ;Program: MODadc.ASM ;Initial: 13 November, 2003 ;By: Dr. Marcus O. Durham, PhD, PE ; Tulsa, OK, USA ; mod@superb.org ; www.ThewayCorp.com ;Copyright (c)2003. All rights reserved ; ; Thanks to Matt Olson for original code. ;Purpose: ; A set of routines are provided to read from ; a serial peripheral interface. The device is ; an 8-bit analog to digital converter. This uses ; the SPI registers ; ;Processor: 8031 family ;PROM: 8k (2000H) onboard ;Crystal: 11.059 MHz ;Assembler: Intel ASM51 ;################################################# ; ASSIGNMENTS ;################################################# ;CONSTANTS ;------------------------------------------------- ;SPI SpCr EQU 0D5h ;SPI control register SpDr EQU 86h ;SPI data register SpSr EQU 0AAh ;SPI status register AdCs EQU 94h ;adc chip select ;################################################# ; PROGRAM ;################################################# ORG 00h START: LJMP INITIAL ORG 0033h ;Address past vector DB 'Marcus O. Durham, PhD, PE' ;------------------------------------------------- ORG 0080h ;Address past reserve INITIAL: LCALL UART ;initialize serial LCALL SPIINIT ;init spi registers ;------------------------------------------------- MAIN: ;------------------------------------------------- ;PROCESS MOV DPTR,#ONLINE ;serial message LCALL BIOSSER ;send serial message LCALL SPIREAD ;read adc on spi LCALL SERCOMM ;send to serial MAN9: LJMP MAN9 ;repeat ;------------------------------------------------- SPIINIT: ;------------------------------------------------- ; Setup SPI: ; Disable interrupts; enable spi; msb first; ; master; clk low when idle; cpha=1; f=osc/64 MOV SPCR,#01010110B RET ;------------------------------------------------- SPIREAD: ;------------------------------------------------- ; Read byte from ADC. ; ;CHIP SELECT LOW CLR AdCs ;enable chip select NOP ;delay > 1.4usec NOP NOP NOP NOP NOP ; ;INIT DATA REGISTER MOV Spdr,#0AAH ;write anything ;CHECK STAUS SPR1: MOV A,Spsr ;read status reg RLC A ;move spif to carry JNC SPR1 ;<>1, so no data ; ;READ DATA REG MOV A,Spdr ;read data from reg SETB AdCs ;disable select line ;RESET STATUS REG MOV SPSR,#0 ;clear spsr RET ;got byte, get out ;------------------------------------------------- SERCOMM: ;------------------------------------------------- ; Send byte on serial line. ; Convert byte to 2 ASCII characters. ; ;SAVE BYTE & SEGMENT MOV R0,A ;hold data ANL A,#11110000B ;keep high nibble SWAP A ;move to low MOV DPTR,#TABASCII;ASCII table MOVC A,@A+DPTR ;convert to ASCII LCALL SEROUT ;send first number ;GET LOW NIBBLE MOV A,R0 ;restore from earlier ANL A,#00001111B ;keep low nibble MOVC A,@A+DPTR ;convert to ASCII LCALL SEROUT ;send second number MOV A,#13 ;carriage return LCALL SEROUT MOV A,#10 ;line feed LCALL SEROUT RET ;its all over ;------------------------------------------------- BIOSSER: ;------------------------------------------------- ;Send a string to the serial port. MOV A,#0 ;read length string MOVC A,@A+DPTR ;input byte MOV LoopC,A ;setup loop BIOL2: MOV A,#1 ;get 1st message MOVC A,@A+DPTR ;input byte MOV CharL,A ;character icd LCALL SEROUT ;send out byte INC DPTR ;restore offset DJNZ LoopC,BIOL2 ;go thru loop RET ;------------------------------------------------- LONGWAIT: ;------------------------------------------------- ; LongWait delays for ~1 second. LCALL WAIT LCALL WAIT LCALL WAIT LCALL WAIT LCALL WAIT LCALL WAIT LCALL WAIT LCALL WAIT LCALL WAIT LCALL WAIT RET ;------------------------------------------------- WAIT: ;------------------------------------------------- ; Wait will use 0.1 seconds of time before ; returning. ; Delay routine using NOPS and a nested loop. ; Registers R2 & R3 are used for counting loops. ; Count the machine cycles for each instruction. ; NOP = 1 ; MOV = 1 ; DJNZ = 2 ; LCALL= 2 ; RET = 2 ; The time for each loop is calculated ; MOV = 1 1 ; NOP = 1*count 256 ; DJNZ = 2*count 512 ; inside = (incount *2) + 1 513 ; outside= [(inside + 2)outcout] + 1 1 515*192 = 98880 ; Plus = 4 for call 4 ; Total = 100167 ; Each machine cycle requires time to execute. ; This is based on the oscillator frequency. ; Time= (sec/12E6 cycle)(12 period/mach cy) ; = 1E-6 sec ; ; Count = 0.1/1e-6 = 100000 ; 192 = C0H MOV R3,#0C0H ;Outer loop counter ZDEL1: MOV R2,#00H ;Nested loop counter ZDEL2: NOP ;Delay DJNZ R2,ZDEL2 ;Nested loop, 256 x DJNZ R3,ZDEL1 ;Outer loop, 256 x RET ;Return to call ;################################################# ; CODE-STORED CONSTANTS ;################################################# TABASCII: ;------------------------------------------------- ;look-up table for hex to ascii conversion: DB '0123456789ABCDEF' ;------------------------------------------------- ;Canned message to confirm serial port activation: Online: DB 6, 80h ,'Value=', CR, LF, 0 ;################################################# END ;Program end