[an error occurred while processing this directive]
Надо цеплять POL к тому уровню, который в SCLK будет считаться неактивным. Привожу рабочий пример для 51 (если пролезет :-)
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)
[an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive]

Отправлено Black Eagle 11 января 2002 г. 00:03
В ответ на: AD7714 отправлено Ю 10 января 2002 г. 19:51

;AD 2500 Assembler synthax used.
;This code works with AD7714 running at 2457.6 KHz, the POL (pin 4) = 1.
;The MCU is Atmel AT89C2051 running at 11059.2 KHz.
;The AD7714 ADC is connected to MCU with two wires (SCLK and SDAT).
;(both DIN and DOUT are tied together to SDAT)
;The ADC gets initialized, calibrated and then all its 4 channels
;are sequentially read 10 times a second to adc_bin 3-byte buffer
;as a 23-bit plus sign absolute value (LSB first).
;Channel samples can be processed on-the-fly - just write
;the appropriate Process_ADC_chX routines.

sclk .reg p3.5 ;ADC (AD7714) serial clock out
sdat .reg p3.7 ;ADC serial data I/O (DIN and DOUT tied together)

flags .reg 28h ;Misc flag bit register

adc_bin .reg 4ch ;ADC binary sample buffer (LSB), 3 bytes

sign .reg flags.1 ;ADC sign bit (1=negative)
f25 .reg flags.2 ;25 ms flag

.org 0
res_vec:
ljmp init

.org 0bh
t0_vec:
ljmp t0_int

;&&&&&&&&&&&&&&&&&&&&&&&&&&&

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;Initialization

.org 30h
init:
mov sp,#50h

mov tmod,#00100001b ;Setup T0 as 16-bit, T1 as 8-bit auto-reload timer

mov tl0,#<-23040 ;For 40 Hz int (every 23040 timer clocks)
mov th0,#>-23040 ;at Fxtal = 11059.2 KHz

mov r7,#40 ;Set up T0 extender to 1000 mS for 1st time
clr f0 ;Clear 100 mS flag
clr f25 ;Clear 25 mS flag

mov ie,#00000010b ;Enable T0 ints

clr tf0

setb tr0 ;Run T0

setb ea ;Global int enable

jnb f0,$ ;Wait for 1000 mS before first ADC channel calibration
clr f0 ;Clear 100 mS flag

mov a,#3 ;Select ADC ch4
mov r3,#00100100b ;Self-cal, gain=2 (+-1.25V), no burnout current
call initadc ;Initialize ADC and launch self-calibration sequence

jnb f0,$ ;100 mS delay before next ADC channel calibration
clr f0 ;Clear 100 mS flag

mov a,#2 ;Select ADC ch3
mov r3,#00100100b ;Self-cal, gain=2 (+-1.25V), no burnout current
call initadc ;Initialize ADC and launch self-calibration sequence

jnb f0,$ ;100 mS delay before next ADC channel calibration
clr f0 ;Clear 100 mS flag

mov a,#1 ;Select ADC ch2
mov r3,#00100100b ;Self-cal, gain=2 (+-1.25V), no burnout current
call initadc ;Initialize ADC and launch self-calibration sequence

jnb f0,$ ;100 mS delay before next ADC channel calibration
clr f0 ;Clear 100 mS flag

mov a,#0 ;Select ADC ch1
mov r3,#00100100b ;Self-cal, gain=2 (+-1.25V), no burnout current
call initadc ;Initialize ADC and launch self-calibration sequence


;*************** Main cycle *************

main:
jnb f0,main ;Wait for a new 100-mS interval flag

clr f0 ;Reset 100 mS flag for current cycle
clr f25 ;Reset 25 mS flag

mov a,#0 ;Set ch0 for next conversion
call readadc ;Read ADC ch3 value
; call Process_ADC_ch3 ;Any routine to process ADC ch3 value
jnb f25,$ ;Ensure ADC conversion cycle is complete
clr f25 ;(25 mS)

mov a,#1 ;Set ch1 for next conversion
call readadc ;Read ADC ch0 value
; call Process_ADC_ch0 ;Any routine to process ADC ch0 value
jnb f25,$ ;Ensure ADC conversion cycle is complete
clr f25 ;(25 mS)

mov a,#2 ;Set ch2 for next conversion
call readadc ;Read ADC ch1 value
; call Process_ADC_ch1 ;Any routine to process ADC ch1 value
jnb f25,$ ;Ensure ADC conversion cycle is complete
clr f25 ;(25 mS)

mov a,#3 ;Set ch3 for next conversion
call readadc ;Read ADC ch2 value
; call Process_ADC_ch2 ;Any routine to process ADC ch2 value
ajmp main ;That's all until next 100 mS

;*************** End of main cycle *************


;^^^^^^^^^^^^^^^^^ Subroutines ^^^^^^^^^^^^^^^^


;^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;Issues ADC initializing commands and sets mode from r3
initadc:
push 2
mov r2,a

mov a,#0ffh ;Reset ADC serial interface
call spi_tx
call spi_tx
call spi_tx
call spi_tx

mov a,#00100000b ;Request FILT_H register write
orl a,r2
call spi_tx
mov a,#01000000b ;Bipolar, 24 bit word, no current boost, high(153)
call spi_tx

mov a,#00110000b ;Request FILT_L register write
call spi_tx
orl a,r2
mov a,#10011001b ;low(153), full (3x) conversion time = 24 mS
call spi_tx

mov a,#00010000b ;Request MODE register write
orl a,r2
call spi_tx
mov a,r3 ;Set requested mode
call spi_tx

pop 2

ret
;
;&&&&&&&&&&&&&&&&&&&&&&&&&&&


;^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;Reads and stores raw ADC data as 23-bit abs value, manages sign flag
readadc:
orl a,#01011000b ;3 LSbits = ch# for next conversion cycle
call spi_tx ;Transmit ADC ch# for next conversion cycle

call spi_rx ;MSB
mov c,acc.7
cpl c ;!!! AD7714 sends MSb=0 for negative
mov sign,c ;Store sign (1=neg)
mov adc_bin+2,a

call spi_rx ;2SB
mov adc_bin+1,a

call spi_rx ;LSB

mov c,sign ;Shift 23-bit word left w/cyclic carry
rlc a
mov adc_bin+0,a

mov a,adc_bin+1
rlc a
mov adc_bin+1,a

mov a,adc_bin+2
rlc a
mov adc_bin+2,a

jnb sign,adc_pos ;Don't negate a positive rdg

mov a,adc_bin ;Do negate a negative rdg
cpl a
add a,#1
mov adc_bin,a

mov a,adc_bin+1
cpl a
addc a,#0
mov adc_bin+1,a

mov a,adc_bin+2
cpl a
addc a,#0
mov adc_bin+2,a

orl a,adc_bin+1 ;Convert -16777216 to -16777215 if necessary
orl a,adc_bin
jnz adc_pos

cpl a
mov adc_bin,a
mov adc_bin+1,a
mov adc_bin+2,a

adc_pos:
ret
;
;&&&&&&&&&&&&&&&&&&&&&&&&&&&

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;SPI byte receive to A
spi_rx:
clr sclk ;Strobe SCLK to 0
mov c,sdat ;Send SDAT to carry flag
setb sclk ;Strobe SCLK back to 1
rlc a ;Shift in the carry flag to A

clr sclk ;Repeat the above 7 times more
mov c,sdat
setb sclk
rlc a

clr sclk
mov c,sdat
setb sclk
rlc a

clr sclk
mov c,sdat
setb sclk
rlc a

clr sclk
mov c,sdat
setb sclk
rlc a

clr sclk
mov c,sdat
setb sclk
rlc a

clr sclk
mov c,sdat
setb sclk
rlc a

clr sclk
mov c,sdat
setb sclk
rlc a

ret
;
;&&&&&&&&&&&&&&&&&&&&&&&&&&&

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;SPI byte transmit from A
spi_tx:
rlc a ;Shift out the ACC MSbit to carry flag
clr sclk ;Strobe SCLK to 0
mov sdat,c ;Send carry flag to SDAT
setb sclk ;Strobe SCLK back to 1

rlc a ;Repeat the above 7 times more
clr sclk
mov sdat,c
setb sclk

rlc a
clr sclk
mov sdat,c
setb sclk

rlc a
clr sclk
mov sdat,c
setb sclk

rlc a
clr sclk
mov sdat,c
setb sclk

rlc a
clr sclk
mov sdat,c
setb sclk

rlc a
clr sclk
mov sdat,c
setb sclk

rlc a
clr sclk
mov sdat,c
setb sclk

rlc a ;!!! Restore A

setb sdat ;!!! Release QBD port line for further input

ret
;
;&&&&&&&&&&&&&&&&&&&&&&&&&&&

;~~~~~~~~~~ Interrupt service routines ~~~~~~~~~~~~~~~~~

;~~~~~~~~~~~~~~~~~~~~~~~~~~~
;T0: sets F0 flag every 100 milliseconds
t0_int:
clr tf0

mov tl0,#<-23040 ;For 40 Hz int (every 23040 timer clocks)
mov th0,#>-23040 ;

setb f25 ;Set 25 mS flag

djnz r7,t0iret ;R7 = timer0 extender

mov r7,#4 ;Preload r7 for next 100 mS cycle

setb f0 ;Set 100 mS flag

t0iret:
reti
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~

;~~~~~~~~~~ End of interrupt service routines ~~~~~~~~~~~~~~~~~

.end


Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru