avr_racer
01.04.2014, 19:01
Hallo,
hier mal eine kleine Bibliothek für den AtMega8, womit ich schon seit etwas längerer Zeit arbeite,
damit man nicht bei jedem Projektstart sich elendig lange wieder alles aus dem Datenblatt zusammen suchen muss
und zügiger starten kann.
getestet mit:
SW AVRStudio4.19 Build 716
HW STK500
Includes sind folgende
ADC
AnalogComparator
EEprom
Externe Interrupts
UART um rs232 aufzubauen
TimerCounter T0-T2
Die origin.asm ist die Hauptdatei.
Viel Spaß beim probieren
origin.asm
;######################################
;# Projekt: #
;# #
;# #
;# Taktfrequenz des AVR: 4 MHz #
;# #
;# CS-SOFT #
;###########################################
.include "m8def.inc" ;Atmega8
.def math1h = r8
.def math1l = r9
.def math2h = R10
.def math2l = r11
.def matherghh = r12
.def mathergh = r13
.def mathergl = r14
.def mathergll = r15
.def temp0 = r16 ;
.def temp1 = r17 ;
.def temp2 = r18
.def temp3 = r19 ;
.def temp4 = r20
.def cnt = r21
.equ ocr2s = $0063 ;für T2
.equ ocra1h = $0064 ;;;;;
.equ ocra1l = $0065 ;;;;;;;; für T1 A channel
.equ ocrb1h = $0066 ;;;;;
.equ ocrb1l = $0067 ;;;;;;;; für T1 B channel
.equ icr1xh = $0068 ;;;;;
.equ icr1xl = $0069 ;;;;;;;; für T1 ICR
.equ hadc = $006a ;adc
.equ ladc = $006b ;adc
.equ eep_adrh= $006c ;eeprom
.equ eep_adrl= $006d ;eeprom
;***************************Einsprungadressen***** ******************
.cseg
.org $0000
rjmp stack
.org $0001 ;1
rjmp INT_0
.org $0002 ;2
rjmp INT_1
.org $0003 ;3
rjmp INT_OC2
.org $0004 ;4
rjmp INT_OVF2
.org $0005 ;5
rjmp INT_ICP1
.org $0006 ;6
rjmp INT_OC1A
.org $0007 ;7
rjmp INT_OC1B
.org $0008 ;8
rjmp INT_OVF1
.org $0009 ;9
rjmp INT_OVF0
reti ;a keine SPI Routinen
.org $000b ;b
rjmp INT_URXC
.org $000c ;c
rjmp INT_UDRE
.org $000d ;d
rjmp INT_UTXC
.org $000e ;e
rjmp adc_rdy
.org $000f ;f
rjmp eeprom_rdy
.org $0010 ;10
rjmp ac_int
reti ;11 keine 2wireRoutinen
reti ;12 keine SPMRoutinen
/* so könnten die einsprungmarken der INTS auch aussehen
INT0addr
INT1addr
OC2addr
OVF2addr
ICP1addr
OC1Aaddr
OC1Baddr
OVF1addr
OVF0addr
SPIaddr
URXCaddr
UDREaddr
UTXCaddr
ADCCaddr
ERDYaddr
ACIaddr
TWIaddr
SPMRaddr
*/
;***************************Init mit allem drumdran*****************
stack: ldi temp1,high(ramend) ;Stackpointer festlegen
out sph, temp1
ldi temp1,low(ramend) ;Stackpointer festlegen
out spl, temp1
rcall sram
sbi portb,0 ;pulls aktivieren nur wenn Taster genutzt werden sollen
sbi portb,1
sbi portb,2
sbi portb,3
; rcall INIT_ext_Int01
; rcall deak_int01
; rcall mode0_t0_init
; rcall prescaler_T0_on
; rcall mode0_t1_init
; rcall prescaler_T1_on
; rcall mode0_t2_init
; rcall prescaler_T2_on
; rcall adc_header
; rcall eeprom_init ;wenn ints bevorzugt werden
; rcall adr_cnt
; rcall eeprom_write
; rcall AC_init
; rcall ac_change
rcall usart_init ;wenn INT bevorzugt dann hier aktivieren und prog erweitern
start: sbis pinb,0
rcall tx ;senden TST auf Bildschirm
sbis pinb,1
rcall tx_db ;sende " TST " auf Bildschirm aus Datenbank
sbis pinb,2
rcall test_zahl ;sende Zahl z.B. hex 99 auf Bildschirm !!!!!Keine HEX:DEZ Wandlung!!!!!!!!!!!!!!!!
sbis pinb,3
rcall rx ;warte auf Empfang von " "=$20 und schicke * zurück
nop
nop
nop
nop
nop
nop
nop
nop
rjmp start
;**********************Masterclr****************** *********************
sram: clr temp0
ldi yl,low(SRAM_START)
ldi yh,high(SRAM_START) ;Masterclr des Sram's über
sram2: st y+,temp0 ;die indirekte Adressierung
cpi yl,$70 ;bis zur zelle x=$70 löschen
brne sram2
ret
;*************************weitere*includedata***** ******************
.include "timercounter.asm"
.include "ext_ints.asm"
.include "uart_std.asm"
.include "adc_lst.asm"
.include "eeprom.asm"
.include "analogcomparator.asm"
.include "zeitschleifen.asm"
.include "mathe.asm"
;*************************ENDE******************** ******************
adc_lst.asm !!!!Änderung in start_convers!!!!!!!!!!!!!!!
/*
.equ ADC_ddr = ddrc
.equ ADC_Port = Portc
.equ ADC_Pin = PinC
.equ Chan0 = 0
.equ Chan1 = 1
.equ Chan2 = 2
.equ Chan3 = 3
.equ Chan4 = 4
.equ Chan5 = 5
*/
;******************************adc_interrupt****** ****************
adc_rdy:
in temp0,adcl ;wichtig erst low
sts ladc,temp0
in temp1,adch ;dann high lesen sonst erg müll
sts hadc,temp1
reti
;***********************adc_header**************** **********
adc_header:
rcall adc_init
rcall start_convers_int ;mit Interrupt
;rcall start_convers ;ohne Interrupt
ret
;***********************adc_init****************** ***********
adc_init:
ldi temp0,(0<<Chan5|0<<Chan4|0<<Chan3|0<<Chan2|0<<Chan1|0<<Chan0)
out ADC_ddr,temp0
ldi temp0,(0<<Chan5|0<<Chan4|0<<Chan3|0<<Chan2|0<<Chan1|0<<Chan0)
out ADC_Pin,temp0
in temp0,adcsra
ori temp0,(1<<ADEN|0<<ADSC|0<<ADFR|0<<ADIE|1<<ADPS2|0<<ADPS1|1<<ADPS0) ;
out adcsra,temp0
in temp0,admux
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX3|0<<MUX2|0<<MUX1|1<<MUX0) ;AVCC with external capacitor at AREF pin
out admux,temp0 ;+ messkanal0 (PC0) eingang
ret
;mit Interrupt
start_convers_int:
in temp0,adcsra ;wenn ADFR aktiv dann nur adc_read nötig für jeweiligen kanal
ori temp0,(0<<ADEN|1<<ADSC|0<<ADFR|1<<ADIE|1<<ADPS2|0<<ADPS1|0<<ADPS0) ;freigabe ADC Abtastrate zwischen 50Khz-200Khz Teiler=32 single mode
out adcsra,temp0 ;
sei
ret
;ohne Interrupt dann abfrage auf das bits ADSC=1?????
start_convers:
in temp0,adcsra
ori temp0,(0<<ADEN|1<<ADSC|0<<ADFR|0<<ADIE|1<<ADPS2|0<<ADPS1|1<<ADPS0);freigabe der Messung
out adcsra,temp0
start_convers2: ;;;
sbic ADCSR,ADSC ;;;;;; diese kleine routine braucht man nicht wenn man mit ints arbeitet
rjmp start_convers2 ;;;
in temp0,adcl ;wichtig erst low
in temp1,adch ;dann high lesen sonst erg müll
sts ladc,temp0
sts hadc,temp1
ret
analogcomparator.asm
;ACHTUNG man kann im simulator nicht mit PD6/7 simulieren geht nur
;wenn ACO händisch gesetzt wird ACO=1 wird auch ACI=1 um den int zu nutzen
;wenn man den int nicht nutzt ist die abfrage auf ACO
AC_init:
ldi temp0,(0<<ACD|0<<ACBG|1<<ACIE|0<<ACIC|0<<ACIS1|0<<ACIS0)
out ACSR,temp0
sei ;
ret
ac_change:
sbis ACSR,ACO
rjmp ac_change
ret
ac_int:
;wird aufgerufen wenn pd6+/pd7- pegelunterschiede feststellen
reti
eeprom.asm
;*************************************
eeprom_init:
ldi temp0,(1<<EERIE)
out EECR,temp0
sei
ret
eeprom_rdy:
;siehe eeprom_write ;** man kann in der wartezeit andere sachen erledigen
;bis der int kommt, um dann weitere daten an den eeprom zum schreiben zu senden
;nur bei eeprom schreiben möglich
reti
;Adreessierung im eeprom
adr_cnt:lds temp0,eep_adrl
inc temp0
cpi temp0,$ff
breq adr_cnt2
sts eep_adrl,temp0
ret
adr_cnt2:
clr temp0
sts eep_adrl,temp0
lds temp0,eep_adrh
inc temp0
sts eep_adrh,temp0
cpi temp0,$02
breq error_eeprom
ret
error_eeprom:
;voll
ret
EEPROM_write:
sbic EECR,EEWE ;** falls eewe im eecr noch gesetzt
rjmp EEPROM_write ;** spring zu zurück
lds r18,eep_adrh
out EEARH, r18 ;highbyte der adr
lds r17,eep_adrl
out EEARL, r17 ;lowbyte der adr
out EEDR,r16 ;zu speichernder wert
sbi EECR,EEMWE ;sperrt eeprom master write enable
sbi EECR,EEWE ;setze EEWE um eeprom zu schreiben
ret
EEPROM_read:
sbic EECR,EEWE ;falls eewe im eecr noch gesetzt
rjmp EEPROM_read ;springe zurück
lds r18,eep_adrh
out EEARH, r18 ;highbyte der adr
lds r17,eep_adrl
out EEARL, r17 ;lowbyte der adr
sbi EECR,EERE ;sperrt lesen des eeproms
in r16,EEDR ;zu lesender wert
ret
ext_ints.asm
;PD2/3 sind INT0/1
INIT_EXT_INT01:
in temp0,MCUCR
ori temp0,(1<<ISC11|1<<ISC10|1<<ISC01|1<<ISC00) ;hier INT0/1 auf steigende flanke siehe PDF KAP.13
out MCUCR,temp0
in temp0,GICR
ori temp0,(1<<INT1|1<<INT0) ;beide INTs aktiv
out GICR,temp0
sei ;global int
ret
deak_INT01:
in temp0,GICR
andi temp0,(0<<INT1|0<<INT0) ;beide INTs aktiv
out GICR,temp0
ret
INT_0: ;hier steht das programm welches ausgeführt werden soll
reti
INT_1: ;hier steht das programm welches ausgeführt werden soll
reti
timercounter.asm
;*****************************INIT-Mode 1 Timer0******************************************** ************************
mode0_t0_init:
in temp1,TIMSK
ori temp1,(1<<TOIE0)
out TIMSK,temp1
ldi temp1,$60
out TCNT0,temp1
ret
prescaler_T0_on:
in temp0,TCCR0
ori temp0,(0<<CS12|0<<CS11|1<<CS10) ;schmeißt den counter an
out TCCR0,temp0
sei
ret
prescaler_T0_off:
in temp0,TCCR0
andi temp0,(0<<CS12|0<<CS11|0<<CS10) ;stoppt den counter an
out TCCR0,temp0
ret
INT_OVF0: ;$0009
;Achtung T0 muss hier neu geladen werden und dann die eigene IDEE
reti
;******************************Init-Modes des Timers1******************************************* ********************
mode0_T1_init:;NORMAL_MODE OCR1A h:l,OCR1B h:l update ocrxH:L sofort oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<ICNC1|0<<ICES1|0<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(0<<COM1A1|0<<COM1A0|0<<COM1B1|0<<COM1B0|0<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode1_T1_init:;8bit phase correct mode OCR1A h:l,OCR1B h:l update ocrxH:L on top oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode2_T1_init:;9bit phase correct mode OCR1A h:l,OCR1B h:l update ocrxH:L on top oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode3_T1_init:;10bit phase correct mode OCR1A h:l,OCR1B h:l update ocrxH:L on top oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode4_T1_init:;CTC mode OCR1A h:l,OCR1B h:l update ocrAH:L oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(0<<COM1A1|0<<COM1A0|0<<COM1B1|0<<COM1B0|0<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode5_T1_init:;FAST PWM 8bit OCR1A h:l,OCR1B h:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode6_T1_init:;FAST PWM 9bit OCR1A h:l,OCR1B h:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode7_T1_init:;FAST PWM 10bit OCR1A h:l,OCR1B h:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode8_T1_init:;PWM,PahseFrequenzyCorrect OCR1A h:l,ICRh:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<ICES1|1<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(1<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode9_T1_init:;PWM,PahseFrequenzyCorrect OCR1A h:l,OCR1A h:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode10_T1_init:;PWM,PahseCorrect OCR1A h:l,ICRh:l update ocrxH:L on top oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(1<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode11_T1_init:;PWM,PahseCorrect OCR1A h:l,OCRah:l update ocrxH:L on top oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode12_T1_init:;CTC OCR1A h:l,ICRh:l update sofort oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(0<<COM1A1|1<<COM1A0|0<<COM1B1|1<<COM1B0|0<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(1<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode13_T1_init:;RESERVED not activated
/* ;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
*/ ret
mode14_T1_init:;FAST PWM OCR1A h:l,ICRh:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(1<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode15_T1_init:;FAST PWM OCR1A h:l,OCRah:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
prescaler_T1_on:
in temp0,TCCR1B
ori temp0,(1<<CS12|1<<CS11|1<<CS10) ;schmeißt den counter an
out TCCR1B,temp0
sei
ret
prescaler_T1_off:
in temp0,TCCR1B
andi temp0,(0<<CS12|0<<CS11|0<<CS10) ;stoppt den counter an
out TCCR1B,temp0
ret
;**********Channel load
A_ch_load:
ldi temp0,$9c ;Toggeln oder Clr/Set aktiv muss OCR1Ah-Register beachtet werden um
sts OCRa1h,temp0 ;____--- oder _------ zu erreichen
out OCR1ah,temp0
ldi temp0,$40 ;Toggeln oder Clr/Set aktiv muss OCR1Al-Register beachtet werden um
sts OCRa1l,temp0 ;____--- oder _------ zu erreichen
out OCR1al,temp0
ret
A_ch_en:sbi ddrb,1 ;output aktivieren wenn Toggeln am PINB1=OCR1A erwünscht
ret
A_ch_dis:
cbi ddrb,1 ;output deaktivieren wenn Toggeln am PINB1=OCR1A erwünscht
ret
B_ch_load:
ldi temp0,$00 ;Toggeln oder Clr/Set aktiv muss OCR1Bh-Register beachtet werden um
sts OCRb1h,temp0 ;____--- oder _------ zu erreichen
out OCR1bh,temp0
ldi temp0,$80 ;Toggeln oder Clr/Set aktiv muss OCR1Bl-Register beachtet werden um
sts OCRb1l,temp0 ;____--- oder _------ zu erreichen
out OCR1bh,temp0
ret
B_ch_en:sbi ddrb,2 ;output aktivieren wenn Toggeln am PINB1=OCR1A erwünscht
ret
B_ch_dis:
cbi ddrb,2 ;output deaktivieren wenn Toggeln am PINB1=OCR1A erwünscht
ret
T1_clr:
clr temp0
out TCNT1h,temp0
out TCNT1l,temp0
ret
;**********ISR
INT_ICP1: ;$0005 Timer/Counter1 Capture Event
;ICRH:L wird vom Counter TVCNT1H:L bei Steigender/Fallender Flanke beschrieben
reti
INT_OC1A: ;$0006 Timer/Counter1 Compare Match A
set
;push temp0
;lds temp0,OCRa1h ;Toggeln oder Clr/Set aktiv muss OCR1Ah-Register beachtet werden um
;out OCR1Ah,temp0 ;____--- oder _------ zu erreichen
;lds temp0,OCRa1l ;Toggeln oder Clr/Set aktiv muss OCR1Al-Register beachtet werden um
;out OCR1Al,temp0 ;____--- oder _------ zu erreichen
;pop temp0
reti
INT_OC1B: ;$0007 Timer/Counter1 Compare Match B
push temp0
lds temp0,OCRb1h ;Toggeln oder Clr/Set aktiv muss OCR1Bh-Register beachtet werden um
out OCR1Bh,temp0 ;____--- oder _------ zu erreichen
lds temp0,OCRb1l ;Toggeln oder Clr/Set aktiv muss OCR1Bl-Register beachtet werden um
out OCR1Bl,temp0 ;____--- oder _------ zu erreichen
pop temp0
reti
INT_OVF1: ;$0008 Timer/Counter1 Overflow
reti
;************************************************* ************************************************** ****************
;******************************Init-Modes des Timers2******************************************* ********************
mode0_T2_init:;NORMAL_MODE OCR2 update sofort oder im INT
;sbi ddrb,3 ;output aktivieren wenn Toggeln am PINB3=OCR2 erwünscht
;ldi temp0,$80 ;Toggeln oder Clr/Set aktiv muss OCR2-Register beachtet werden um
;out OCR2,temp0 ;____--- oder _------ zu erreichen
in temp0,TIMSK
ori temp0,(0<<OCIE2|1<<TOIE2) ;TimerOvfl-Int aktivieren
out TIMSK,temp0
ldi temp0,(0<<WGM21|0<<WGM20|0<<COM21|0<<COM20) ;zum Toggeln COM2x Einstellungen beachten!!!!!!!!!
out TCCR2,temp0 ;
ret
mode1_T2_init:;PWM-PhaseCorrect kein toggeln möglich nur Clear/Set, bei erreichen TOP = OCR2 update
sbi ddrb,3 ;output aktivieren
ldi temp0,$80 ;zum Clr/Set muss OCR2-Register beachtet werden um
out OCR2,temp0 ;____--- oder _------ zu erreichen
in temp0,TIMSK
ori temp0,(0<<OCIE2|0<<TOIE2);OutputCompareInterrupt deaktiviert
out TIMSK,temp0
ldi temp0,(0<<WGM21|1<<WGM20|1<<COM21|0<<COM20) ;zum Toggeln COM2x Einstellungen beachten!!!!!!!!!
out TCCR2,temp0
ret
mode2_T2_init:;CTC = nonPwm = toggeln möglich OCR2 update sofort oder im INT
sbi ddrb,3 ;output aktivieren
ldi temp0,$13 ;Toggeln oder Clr/Set aktiv muss OCR2-Register beachtet werden um
out OCR2,temp0 ;________-------- oder ____---- zu erreichen
sts OCR2s,temp0
in temp0,TIMSK
ori temp0,(1<<OCIE2|0<<TOIE2);OutputCompareInterrupt deaktiviert
out TIMSK,temp0
ldi temp0,(1<<WGM21|0<<WGM20|0<<COM21|1<<COM20) ;zum Toggeln COM2x Einstellungen beachten!!!!!!!!!
out TCCR2,temp0
ret
mode3_T2_init:;FastPWM kein toggeln möglich nur Clear/Set, bei erreichen BOTTOM = OCR2 update
sbi ddrb,3 ;output aktivieren
ldi temp0,$e0 ;zum Clr/Set muss OCR2-Register beachtet werden um
out OCR2,temp0 ;____--- oder _------ zu erreichen
sts OCR2s,temp0
in temp0,TIMSK
ori temp0,(1<<OCIE2|0<<TOIE2);OutputCompareInterrupt deaktiviert
out TIMSK,temp0
ldi temp0,(1<<WGM21|1<<WGM20|1<<COM21|0<<COM20) ;zum Toggeln COM2x Einstellungen beachten!!!!!!!!!
out TCCR2,temp0
ret
prescaler_T2_on:
in temp0,TCCR2
ori temp0,(1<<CS22|1<<CS21|0<<CS20) ;schmeißt den counter an
out TCCR2,temp0
sei
ret
prescaler_T2_off:
in temp0,TCCR2
andi temp0,(0<<CS22|0<<CS21|0<<CS20) ;stoppt den counter an
out TCCR2,temp0
ret
T2_clr: clr temp0
out TCNT2,temp0
ret
INT_OC2: ;$0003
push temp1
lds temp1,ocr2s
out ocr2,temp1
pop temp1
reti
INT_OVF2: ;$0004
reti
uart_std.asm
;************************Unterprogramme*********** *******************
tx: rcall wait150ms
ldi temp1,'T'
rcall data_transmit ;sende T
ldi temp1,'S'
rcall data_transmit ;sende S
ldi temp1,'T'
rcall data_transmit ;sende T
ret
tx_DB: ldi zh,high(Out0_rs*2)
ldi zl,low(Out0_rs*2)
rcall txt_out_rs
ret
rx: rcall data_received ;warte auf daten von PC
cpi temp1,' ' ;vergleich auf Leerzeichen
brne rx ;sonst wenn falsch warte weiter
ldi temp1,'*' ;
rcall data_transmit ;sende * als ack
ret
;***********************Wandlung in ASCII*****************************
txt_out_rs:
lpm temp1,z+ ;!!! muss der .db *2 genommen werden
cpi temp1,$ff ;Ende der Datenbank mit $ff gekennzeichnet
breq txt_out_rs_end
rcall data_transmit ;z.b.: ldi ZH,high(out0*2)
rjmp txt_out_rs
txt_out_rs_end:
ret
out0_rs: .db " TST ",$ff
;************************Wandlung nur Zahl(0-9) nach ASCII**********************
test_zahl:
ldi temp1,$99
rcall zahl_out_rs
ret
zahl_out_rs:
push temp1 ;sichern für 2ten teil
andi temp1,$f0 ;
swap temp1 ;
ori temp1,$30
rcall data_transmit
pop temp1 ;2ter Teil
andi temp1,$0f
ori temp1,$30
rcall data_transmit
ret
;************************uart_init mit RX interrupt**********************
usart_init:
ldi temp0,(0<<URSEL)
out UCSRC,temp0
clr temp0
out UBRRH,temp0
ldi temp0,$19 ;9600 Baud einstellen PDF S.133 table52
out UBRRL,temp0
rcall char_size8 ;8 zeichen, 1 stoppbit
ldi temp0,(0<<U2X|0<<MPCM) ;no DoubleSpeed, no MultiProzComMode
out UCSRA,temp0
sei
ret
char_size5:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|0<<UCSZ1|0<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=5bit(UCSZ2=0)
out UCSRB,temp0 ;
ret
char_size6:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|0<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=6bit(UCSZ2=0)
out UCSRB,temp0
ret
char_size7:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|0<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=7bit(UCSZ2=0)
out UCSRB,temp0 ;
ret
char_size8:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=7bit(UCSZ2=0)
out UCSRB,temp0
ret
char_size9:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|1<<UCSZ2) ;enable RX u TX <=9bit(UCSZ2=1)
out UCSRB,temp0
ret
;************************uart_deinit************** ******************
usart_all_aus:
clr temp0
out UCSRB,temp0
out UCSRC,temp0
out UBRRL,temp0
out UBRRH,temp0
ret
usart_ofln: ;wenn unterprogramme nicht
clr temp0 ;gestört werden dürfen
out UCSRB,temp0 ;nur usart offline
ret
;**********************daten_senden*************** ******************
INT_UTXC:
;siehe data_transmit;** man kann in der wartezeit andere sachen erledigen
;bis der int kommt im INT selbst könnte man ne art daten-lese-schleife implementieren
;um weitere daten zu senden die dann an temp1>>>UDR weitergegeben werden
out UDR,temp1 ; Put LSB data (r17) into buffer, tranceived data
reti
data_transmit:
sbis UCSRA,UDRE ;**
rjmp data_transmit ;**
out UDR,temp1 ; Put LSB data (r17) into buffer, tranceived data
ret
;**********************daten_empfangen (polling)**********************
INT_URXC:
in temp1,UDR ; Put data from buffer into r17, received Data
;siehe data_received;** man kann in der wartezeit andere sachen erledigen
;bis der int kommt im INT selbst könnte man ne art daten-schreib-schleife implementieren
;um weitere daten zu empfangen die dann an UDR>>>temp1 weitergegeben werden
reti
data_received:
sbis UCSRA,RXC ;**
rjmp data_received ;**
in temp1,UDR ; Put data from buffer into r17, received Data
ret
;********************DatenRegisterLeereInterrupt** *********************
INT_UDRE:
;SOLANGE dieses register leer ist wird diese routine aufgerufen
;also eigentlich immer wenn UDR=0
reti
hier mal eine kleine Bibliothek für den AtMega8, womit ich schon seit etwas längerer Zeit arbeite,
damit man nicht bei jedem Projektstart sich elendig lange wieder alles aus dem Datenblatt zusammen suchen muss
und zügiger starten kann.
getestet mit:
SW AVRStudio4.19 Build 716
HW STK500
Includes sind folgende
ADC
AnalogComparator
EEprom
Externe Interrupts
UART um rs232 aufzubauen
TimerCounter T0-T2
Die origin.asm ist die Hauptdatei.
Viel Spaß beim probieren
origin.asm
;######################################
;# Projekt: #
;# #
;# #
;# Taktfrequenz des AVR: 4 MHz #
;# #
;# CS-SOFT #
;###########################################
.include "m8def.inc" ;Atmega8
.def math1h = r8
.def math1l = r9
.def math2h = R10
.def math2l = r11
.def matherghh = r12
.def mathergh = r13
.def mathergl = r14
.def mathergll = r15
.def temp0 = r16 ;
.def temp1 = r17 ;
.def temp2 = r18
.def temp3 = r19 ;
.def temp4 = r20
.def cnt = r21
.equ ocr2s = $0063 ;für T2
.equ ocra1h = $0064 ;;;;;
.equ ocra1l = $0065 ;;;;;;;; für T1 A channel
.equ ocrb1h = $0066 ;;;;;
.equ ocrb1l = $0067 ;;;;;;;; für T1 B channel
.equ icr1xh = $0068 ;;;;;
.equ icr1xl = $0069 ;;;;;;;; für T1 ICR
.equ hadc = $006a ;adc
.equ ladc = $006b ;adc
.equ eep_adrh= $006c ;eeprom
.equ eep_adrl= $006d ;eeprom
;***************************Einsprungadressen***** ******************
.cseg
.org $0000
rjmp stack
.org $0001 ;1
rjmp INT_0
.org $0002 ;2
rjmp INT_1
.org $0003 ;3
rjmp INT_OC2
.org $0004 ;4
rjmp INT_OVF2
.org $0005 ;5
rjmp INT_ICP1
.org $0006 ;6
rjmp INT_OC1A
.org $0007 ;7
rjmp INT_OC1B
.org $0008 ;8
rjmp INT_OVF1
.org $0009 ;9
rjmp INT_OVF0
reti ;a keine SPI Routinen
.org $000b ;b
rjmp INT_URXC
.org $000c ;c
rjmp INT_UDRE
.org $000d ;d
rjmp INT_UTXC
.org $000e ;e
rjmp adc_rdy
.org $000f ;f
rjmp eeprom_rdy
.org $0010 ;10
rjmp ac_int
reti ;11 keine 2wireRoutinen
reti ;12 keine SPMRoutinen
/* so könnten die einsprungmarken der INTS auch aussehen
INT0addr
INT1addr
OC2addr
OVF2addr
ICP1addr
OC1Aaddr
OC1Baddr
OVF1addr
OVF0addr
SPIaddr
URXCaddr
UDREaddr
UTXCaddr
ADCCaddr
ERDYaddr
ACIaddr
TWIaddr
SPMRaddr
*/
;***************************Init mit allem drumdran*****************
stack: ldi temp1,high(ramend) ;Stackpointer festlegen
out sph, temp1
ldi temp1,low(ramend) ;Stackpointer festlegen
out spl, temp1
rcall sram
sbi portb,0 ;pulls aktivieren nur wenn Taster genutzt werden sollen
sbi portb,1
sbi portb,2
sbi portb,3
; rcall INIT_ext_Int01
; rcall deak_int01
; rcall mode0_t0_init
; rcall prescaler_T0_on
; rcall mode0_t1_init
; rcall prescaler_T1_on
; rcall mode0_t2_init
; rcall prescaler_T2_on
; rcall adc_header
; rcall eeprom_init ;wenn ints bevorzugt werden
; rcall adr_cnt
; rcall eeprom_write
; rcall AC_init
; rcall ac_change
rcall usart_init ;wenn INT bevorzugt dann hier aktivieren und prog erweitern
start: sbis pinb,0
rcall tx ;senden TST auf Bildschirm
sbis pinb,1
rcall tx_db ;sende " TST " auf Bildschirm aus Datenbank
sbis pinb,2
rcall test_zahl ;sende Zahl z.B. hex 99 auf Bildschirm !!!!!Keine HEX:DEZ Wandlung!!!!!!!!!!!!!!!!
sbis pinb,3
rcall rx ;warte auf Empfang von " "=$20 und schicke * zurück
nop
nop
nop
nop
nop
nop
nop
nop
rjmp start
;**********************Masterclr****************** *********************
sram: clr temp0
ldi yl,low(SRAM_START)
ldi yh,high(SRAM_START) ;Masterclr des Sram's über
sram2: st y+,temp0 ;die indirekte Adressierung
cpi yl,$70 ;bis zur zelle x=$70 löschen
brne sram2
ret
;*************************weitere*includedata***** ******************
.include "timercounter.asm"
.include "ext_ints.asm"
.include "uart_std.asm"
.include "adc_lst.asm"
.include "eeprom.asm"
.include "analogcomparator.asm"
.include "zeitschleifen.asm"
.include "mathe.asm"
;*************************ENDE******************** ******************
adc_lst.asm !!!!Änderung in start_convers!!!!!!!!!!!!!!!
/*
.equ ADC_ddr = ddrc
.equ ADC_Port = Portc
.equ ADC_Pin = PinC
.equ Chan0 = 0
.equ Chan1 = 1
.equ Chan2 = 2
.equ Chan3 = 3
.equ Chan4 = 4
.equ Chan5 = 5
*/
;******************************adc_interrupt****** ****************
adc_rdy:
in temp0,adcl ;wichtig erst low
sts ladc,temp0
in temp1,adch ;dann high lesen sonst erg müll
sts hadc,temp1
reti
;***********************adc_header**************** **********
adc_header:
rcall adc_init
rcall start_convers_int ;mit Interrupt
;rcall start_convers ;ohne Interrupt
ret
;***********************adc_init****************** ***********
adc_init:
ldi temp0,(0<<Chan5|0<<Chan4|0<<Chan3|0<<Chan2|0<<Chan1|0<<Chan0)
out ADC_ddr,temp0
ldi temp0,(0<<Chan5|0<<Chan4|0<<Chan3|0<<Chan2|0<<Chan1|0<<Chan0)
out ADC_Pin,temp0
in temp0,adcsra
ori temp0,(1<<ADEN|0<<ADSC|0<<ADFR|0<<ADIE|1<<ADPS2|0<<ADPS1|1<<ADPS0) ;
out adcsra,temp0
in temp0,admux
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX3|0<<MUX2|0<<MUX1|1<<MUX0) ;AVCC with external capacitor at AREF pin
out admux,temp0 ;+ messkanal0 (PC0) eingang
ret
;mit Interrupt
start_convers_int:
in temp0,adcsra ;wenn ADFR aktiv dann nur adc_read nötig für jeweiligen kanal
ori temp0,(0<<ADEN|1<<ADSC|0<<ADFR|1<<ADIE|1<<ADPS2|0<<ADPS1|0<<ADPS0) ;freigabe ADC Abtastrate zwischen 50Khz-200Khz Teiler=32 single mode
out adcsra,temp0 ;
sei
ret
;ohne Interrupt dann abfrage auf das bits ADSC=1?????
start_convers:
in temp0,adcsra
ori temp0,(0<<ADEN|1<<ADSC|0<<ADFR|0<<ADIE|1<<ADPS2|0<<ADPS1|1<<ADPS0);freigabe der Messung
out adcsra,temp0
start_convers2: ;;;
sbic ADCSR,ADSC ;;;;;; diese kleine routine braucht man nicht wenn man mit ints arbeitet
rjmp start_convers2 ;;;
in temp0,adcl ;wichtig erst low
in temp1,adch ;dann high lesen sonst erg müll
sts ladc,temp0
sts hadc,temp1
ret
analogcomparator.asm
;ACHTUNG man kann im simulator nicht mit PD6/7 simulieren geht nur
;wenn ACO händisch gesetzt wird ACO=1 wird auch ACI=1 um den int zu nutzen
;wenn man den int nicht nutzt ist die abfrage auf ACO
AC_init:
ldi temp0,(0<<ACD|0<<ACBG|1<<ACIE|0<<ACIC|0<<ACIS1|0<<ACIS0)
out ACSR,temp0
sei ;
ret
ac_change:
sbis ACSR,ACO
rjmp ac_change
ret
ac_int:
;wird aufgerufen wenn pd6+/pd7- pegelunterschiede feststellen
reti
eeprom.asm
;*************************************
eeprom_init:
ldi temp0,(1<<EERIE)
out EECR,temp0
sei
ret
eeprom_rdy:
;siehe eeprom_write ;** man kann in der wartezeit andere sachen erledigen
;bis der int kommt, um dann weitere daten an den eeprom zum schreiben zu senden
;nur bei eeprom schreiben möglich
reti
;Adreessierung im eeprom
adr_cnt:lds temp0,eep_adrl
inc temp0
cpi temp0,$ff
breq adr_cnt2
sts eep_adrl,temp0
ret
adr_cnt2:
clr temp0
sts eep_adrl,temp0
lds temp0,eep_adrh
inc temp0
sts eep_adrh,temp0
cpi temp0,$02
breq error_eeprom
ret
error_eeprom:
;voll
ret
EEPROM_write:
sbic EECR,EEWE ;** falls eewe im eecr noch gesetzt
rjmp EEPROM_write ;** spring zu zurück
lds r18,eep_adrh
out EEARH, r18 ;highbyte der adr
lds r17,eep_adrl
out EEARL, r17 ;lowbyte der adr
out EEDR,r16 ;zu speichernder wert
sbi EECR,EEMWE ;sperrt eeprom master write enable
sbi EECR,EEWE ;setze EEWE um eeprom zu schreiben
ret
EEPROM_read:
sbic EECR,EEWE ;falls eewe im eecr noch gesetzt
rjmp EEPROM_read ;springe zurück
lds r18,eep_adrh
out EEARH, r18 ;highbyte der adr
lds r17,eep_adrl
out EEARL, r17 ;lowbyte der adr
sbi EECR,EERE ;sperrt lesen des eeproms
in r16,EEDR ;zu lesender wert
ret
ext_ints.asm
;PD2/3 sind INT0/1
INIT_EXT_INT01:
in temp0,MCUCR
ori temp0,(1<<ISC11|1<<ISC10|1<<ISC01|1<<ISC00) ;hier INT0/1 auf steigende flanke siehe PDF KAP.13
out MCUCR,temp0
in temp0,GICR
ori temp0,(1<<INT1|1<<INT0) ;beide INTs aktiv
out GICR,temp0
sei ;global int
ret
deak_INT01:
in temp0,GICR
andi temp0,(0<<INT1|0<<INT0) ;beide INTs aktiv
out GICR,temp0
ret
INT_0: ;hier steht das programm welches ausgeführt werden soll
reti
INT_1: ;hier steht das programm welches ausgeführt werden soll
reti
timercounter.asm
;*****************************INIT-Mode 1 Timer0******************************************** ************************
mode0_t0_init:
in temp1,TIMSK
ori temp1,(1<<TOIE0)
out TIMSK,temp1
ldi temp1,$60
out TCNT0,temp1
ret
prescaler_T0_on:
in temp0,TCCR0
ori temp0,(0<<CS12|0<<CS11|1<<CS10) ;schmeißt den counter an
out TCCR0,temp0
sei
ret
prescaler_T0_off:
in temp0,TCCR0
andi temp0,(0<<CS12|0<<CS11|0<<CS10) ;stoppt den counter an
out TCCR0,temp0
ret
INT_OVF0: ;$0009
;Achtung T0 muss hier neu geladen werden und dann die eigene IDEE
reti
;******************************Init-Modes des Timers1******************************************* ********************
mode0_T1_init:;NORMAL_MODE OCR1A h:l,OCR1B h:l update ocrxH:L sofort oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<ICNC1|0<<ICES1|0<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(0<<COM1A1|0<<COM1A0|0<<COM1B1|0<<COM1B0|0<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode1_T1_init:;8bit phase correct mode OCR1A h:l,OCR1B h:l update ocrxH:L on top oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode2_T1_init:;9bit phase correct mode OCR1A h:l,OCR1B h:l update ocrxH:L on top oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode3_T1_init:;10bit phase correct mode OCR1A h:l,OCR1B h:l update ocrxH:L on top oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode4_T1_init:;CTC mode OCR1A h:l,OCR1B h:l update ocrAH:L oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(0<<COM1A1|0<<COM1A0|0<<COM1B1|0<<COM1B0|0<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode5_T1_init:;FAST PWM 8bit OCR1A h:l,OCR1B h:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode6_T1_init:;FAST PWM 9bit OCR1A h:l,OCR1B h:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode7_T1_init:;FAST PWM 10bit OCR1A h:l,OCR1B h:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(0<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode8_T1_init:;PWM,PahseFrequenzyCorrect OCR1A h:l,ICRh:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<ICES1|1<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(1<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode9_T1_init:;PWM,PahseFrequenzyCorrect OCR1A h:l,OCR1A h:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode10_T1_init:;PWM,PahseCorrect OCR1A h:l,ICRh:l update ocrxH:L on top oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(1<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode11_T1_init:;PWM,PahseCorrect OCR1A h:l,OCRah:l update ocrxH:L on top oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|0<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode12_T1_init:;CTC OCR1A h:l,ICRh:l update sofort oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(0<<COM1A1|1<<COM1A0|0<<COM1B1|1<<COM1B0|0<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(1<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode13_T1_init:;RESERVED not activated
/* ;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
*/ ret
mode14_T1_init:;FAST PWM OCR1A h:l,ICRh:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|0<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(1<<TICIE1|0<<OCIE1A|0<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
mode15_T1_init:;FAST PWM OCR1A h:l,OCRah:l update ocrxH:L on bottom oder im INT
;rcall A_ch_en ;out aktivieren
;rcall B_ch_en ;out aktivieren
;rcall A_ch_load ;Zeitwert laden
;rcall B_ch_load ;Zeitwert laden
ldi temp0,(1<<WGM13|1<<WGM12) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1B,temp0
in temp0,TCCR1A
ori temp0,(1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|1<<WGM11|1<<WGM10) ;zum Toggeln COM1xA/B Einstellungen beachten!!!!!!!!!
out TCCR1A,temp0
in temp0,TIMSK
ori temp0,(0<<TICIE1|1<<OCIE1A|1<<OCIE1B|0<<TOIE1) ;INT für ICP=off, OCIE1A=off, OCIE1B=off, OVFL=1
out TIMSK,temp0
ret
prescaler_T1_on:
in temp0,TCCR1B
ori temp0,(1<<CS12|1<<CS11|1<<CS10) ;schmeißt den counter an
out TCCR1B,temp0
sei
ret
prescaler_T1_off:
in temp0,TCCR1B
andi temp0,(0<<CS12|0<<CS11|0<<CS10) ;stoppt den counter an
out TCCR1B,temp0
ret
;**********Channel load
A_ch_load:
ldi temp0,$9c ;Toggeln oder Clr/Set aktiv muss OCR1Ah-Register beachtet werden um
sts OCRa1h,temp0 ;____--- oder _------ zu erreichen
out OCR1ah,temp0
ldi temp0,$40 ;Toggeln oder Clr/Set aktiv muss OCR1Al-Register beachtet werden um
sts OCRa1l,temp0 ;____--- oder _------ zu erreichen
out OCR1al,temp0
ret
A_ch_en:sbi ddrb,1 ;output aktivieren wenn Toggeln am PINB1=OCR1A erwünscht
ret
A_ch_dis:
cbi ddrb,1 ;output deaktivieren wenn Toggeln am PINB1=OCR1A erwünscht
ret
B_ch_load:
ldi temp0,$00 ;Toggeln oder Clr/Set aktiv muss OCR1Bh-Register beachtet werden um
sts OCRb1h,temp0 ;____--- oder _------ zu erreichen
out OCR1bh,temp0
ldi temp0,$80 ;Toggeln oder Clr/Set aktiv muss OCR1Bl-Register beachtet werden um
sts OCRb1l,temp0 ;____--- oder _------ zu erreichen
out OCR1bh,temp0
ret
B_ch_en:sbi ddrb,2 ;output aktivieren wenn Toggeln am PINB1=OCR1A erwünscht
ret
B_ch_dis:
cbi ddrb,2 ;output deaktivieren wenn Toggeln am PINB1=OCR1A erwünscht
ret
T1_clr:
clr temp0
out TCNT1h,temp0
out TCNT1l,temp0
ret
;**********ISR
INT_ICP1: ;$0005 Timer/Counter1 Capture Event
;ICRH:L wird vom Counter TVCNT1H:L bei Steigender/Fallender Flanke beschrieben
reti
INT_OC1A: ;$0006 Timer/Counter1 Compare Match A
set
;push temp0
;lds temp0,OCRa1h ;Toggeln oder Clr/Set aktiv muss OCR1Ah-Register beachtet werden um
;out OCR1Ah,temp0 ;____--- oder _------ zu erreichen
;lds temp0,OCRa1l ;Toggeln oder Clr/Set aktiv muss OCR1Al-Register beachtet werden um
;out OCR1Al,temp0 ;____--- oder _------ zu erreichen
;pop temp0
reti
INT_OC1B: ;$0007 Timer/Counter1 Compare Match B
push temp0
lds temp0,OCRb1h ;Toggeln oder Clr/Set aktiv muss OCR1Bh-Register beachtet werden um
out OCR1Bh,temp0 ;____--- oder _------ zu erreichen
lds temp0,OCRb1l ;Toggeln oder Clr/Set aktiv muss OCR1Bl-Register beachtet werden um
out OCR1Bl,temp0 ;____--- oder _------ zu erreichen
pop temp0
reti
INT_OVF1: ;$0008 Timer/Counter1 Overflow
reti
;************************************************* ************************************************** ****************
;******************************Init-Modes des Timers2******************************************* ********************
mode0_T2_init:;NORMAL_MODE OCR2 update sofort oder im INT
;sbi ddrb,3 ;output aktivieren wenn Toggeln am PINB3=OCR2 erwünscht
;ldi temp0,$80 ;Toggeln oder Clr/Set aktiv muss OCR2-Register beachtet werden um
;out OCR2,temp0 ;____--- oder _------ zu erreichen
in temp0,TIMSK
ori temp0,(0<<OCIE2|1<<TOIE2) ;TimerOvfl-Int aktivieren
out TIMSK,temp0
ldi temp0,(0<<WGM21|0<<WGM20|0<<COM21|0<<COM20) ;zum Toggeln COM2x Einstellungen beachten!!!!!!!!!
out TCCR2,temp0 ;
ret
mode1_T2_init:;PWM-PhaseCorrect kein toggeln möglich nur Clear/Set, bei erreichen TOP = OCR2 update
sbi ddrb,3 ;output aktivieren
ldi temp0,$80 ;zum Clr/Set muss OCR2-Register beachtet werden um
out OCR2,temp0 ;____--- oder _------ zu erreichen
in temp0,TIMSK
ori temp0,(0<<OCIE2|0<<TOIE2);OutputCompareInterrupt deaktiviert
out TIMSK,temp0
ldi temp0,(0<<WGM21|1<<WGM20|1<<COM21|0<<COM20) ;zum Toggeln COM2x Einstellungen beachten!!!!!!!!!
out TCCR2,temp0
ret
mode2_T2_init:;CTC = nonPwm = toggeln möglich OCR2 update sofort oder im INT
sbi ddrb,3 ;output aktivieren
ldi temp0,$13 ;Toggeln oder Clr/Set aktiv muss OCR2-Register beachtet werden um
out OCR2,temp0 ;________-------- oder ____---- zu erreichen
sts OCR2s,temp0
in temp0,TIMSK
ori temp0,(1<<OCIE2|0<<TOIE2);OutputCompareInterrupt deaktiviert
out TIMSK,temp0
ldi temp0,(1<<WGM21|0<<WGM20|0<<COM21|1<<COM20) ;zum Toggeln COM2x Einstellungen beachten!!!!!!!!!
out TCCR2,temp0
ret
mode3_T2_init:;FastPWM kein toggeln möglich nur Clear/Set, bei erreichen BOTTOM = OCR2 update
sbi ddrb,3 ;output aktivieren
ldi temp0,$e0 ;zum Clr/Set muss OCR2-Register beachtet werden um
out OCR2,temp0 ;____--- oder _------ zu erreichen
sts OCR2s,temp0
in temp0,TIMSK
ori temp0,(1<<OCIE2|0<<TOIE2);OutputCompareInterrupt deaktiviert
out TIMSK,temp0
ldi temp0,(1<<WGM21|1<<WGM20|1<<COM21|0<<COM20) ;zum Toggeln COM2x Einstellungen beachten!!!!!!!!!
out TCCR2,temp0
ret
prescaler_T2_on:
in temp0,TCCR2
ori temp0,(1<<CS22|1<<CS21|0<<CS20) ;schmeißt den counter an
out TCCR2,temp0
sei
ret
prescaler_T2_off:
in temp0,TCCR2
andi temp0,(0<<CS22|0<<CS21|0<<CS20) ;stoppt den counter an
out TCCR2,temp0
ret
T2_clr: clr temp0
out TCNT2,temp0
ret
INT_OC2: ;$0003
push temp1
lds temp1,ocr2s
out ocr2,temp1
pop temp1
reti
INT_OVF2: ;$0004
reti
uart_std.asm
;************************Unterprogramme*********** *******************
tx: rcall wait150ms
ldi temp1,'T'
rcall data_transmit ;sende T
ldi temp1,'S'
rcall data_transmit ;sende S
ldi temp1,'T'
rcall data_transmit ;sende T
ret
tx_DB: ldi zh,high(Out0_rs*2)
ldi zl,low(Out0_rs*2)
rcall txt_out_rs
ret
rx: rcall data_received ;warte auf daten von PC
cpi temp1,' ' ;vergleich auf Leerzeichen
brne rx ;sonst wenn falsch warte weiter
ldi temp1,'*' ;
rcall data_transmit ;sende * als ack
ret
;***********************Wandlung in ASCII*****************************
txt_out_rs:
lpm temp1,z+ ;!!! muss der .db *2 genommen werden
cpi temp1,$ff ;Ende der Datenbank mit $ff gekennzeichnet
breq txt_out_rs_end
rcall data_transmit ;z.b.: ldi ZH,high(out0*2)
rjmp txt_out_rs
txt_out_rs_end:
ret
out0_rs: .db " TST ",$ff
;************************Wandlung nur Zahl(0-9) nach ASCII**********************
test_zahl:
ldi temp1,$99
rcall zahl_out_rs
ret
zahl_out_rs:
push temp1 ;sichern für 2ten teil
andi temp1,$f0 ;
swap temp1 ;
ori temp1,$30
rcall data_transmit
pop temp1 ;2ter Teil
andi temp1,$0f
ori temp1,$30
rcall data_transmit
ret
;************************uart_init mit RX interrupt**********************
usart_init:
ldi temp0,(0<<URSEL)
out UCSRC,temp0
clr temp0
out UBRRH,temp0
ldi temp0,$19 ;9600 Baud einstellen PDF S.133 table52
out UBRRL,temp0
rcall char_size8 ;8 zeichen, 1 stoppbit
ldi temp0,(0<<U2X|0<<MPCM) ;no DoubleSpeed, no MultiProzComMode
out UCSRA,temp0
sei
ret
char_size5:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|0<<UCSZ1|0<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=5bit(UCSZ2=0)
out UCSRB,temp0 ;
ret
char_size6:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|0<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=6bit(UCSZ2=0)
out UCSRB,temp0
ret
char_size7:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|0<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=7bit(UCSZ2=0)
out UCSRB,temp0 ;
ret
char_size8:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=7bit(UCSZ2=0)
out UCSRB,temp0
ret
char_size9:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|1<<UCSZ2) ;enable RX u TX <=9bit(UCSZ2=1)
out UCSRB,temp0
ret
;************************uart_deinit************** ******************
usart_all_aus:
clr temp0
out UCSRB,temp0
out UCSRC,temp0
out UBRRL,temp0
out UBRRH,temp0
ret
usart_ofln: ;wenn unterprogramme nicht
clr temp0 ;gestört werden dürfen
out UCSRB,temp0 ;nur usart offline
ret
;**********************daten_senden*************** ******************
INT_UTXC:
;siehe data_transmit;** man kann in der wartezeit andere sachen erledigen
;bis der int kommt im INT selbst könnte man ne art daten-lese-schleife implementieren
;um weitere daten zu senden die dann an temp1>>>UDR weitergegeben werden
out UDR,temp1 ; Put LSB data (r17) into buffer, tranceived data
reti
data_transmit:
sbis UCSRA,UDRE ;**
rjmp data_transmit ;**
out UDR,temp1 ; Put LSB data (r17) into buffer, tranceived data
ret
;**********************daten_empfangen (polling)**********************
INT_URXC:
in temp1,UDR ; Put data from buffer into r17, received Data
;siehe data_received;** man kann in der wartezeit andere sachen erledigen
;bis der int kommt im INT selbst könnte man ne art daten-schreib-schleife implementieren
;um weitere daten zu empfangen die dann an UDR>>>temp1 weitergegeben werden
reti
data_received:
sbis UCSRA,RXC ;**
rjmp data_received ;**
in temp1,UDR ; Put data from buffer into r17, received Data
ret
;********************DatenRegisterLeereInterrupt** *********************
INT_UDRE:
;SOLANGE dieses register leer ist wird diese routine aufgerufen
;also eigentlich immer wenn UDR=0
reti