;*************************************************************************** ; ; NSC ADC12130 Software Interface on PIC 16F84 V1.02 ; =================================================== ; ; written by Peter Luethi, 31.7.1999, Dietikon, Switzerland ; http://www.electronic-engineering.ch ; last update: 19.04.2004 ; ; V1.02: Added LCDcflag (LCD command/data flag) to comply with ; latest LCD modules. ; (19.04.2004) ; ; V1.01: Updated to latest revision of m_lcd_bf.asm ; (31.12.2000) ; ; This code and accompanying files may be distributed freely and ; modified, provided this header with my name and this notice remain ; intact. Ownership rights remain with me. ; You may not sell this software without my approval. ; ; This software comes with no guarantee or warranty except for my ; good intentions. By using this code you agree to indemnify me from ; any liability that might arise from its use. ; ; ; SPECIFICATIONS: ; =============== ; Processor: Microchip PIC 16F84 ; Clock: 4.00 MHz XT ; Throughput: 1 MIPS ; Required Hardware: NSC ADC12130, dot matrix LCD display ; ; ; DESCRIPTION: ; ============ ; This is a communication test routine between the PIC16F84 and ; the NSC ADC12130 12 bit A/D Converter based on the software- ; implemented SSP (Synchronous Serial Port) interface. ; The following features are implemented: ; - Setup of SSP communication and control lines to A/D converter ; - Auto Calibration and Mode Configuration of A/D converter ; - Status Read of A/D configuration ; - Readout of A/D value and display on LCD Display. ; ; Output format: 16 bit unsigned, MSB first, CH0 single-ended : ; 0 0 0 0 MSB <12 bit data> LSB ; ;*************************************************************************** ;***** COMPILATION MESSAGES & WARNINGS ***** ERRORLEVEL -207 ; Found label after column 1. ERRORLEVEL -302 ; Register in operand not in bank 0. ;***** PROCESSOR DECLARATION & CONFIGURATION ***** PROCESSOR 16F84 #include "p16F84.inc" ; embed Configuration Data within .asm File. __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ;***** MEMORY STRUCTURE ***** ORG 0x00 ; processor reset vector goto MAIN ORG 0x04 ; interrupt vector location goto MAIN ; no Interrupt Service Routine ;***** PORT DECLARATION ***** LCDtris equ TRISB LCDport equ PORTB #define CS PORTA,0 ; chip select, active low #define CONV PORTA,1 ; do conversion, active low #define DO PORTA,2 ; serial data output #define SCK PORTA,3 ; serial clock, idle state low #define DI PORTA,4 ; serial data input ;***** CONSTANT DECLARATION ***** CONSTANT BASE = 0x0C ; Base address of user file registers ;*** CONFIGURATION COMMANDS of NSC ADC12130 *** CONSTANT AutoCal = b'00100000' CONSTANT AutoZero = b'00100100' CONSTANT PowerUp = b'00101000' CONSTANT PowerDown = b'00101100' CONSTANT StatusRead = b'00110000' CONSTANT Unsigned = b'00110100' CONSTANT Signed = b'10110100' CONSTANT AT6 = b'00111000' CONSTANT AT10 = b'01111000' CONSTANT AT18 = b'10111000' CONSTANT AT34 = b'11111000' CONSTANT DummyCmd = b'00000000' ;*** CH0 : channel 0, se : single-ended, format, first bit *** CONSTANT CH0se12MSB = b'10000000' CONSTANT CH0se16MSB = b'10000100' CONSTANT CH0se12LSB = b'10010000' CONSTANT CH0se16LSB = b'10010100' ;*** CH1 : channel 1, se : single-ended, format, first bit *** CONSTANT CH1se12MSB = b'11000000' CONSTANT CH1se16MSB = b'11000100' CONSTANT CH1se12LSB = b'11010000' CONSTANT CH1se16LSB = b'11010100' ;*** CH0 : CH0 vs CH1, df : differential mode, format, first bit *** CONSTANT CH0df12MSB = b'00000000' CONSTANT CH0df16MSB = b'00010000' CONSTANT CH0df12LSB = b'00010000' CONSTANT CH0df16LSB = b'00010100' ;***** REGISTER DECLARATION ***** FLAGreg equ BASE+d'6' #define LCDbusy FLAGreg,0x00 ; LCD busy flag #define LCDcflag FLAGreg,0x01 ; LCD command/data flag b16_cnt equ BASE+d'7' ; counter for 16 bit binary output AD_cnt set BASE+d'8' ; counter for A/D readout HI equ BASE+d'9' LO equ BASE+d'10' HI_TEMP set BASE+d'11' LO_TEMP set BASE+d'12' SSPSR equ BASE+d'13' ; SSP Shift Register ;***** INCLUDE FILES ***** #include "..\m_bank.asm" #include "..\m_wait.asm" #include "..\m_lcd_bf.asm" #include "..\m_lcdb16.asm" ;***** MACROS ***** ADinit macro BANK1 movlw b'11110000' ; set A/D control lines I/O direction movwf TRISA BANK0 movlw b'00000011' ; set A/D control lines : movwf PORTA ; disable chip select & conversion, endm ; SCK low ADenable macro movlw b'11111100' ; select chip & enable conversion andwf PORTA,1 endm ADdisable macro movlw b'00000011' ; deselect chip & disable conversion iorwf PORTA,1 endm ADcmd macro ADcommand movlw ADcommand call AD_cmd endm ;***** SUBROUTINES ***** AD_cmd movwf SSPSR ; call with command in w movlw d'8' movwf AD_cnt ad_loop ;*** TRANSMISSION : MSB out on pin DO *** btfss SSPSR,7 ; check MSB, skip if set bcf DO btfsc SSPSR,7 ; check MSB, skip if cleared bsf DO ; btfss/btfsc used due to illegal consecutive write cycles ; on output pins and to prevent unnecessary spikes: ; only one write cycle is performed ;*** rotate SSPSR left, because bit 7 clocked out *** rlf SSPSR,1 nop ; settle time for transmission ;*** RECEPTION on rising edge of serial clock *** bsf SCK ; clock high nop ; settle time for clock high bcf SSPSR,0 ; fetch data applied on DI btfsc DI bsf SSPSR,0 ;*** TRANSMISSION on falling edge of serial clock *** bcf SCK ; clock low decfsz AD_cnt,1 goto ad_loop RETURN ;************** MAIN ************** MAIN LCDinit ADinit LCDchar 'N' LCDchar 'S' LCDchar 'C' LCDchar ' ' LCDchar 'A' LCDchar 'D' LCDchar 'C' LCDchar '1' LCDchar '2' LCDchar '1' LCDchar '3' LCDchar '0' LCDchar ' ' LCDchar 'C' LCDchar 'I' LCDchar 'N' LCDline 2 LCDchar 'T' LCDchar 'e' LCDchar 's' LCDchar 't' LCDchar '-' LCDchar 'I' LCDchar 'n' LCDchar 't' LCDchar 'e' LCDchar 'r' LCDchar 'f' LCDchar 'a' LCDchar 'c' LCDchar 'e' WAITX d'16',d'7' ;*** Display Default Configuration of the A/D: Status Read *** ADenable ADcmd StatusRead ADdisable LCDcmd LCDCLR LCDchar 'S' LCDchar 't' LCDchar 'a' LCDchar 't' LCDchar 'u' LCDchar 's' ;*** Set A/D output format to unsigned *** ADenable ADcmd Unsigned movfw SSPSR movwf HI ; get upper 8 bits of status data ; get remaining bit of status data : bsf SCK ; clock high nop ; settle time for clock high clrf LO btfsc DI bsf LO,7 ; store remaining status bit bcf SCK ; clock low ADdisable LCD_DDAdr 0x07 ; display status data: 9 bits (!) LCDbin_16 ; default: 13 bit, MSB first, signed WAITX d'25',d'7' ;*** Set Aquisition Time to 34 CCLK Cycles *** ADenable ADcmd AT34 ; wait at least 34 tck ADdisable ; = 0.0085 ms @ 4 MHz WAIT 0x01 ;*** Auto-Calibration of A/D *** ADenable ADcmd AutoCal ; wait at least 4944 tck ADdisable ; = 1.232 ms @ 4 MHz WAIT 0x03 ;*** Auto-Zero of A/D *** ADenable ADcmd AutoZero ; wait at least 76 tck ADdisable ; = 0.019 ms @ 4 MHz WAIT 0x01 ;*** Display Current Configuration of the A/D: Status Read *** ADenable ADcmd StatusRead ; Note: the returned bit length ADdisable ; corresponds to the preceeding command WAIT 0x01 ADenable ;***************** ADcmd CH0se16MSB ; CH0, single-ended, 16 bit, MSB first ;ADcmd CH1se16MSB ; CH1, single-ended, 16 bit, MSB first ;***************** movfw SSPSR movwf HI ; get upper 8 bits of status data ; get remaining bit of status data : bsf SCK ; clock high nop ; settle time for clock high clrf LO btfsc DI bsf LO,7 ; store remaining status bit bcf SCK ; clock low ADdisable LCD_DDAdr 0x07 ; display status data: 9 bits (!) LCDbin_16 ; now: 16 bit, MSB first, unsigned ;*** A/D Value Readout *** Loop ; wait at least Tacq + Tconv = (34 + 44) Tclk ; = 78 Tclk = 20 us @ 4 MHz WAIT 0x01 ; wait 1 ms ADenable ;***************** ADcmd CH0se16MSB ; CH0, single-ended, 16 bit, MSB first ;ADcmd CH1se16MSB ; CH1, single-ended, 16 bit, MSB first ;***************** movfw SSPSR movwf HI bsf CONV ; disable conversion (for safety reasons) ADcmd DummyCmd movfw SSPSR movwf LO ADdisable LCD_DDAdr 0x40 ; display A/D data LCDbin_16 goto Loop ; re-entry END