⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tiny26_adc_test.asm

📁 用TINY26做的模拟量采集工具,详细看附件
💻 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 + -