📄 tiny26_adc_test.asm
字号:
; test 3-input adc of ATtiny26
; STERGIOPOULOS Vasilis - Athens - Greece
; vster@tee.gr
; This is a test circuit to test the adc part of ATMEL ATtiny26. 3 analog inputs are connected for testing, but
; up to 10 can be connected.
; The program reads the voltage in the input and displays it to the byte at portA.
; Although the adc is 10 bits I use only the 8 higher bits. So only the ADCH register is read.
; According to the data for ATtiny26, I choosed the settings below:
; The referece is Vcc, the internal reference is not used, because I had not to use the pin Pa3.
; So in the register ADMUX I clear the bits 7(refs1) & 6(refs0).
; I don't use interrupt to know that a conversion is complete. I choose a single conversion (not free running)
; so I clear bit5 (adfr) in ADCSR register.
; I let the default setting for internal oscilator at 1MHz, with prescaler for adc 1/128. The adc needs
; clock between 50KHz and 200kHz, so deviding 1MHz by 128 we get 125KHz. So bits 0,1,2 (ADPS) in register ADCSR
; must be set.
; The result of the conversion is stored in ADCH and ADCL registers. I use left justification of the result
; and if 8-bit accuracy is enough, it is sufficient to read only ADCH register.
; When all these are set we can start the conversion. Set the bit6 (ADSC) in register ADCSR, to start the conversion.
; First show on the LEDs the input number selected (7,8,9), wait a while and proceed.
; When the conversion is complete this bit is cleared by its self. So wait until this bit is cleared.
; Next read the ADCH (8 bits only) and output it to LEDs in portA. Then, after a delay of about 1 sec select next input
; and take the new measurement. Continue for ever.
; Let me know your opinion or question at vster@tee.gr
.NOLIST
.INCLUDE "tn26def.inc"
.LIST
; Used registers r16 = scratch timer
.def Tc = r19 ; Tc timer = r19(MSByte),r18,r17
.def Poa = r20 ; status of outputs
.def chs = r21 ; channel select
.equ Tm = 1 ; preset value of Tc timer, if you change this you change the delay between measurements
; Code starts here
.CSEG
.ORG $0000
; Reset and Interrupt-vectors for ATtiny26
; Reset-vector, when Vcc falls or
; PB7=0 (if RSTDISBL fuse is 1), or WDT is overflown, or
; brown-out detector acts (2.7V for ATtiny26L and 4V for ATtiny26)
rjmp start
; rjmp ExtInt0 ; 2 External Interrupt Request 0
; rjmp PinChange ; 3 I/O pins changed
; rjmp Tim1Cmp1a ; 4 Timer1 compare match 1A
; rjmp Tim1Cmp1b ; 5 Timer1 compare match 1B
; rjmp Tim1Ovfl ; 6 Timer1 overflow
; rjmp Tim0Ovfl ; 7 Timer0 overflow
; rjmp UsiStart ; 8 USI start
; rjmp UsiOvfl ; 9 USI overflow
; rjmp EEReady ; 10 EEPROM ready
; rjmp AnalComp ; 11 Analog Comparator
; rjmp ADCC ; 12 Analog to Digital Conversion complete
; ************** Interrupt service routines ********
; External Interrupt 0 ; general structure for ATtiny26
; ExtInt0: reti
; PinChange: reti
; Tim1Cmp1a: reti
; Tim1Cmp1b: reti
; Tim1Ovfl: reti
; Tim0Ovfl: reti
; UsiStart: reti
; UsiOvfl: reti
; EEReady: reti
; AnalComp: reti
; ADCC: reti
; **************** End of interrupt service routines ***********
; ****************** delay routine **************
delT: dec r17 ; delay routine
brne delT
ser r17
del1: dec r18
brne delT
ser r18
del2: dec r19
brne delT
seTc: ldi Tc,Tm ; preset Tc timer
ret
;;;;;;;;;;;;;;;;;;;;
; **************** End of the subroutines section ***************
; ******************** Main program ****************************
; internal pull-up resistors not needed, since
; external resistors are connected.
start: ldi r16,RAMEND ; Initiate Stackpointer.
out SP,r16
ldi r16,255
out ddra,r16 ; porta is outputs
clr r16
out ddrb,r16 ; portb is inputs
ldi r16,$8f ; pull-up only for inputs that
out portb,r16 ; are not analog inputs
clr Poa
ldi r16,$83
out ADCSR,r16
; ADCSR
; bit7=ADEN=1: enable ADC when = 1
; bit6=ADSC=0: dont start conversion now
; bit5=ADFR=0: single conversion
; bit4=ADIF=0: interrupt flag disabled, is 1 when conv is complete
; bit3=ADIE=0: disable ADC interrupt. The int routine is executed if ADIE=1&SREG(I)=1
; bits2,1,0: 011=prescaler: 1MHz/8=125KHz for ADC clock
; ADMUX
; bit7=REFS1=0,bit6=REFS0=0:reference select 00=AVcc,
; bit5=ADLAR=1: left justify: ADCH fill all the way, and ADCL only bits 7,6 present the LSBits 1 and 0.
; bits4,3,2,1,0=MUXn=input select (0-10: single ended)
sadc: ldi chs,$27 ; input 7 selected first
sadc1: out ADMUX,chs
in r16,ADCSR
sbr r16,(1<<6) ; start coversion, when completed bit6 returns to 0 automatically
out ADCSR,r16
mov r16,chs
andi r16,15
out porta,r16 ; show selected input
rcall delT ; wait a while to see the input number
adcw: sbic ADCSR,6 ; wait for bit6 to clear (when conversion is ready)
rjmp adcw
; for 10-bit resolution erase all the ; marks at start of all rows below here
; in Poa,ADCL ; for 10-bit resolution read ADCL first
; out porta,Poa ; display the result to the LEDs
; rcall delT ; delay
in Poa,ADCH
out porta,Poa ; display the result to the LEDs
rcall delT ; longer delay to distinguish between measurments
rcall delT ; delay
rcall delT ; delay
inc chs ; select next input
cpi chs,$2a ; last input selected?
breq sadc
rjmp sadc1 ; repeat 4 ever
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -