;******************************************************************
; *
; Filename: 10F322 Serial ADC Demo.asm *
; Author: Mike McLaren, K8LH *
; Date: 31-Aug-2014 *
; *
; Read and send 8-bit ADC(0) and ADC(1) results via serial on *
; the RA2 pin (38400 baud). *
; *
; MPLab: 8.92 (tabs = 8) *
; MPAsm: 5.51 *
; *
;******************************************************************
list p=10f322, st=off
#include "p10f322.inc"
radix dec
__CONFIG _FOSC_INTOSC & _WDTE_OFF & _MCLRE_OFF & _LVP_OFF
;--< variables >---------------------------------------------------
cblock 0x40 ; start of 10F322 RAM (0x40..0x7F)
txbyte ; put232() subroutine
bitctr ; put232() subroutine
endc
;--< constants >---------------------------------------------------
TxPin equ RA2 ;
;==================================================================
; K8LH delayCy() subsystem macro generates two instructions
;
clock equ 4 ; 4, 8, 12, or 16 MHz clock
usecs equ clock/4 ; cycles/usec operand multiplier
delayCy macro delay ; range 8..1031 (cycles)
movlw (delay-8)/4+1
call iDelay-(delay%4)
endm
;==================================================================
; readADC() macro
;
ReadADC macro channel ; 0, 1, or 2
movlw channel<<CHS0 ; shift into correct position |00
; xorwf ADCON,W ; delta CHS<2:0> old and new |00
; andlw b'00011100' ; filter out non CHS<2:0> bits |00
; xorwf ADCON,F ; set new CHS<2:0> 'chan' bits |00
call getADC ; |00
endm ;
;******************************************************************
; reset vector *
;******************************************************************
org 0x000
v_reset
goto init ; |00
;******************************************************************
; interrupt vector *
;******************************************************************
org 0x004
v_int
;******************************************************************
; main init *
;******************************************************************
init
; movlw b'01110000' ; value for 16-MHz |00
; movlw b'01100000' ; value for 8-MHz |00
movlw b'01010000' ; value for 4-MHz |00
movwf OSCCON ; change INTOSC speed |00
delayCy(250*usecs) ; |00
;
; setup PORTA digital and ADC pins
;
movlw 1<<RA0|1<<RA1 ; RA0, RA1 (and RA3) inputs |00
movwf TRISA ; RA2 (TxPin) is an output |00
bsf PORTA,TxPin ; set TxPin (RA2) high |00
movlw 1<<ANSA0|1<<ANSA1
movwf ANSELA ; RA0/RA1 (ch 0/1) ADC 'on' |00
;
; setup ADC clock source to OSC/16 (leave ADC 'off')
;
bsf ADCON,ADCS2 ; ADC conversion clock OSC/16 |00
bcf ADCON,ADCS1 ; " |00
bsf ADCON,ADCS0 ; " |00
;******************************************************************
; main loop (approximately 1000 AN0 + AN1 samples per second) *
;******************************************************************
main
ReadADC(0) ; read ADC channel 0 (RA0) |00
call put232 ; send raw 8-bit ADC result in W |00
delayCy(50*usecs) ; 50-usec inter-char delay |00
ReadADC(1) ; read ADC channel 1 (RA1) |00
call put232 ; send raw 8-bit ADC result in W |00
delayCy(50*usecs) ; 50-usec inter-char delay |00
movlw '\r' ; use <cr> character (0x0D) |00
call put232 ; as line terminator char |00
delayCy(50*usecs) ; 50-usec inter-char delay |00
goto main ; loop forever |00
;******************************************************************
; getADC(), pass channel number, 0-2 (shifted left two bits) in *
; wreg on entry and pass the 8-bit ADC result in wreg on exit. *
; *
getADC ;**********************************
xorwf ADCON,W ; setup new CHS (channel) bits |00
andlw b'111'<<CHS0 ; filter out non CHS<2:0> BITS |00
xorwf ADCON,F ; set new CHS<2:0> ADC channel |00
bsf ADCON,ADON ; turn ADC 'on' |00
delayCy(10*usecs) ; 10-usec acquisition delay |00
bsf ADCON,GO_NOT_DONE ; start conversion |00
adcrdy
btfsc ADCON,GO_NOT_DONE ; done? yes, skip, else |00
goto adcrdy ; wait for conversion complete |00
movf ADRES,W ; wreg = 8-bit ADC result |00
bcf ADCON,ADON ; turn ADC 'off' |00
return ; |00
;******************************************************************
; put232 subroutine (change 'skpc' to 'skpnc' to rev polarity). *
; *
; delayCy(104*usecs-10) -> 9600 (0.16%) (4, 8, or 16-MHz clock) *
; delayCy(52*usecs-10) -> 19200 (0.16%) (4, 8, or 16-MHz clock) *
; delayCy(26*usecs-10) -> 38400 (0.16%) (4, 8, or 16-MHz clock) *
; *
put232 ;**********************************
movwf txbyte ; save Tx data |00
movlw 11 ; 1 start + 8 data + 1 stop bit |00
movwf bitctr ; setup bit counter |00
clrc ; |00
goto sendbit ; |00
nextbit
delayCy(26*usecs-10) ; 52-usecs -10 cycle loop time |00
setc ; always shift in a 'stop' bit |00
rrf txbyte,F ; put data bit in Carry |00
sendbit
movf PORTA,W ; read port |00
iorlw 1<<TxPin ; set TxPin bit to 1 |00
skpc ; if data bit = 1 skip, else |00
xorlw 1<<TxPin ; set TxPin bit to 0 |00
movwf PORTA ; precise "bit Time" intervals |00
decfsz bitctr,F ; done? yes, skip, else |00
goto nextbit ; send next bit |00
return ; |00
;******************************************************************
; delayCy() subsystem iDelay subroutine (8-bit 4-cycle loop) *
; ;**********************************
nop ; entry point for (delay%4) == 3 |00
nop ; entry point for (delay%4) == 2 |00
nop ; entry point for (delay%4) == 1 |00
iDelay addlw -1 ; entry point for (delay%4) == 0 |00
skpz ; done? yes, skip, else |00
goto iDelay ; loop again |00
return ; return (Z = 1 and C = 1) |00
;******************************************************************
end
Tom Maier wrote:... so I just made up a project to make an rs232 line powered streaming AD, and here it is.
Users browsing this forum: No registered users and 2 guests