; ; ********************************************** ; * PCM-Encoder 4-Kanal mit Trimmung * ; * fuer ATtiny26, Version 1 Juli 2011 * ; * (C)2011 by http://www.avr-asm-tutorial.net * ; ********************************************** ; ; ACHTUNG! Den internen RC-Oszillator durch ; Programmieren der richtigen Fuses von 1 MHz ; auf 4 MHz Takt umstellen! ; ; Include-Datei fuer den AVR-Typ .NOLIST .INCLUDE "tn26def.inc" ; Headerdatei fuer ATtiny26 .LIST ; ; ============================================ ; H A R D W A R E I N F O R M A T I O N E N ; ============================================ ; ; Schaltbild ; ___________ ; 1 / |20 ; MOSI O--|PB0 PA0|--O ADC0 Kanal1 ; MISO O--|PB1 PA1|--O ADC1 Kanal2 ; SCK O--|PB2 AT PA2|--O ADC2 Kanal3 ; Ausgang O--|PB3 PA3|--O AREF ; VCC O--|VCC tiny GND|--O GND ; GND O--|GND AVC|--O AVCC ; Trim 4 ADC7 O--|PB4 26 PA4|--O ADC3 Kanal4 ; --|PB5 PA5|--O ADC4 Trim 1 ; --|PB6 PA6|--O ADC5 Trim 2 ; RESET O--|RES PA7|--O ADC6 Trim 3 ; 10|____________|11 ; ; ============================================ ; S O F T W A R E D E S I G N ; ============================================ ; ; Software-Timing ohne Interrupts und Timer ; ; Der Prozessor laeuft mit vier MHz Takt aus dem internen ; kalibrierten RC-Generator. Die Fuses sind entsprechend ; zu setzen! ; ; PCM-Signal ; Kanal 1 Kanal 2 Kanal 3 Kanal 4 Synchronsignal ; 500µs 300- ; ___ 1700___ ___ ___ ___ __ ; __| 1 |___| 2 |____| 3 |____| 4 |____| S |___...____| ; AD0 AD4 AD1 AD5 AD2 AD6 AD3 AD7 Umrechnen ; ; Kanalsignalausgabe- und Messperiode ; ----------------------------------- ; Die vier Kanaele starten mit einem 500 us langen Impuls ; am Ausgang. Waehrend dieser Zeit wird am AD-Wandler ein ; Eingang gewandelt und nach Beendigung des Impulses das ; Ergebnis gelesen und im SRAM gespeichert. Dann folgt ; eine Ruhezeit zwischen 800-500=300 und 2200-500=1700 us. ; Waehrend der Ruhezeit wird der naechste AD-Kanal gewan- ; delt und nach Beendigung der Pause das Ergebnis eingele- ; sen. Nach der Ausgabe der vier Kanaele sind alle acht ; Eingaenge umgewandelt und stehen im SRAM ab sAdRes. ; ; Synchronsignalausgabe und Umrechnungsperiode ; -------------------------------------------- ; Der letzte Kanal wird mit einem 500 us langen Synchron- ; signal abgeschlossen. Waehrend der nachfolgenden langen ; Pause werden die AD-Werte in Zeiten umgewandelt: ; - Der Wert am Kanaleingang wird mit 38.437 multipliziert ; (ADC * 1.200 * 65.536 / 1023 / 2 = ADC * 38.437), das ; Ergebnis durch 65.536 geteilt, gerundet und mit zwei ; multipliziert. ; - Der Wert am Trimeingang des gleichen Kanals wird mit ; 12.813 multipliziert (ADC * 200 * 65.536 / 1023 = ; ADC * 12.813), durch 65.536 geteilt und gerundet. ; - Der Wert aus der zweiten Berechnung wird zum ersten ; Wert addiert und die Zeit zur Ausfuehrung des Start- ; impulses (503 us) abgezogen. ; - Die Dauer des inaktiven Teils des Synchronsignals ; wird durch Abziehen der Dauer der vier Kanaele, der ; Dauer von fuenf Startsignalen und der Dauer, die die ; Umrechnung aller Kanaele benoetigt, von 20.000 us ; berechnet. ; - Die Ergebnisse der Umrechnung werden in das SRAM ab ; sCtr geschrieben. ; ; AD-Umwandlungstiming ; -------------------- ; Die AD-Umwandlung erfolgt bei 4 MHz Takt mit einem ; Vorteiler von 64. Fuer eine Wandlung werden 13 * 64 ; Takte benoetigt = 832 Takte = 208 us@4 MHz. ; Es stehen mindestens 800-500-5 = 295 us zur Verfuegung. ; ; ============================================ ; P O R T S U N D P I N S ; ============================================ ; ; Namen fuer Hardware-Ports und Pins .equ pOutP = PORTB ; Output Port .equ pOutD = DDRB ; Portrichtung .equ bOutP = PORTB3 ; Portpin Output ; ; ================================================ ; K O N S T A N T E N Z U M E I N S T E L L E N ; ================================================ ; .equ Invert = 0 ; 1: Signal invertiert ausgeben .equ cOn = 400 ; Dauer Startsignal .equ cBase = 800 ; Mindestdauer Signal .equ cMain = 1000 ; us Zeitvariation Hauptpotentiometer .equ cTrim = 400 ; us Zeitvariation Trimmpotentiometer ; ; ======================================================= ; F E S T E + A B G E L E I T E T E K O N S T A N T E N ; ======================================================= ; .equ cClock = 4000000 ; Prozessortakt 4 MHz .equ cBaseA = cBase-cOn-12 ; Mindestdauer minus Startimpulsdauer .equ cMainM = (65536*cMain+511)/1023 ; Multiplikator fuer AD1 .equ cTrimM = (65536*cTrim+511)/1023 ; Multiplikator fuer AD2 ; ; ============================================ ; R E G I S T E R D E F I N I T I O N E N ; ============================================ ; ; R0 verwendet fuer Kanalmutiplexer ; R1..R10 verwendet fuer Multiplikationen ; Frei: R11..R15 .def rmp = R16 ; Vielzweckregister .def rRL = R17 ; LSB Rechenregister fuer Zeitumrechnung .def rRH = R18 ; dto., MSB ; Frei: R17..R23 .def rCL = R24 ; LSB Timerzaehler .def rCH = R25 ; MSB Timerzaehler ; Verwendet: R27:R26 X als Zeiger AD-Messung ; Verwendet: R29:R28 Y als Zeiger fuer Zaehler ; Verwendet: R31:R30 Z als Zeiger ; ; ============================================ ; S R A M D E F I N I T I O N E N ; ============================================ ; .DSEG .ORG SRAM_START ; sAdRes: ; Speicher fuer gemessene Werte .byte 16 ; acht Kanaele zu je zwei Bytes sCtr: ; Speicher fuer Zaehldauern .byte 10 ; Dauer inaktive Zeiten, 4 Kanaele + Synchronrest ; ; ============================================== ; R E S E T V E K T O R ; ============================================== ; .CSEG .ORG $0000 rjmp Main ; Reset-Vektor ; ; ============================================ ; H A U P T P R O G R A M M I N I T ; ============================================ ; Main: ; Init Stapel fuer Unterprogramme ldi rmp,LOW(RAMEND) ; setze Stapelzeiger out SP,rmp ; Init Portausgang fuer Signalausgang sbi pOutD,bOutP ; Richtung Ausgangsport ; Messe alle acht Kanaele erstmals ldi XH,HIGH(sAdRes) ; Zeiger in SRAM ldi XL,LOW(sAdRes) clr R0 ; channel multiplexer MainAdc: out ADMUX,R0 ldi rmp,(1<