Home =>
AVR-Übersicht =>
8-Bit-ADC am STK500 => adc8 software
(This page in English:
)
Assembler-Quelltext der Umwandlung einer Analogspannung in eine 8-Bit-Zahl
; +-----------------------------------------------------+
; | 8-Analog-Digital-Converter mit ATMEL AT90S8515 |
; | auf dem STK500 board, Ausgabe über LEDs |
; | (C)2003 by http://www.avr-asm-tutorial.net |
; | Verwendete Anschlüsse: Ausgang PWM-Rechteckspannung |
; | OC1A an Port D, Bit 5; über dreifach RC-Filter an|
; | invertierienden Analogeingang AIN1 entsprechend |
; | Port B Bit 3; Anschluss der zu messenden Analog- |
; | spannung an nichtinvertierenden Analogeingang |
; | Port B Bit 2; Ausgabe für die LEDs an Port C |
; +-----------------------------------------------------+
;
; Geschrieben für und getestet mit AT90S8515 auf STK500
;
.NOLIST
.INCLUDE "8515def.inc"
.LIST
;
; Konstanten
;
.EQU CycLen = 128 ; Anzahl PWM-Zyklen zum Einschwingen
.EQU CycLen0 = 128 ; Anzahl PWM-Zyklen vor der ersten Messung
;
; Register
;
.DEF rRes = R1 ; Endwert des ADC
.DEF rTmp = R14 ; Temporärwert für ADC
.DEF rSrg = R15 ; Temporärregister für SREG
.DEF rmp = R16 ; Universalregister ohne Int
.DEF rimp = R17 ; Universalregister bei Int
.DEF rFlg = R18 ; Flagregister, Bit 0=ADC fertig
.DEF rBlc = R19 ; Bitlevel-Counter für ADC
.DEF rCcL = R24 ; Cycle Counter für ADC, LSB
.DEF rCcH = R25 ; dto., LSB
;
; Reset- und Interrupt-Vektoren
;
rjmp main ; Reset
reti ; INT0
reti ; INT1
reti ; TC1-Capt
reti ; TC1-CompA
reti ; TC1-CompB
rjmp Tc1Ovflw ; TC1-Ovflw
reti ; TC0-Ovflw
reti ; SPI STC
reti ; UART RX
reti ; UART UDRE
reti ; UART TX
reti ; Ana-Comp
;
; TC1-Overflow am PWM-Zyklusende
;
Tc1Ovflw:
in rSrg,SREG ; Sichern von SREG
sbiw rCcL,1 ; Erniedrige Zykluszähler
brne Tc1OvflwR ; bei ><0 fertig
ldi rCcH,HIGH(CycLen) ; Setze Zyklenzähler
ldi rCcL,LOW(CycLen)
sbis ACSR,ACO ; prüfe Analogcomp-Ausgang
eor rTmp,rBlc ; U zu hoch, lösche letztes Bit
lsr rBlc ; Aktives Bit eins rechts
brcc Tc1OvflwA ; noch nicht fertig
mov rRes,rTmp ; Kopiere das Ergebnis
sbr rFlg,0x01 ; Setze Fertig-Flag
ldi rCcH,HIGH(CycLen0) ; Setze Dauer vor Messbeginn
ldi rCcL,LOW(CycLen0)
clr rTmp ; Leeres Ergebnis
ldi rBlc,0x80 ; Setze Bitzähler
Tc1OvflwA:
or rTmp,rBlc ; setze nächstes Bit
clr rimp ; Setze TC1-PWM-Zyklus
out OCR1AH,rimp
out OCR1AL,rTmp
Tc1OvflwR: ; Rückkehr vom Interupt
out SREG,rSrg ; SREG wieder herstellen
reti
;
; Hauptprogramm-Schleife
;
main:
ldi rmp,HIGH(RAMEND) ; Definiere Stack
out SPH,rmp
ldi rmp,LOW(RAMEND)
out SPL,rmp
ldi rCcH,HIGH(CycLen0) ; Setze Dauer vor Messbeginn
ldi rCcL,LOW(CycLen0)
ldi rBlc,0x80 ; Setze Bitzähler
mov rTmp,rBlc ; Leeres Ergebnis
ldi rmp,0xFF ; Port C auf Output, treibt die LEDs
out DDRC,rmp ; alle Datenrichtungsregister = 1
sbi DDRD,PD5 ; PWM-Ausgang OC1A auf Ausgang setzen
ldi rmp,0b00100000 ; Sleep-mode idle einstellen
out MCUCR,rmp
ldi rmp,0b10000001 ; TC1 auf PWM8 non-invertiert
out TCCR1A,rmp ; in TC1-Kontrollregister A
ldi rmp,0b00000001 ; TC1-clock=System clock
out TCCR1B,rmp ; in TC1-Kontrollregister B
clr rmp ; Pulsweite Rechtecksignal einstellen
out OCR1AH,rmp ; erst das HIGH Byte!
ldi rmp,0x80 ; dann das LOW Byte!
out OCR1AL,rmp
ldi rmp,0b10000000 ; TC1 Overflow Int einschalten
out TIMSK,rmp ; in Timer Int Mask Register
sei ; Reaktion auf Interrupts durch CPU ermöglichen
;
; Hauptprogramm-Loop
;
main1:
sleep ; CPU schlafen legen
nop
sbrs rFlg,0 ; Ready flag Bit 0 abfragen
rjmp main1 ; Nicht ready, schlaf weiter
cbr rFlg,0x01 ; Setze Bit 0 zurück
mov rmp,rRes ; Kopiere Ergebnis in Universalregister
com rmp ; Invertiere alle bits (Lampe invers!)
out PortC,rmp ; an LED Port ausgeben
rjmp main1 ; fertig, schlafen legen
;
; Ende des Programms
;
©2003 by http://www.avr-asm-tutorial.net