PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ASM AtMega8 kleine Bibliothek



avr_racer
01.04.2014, 18: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

avr_racer
19.10.2014, 20:15
zeitschleifen.asm


;************************zeitschleifen************ ******************************
wait1us:nop
ret

wait6us:
ldi temp0,$06
wait6us1:
dec temp0
brne wait6us1
ret

wait9us:
ldi temp0,$0a
wait9us1:
dec temp0
brne wait9us1
ret

wait10us:
ldi temp0,$0c
wait10us1:
dec temp0
brne wait10us1
ret


wait25us:
ldi temp4,$20
wait25us1:
dec temp4
brne wait25us1
ret

wait50us:
ldi temp4,$41
wait50us1:
dec temp4
brne wait50us1
ret

wait55us:
ldi temp0,$41
wait55us1:
dec temp0
brne wait55us1
ret

wait58us:
ldi temp4,$4c
wait58us1:
dec temp4
brne wait58us1
ret

wait60us:
ldi temp0,$4e
wait60us1:
dec temp0
brne wait60us1
ret

wait64us:
ldi temp0,$54
wait64us1:
dec temp0
brne wait64us1
ret

wait70us:
ldi temp0,$5a
nop
wait70us1:
dec temp0
brne wait70us1
nop
nop
ret

wait100us:
ldi temp4,$83
wait100us1:
dec temp4
brne wait100us1
ret

wait500us:
ldi temp1,$03
wait500us1:
ldi temp0,$dd
wait500us2:
dec temp0
brne wait500us2
dec temp1
brne wait500us1
ret

wait1ms:ldi temp3,$06
wait1ms1:
ldi temp4,$df
wait1ms2:
dec temp4
brne wait1ms2
dec temp3
brne wait1ms1
ret

wait10ms:ldi temp3,$60
wait10ms1:
ldi temp4,$df
wait10ms2:
dec temp4
brne wait10ms2
dec temp3
brne wait10ms1
ret

waitxms: rcall wait1ms
dec temp0
brne waitxms
ret

wait150ms:
ldi temp0,$96
rjmp waitxms

wait750ms:
ldi temp1,$08
wait750ms1:
ldi temp2,$63
wait750ms2:
rcall wait1ms
dec temp2
brne wait750ms2
dec temp1
brne wait750ms1
ret

wait1s: ldi temp1,$0a
wait1s1: ldi temp2,$63
wait1s2: rcall wait1ms
dec temp2
brne wait1s2
dec temp1
brne wait1s1
ret




mathe.asm


.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 cnt = r21

;**********SRAM
.equ erg_k = $0060 ;erg_k wird bis zu 5 weiteren bytes genutzt sprich erg_k+5

rcall load_math_word ;hier werden die Zahlen aus dem SRAM geladen die +, -, x, / werden sollen

rcall add_2_16bit ;16bit + 16bit = 17bit nutzt 3Byte
;rcall sub_2_16bit ;16bit - 16bit = <16bit
;rcall smul_2_16bit ;16bit x 16bit = 32bit nutzt 4Byte für AVR's ohne mul-Befehl
;rcall hmul_2_16bit ;16bit x 16bit = 32bit nutzt 4Byte für AVR's mit mul-Befehl
;rcall sdiv_2_16bit ;16bit / 16bit = <16bit nur Software da kein DIV-Befehl vorhanden

rcall load_hex_dez ;zu wandelnde Werte in in X und Z Pointer laden z.B FF Hex = 255 Dez laden
rcall hex_dez ;Werte stehen als Byte bereit ohne ASCII Convertierung Wandlung Byte 1 2 3 4 5
00 00 00 02 55
*/

load_math_word:
lds temp0,$0070
mov math1h,temp0
lds temp0,$0071
mov math1l,temp0

lds temp0,$0072
mov math2h,temp0
lds temp0,$0073
mov math2l,temp0
ret

;*********Addition 16bit + 16bit Vorzeichenlos
;math2h:math2l + math1h:math1l = matherhh:mathergh:mathergl:mathergll
; r10:r11 r8:r9 = r12 : r13 : r14
add_2_16bit:
rcall clr_erg
add math2l,math1l ;mathxl lowbytes adden
adc math2h,math1h ;mathxlh highbytes adden + Carry
brcc add_2_16bit_2 ;wenn Carry gesetzt
adc mathergh,yl ;dann ins 3te Ergbyte speichern quasi Überlauf
add_2_16bit_2:
mov mathergl,math2h ;in ergreg schubsen
mov mathergll,math2l
ret

;*********Subtraktion 16bit - 16bit mit Vorzeichenanzeige
;math2h:math2l - math1h:math1l = matherhh:mathergh:mathergl:mathergll
; r10:r11 r8:r9 = r12 : r13 : r14 : r15
sub_2_16bit:
ldi yl,'+'
sts erg_k+5,yl ;grundsätzlich erstmal plus
rcall clr_erg
sub math2l,math1l ;mathxl lowbytes suben
sbc math2h,math1h ;mathxlh highbytes suben - Carry
brcc sub_2_16bit_2 ;wenn Carry gesetzt
sbc mathergh,yl ;dann ins 3te Ergbyte speichern quasi Unterlauf
com mathergh ;da minus einerkomplement macht aus ff=00
com math2h ;da minus einerkomplement macht aus ff=00
neg math2l ;da minus zweierkomplement macht aus ff=01
ldi yl,'-'
sts erg_k+5,yl ;zeigt an, das dass ERG negativ ist
sub_2_16bit_2:
mov mathergl,math2h ;in ergreg schubsen
mov mathergll,math2l
ret

;*********Multiplikation 16bit * 16bit Vorzeichenlos Software
;math1h:math1l * math2h:math2l = matherhh:mathergh:mathergl:mathergll
; r8:r9 r10:r11 = r12 : r13 : r14 : r15
smul_2_16bit:
rcall clr_erg ;löschen
ldi cnt,$10 ;16bit zum multiplzieren
smul_2_16bit2:
lsl mathergll ;bei jedem Durchgang erg x 2
rol mathergl
rol mathergh
rol matherghh

lsl math1l ;Multiplikant
rol math1h
brcc smul_2_16bit4 ;C = 0 ?
rcall smul_add_erg_16bit ;wenn nicht dann addieren
smul_2_16bit4:
dec cnt ;bitcnt -1
brne smul_2_16bit2 ;sprung zu Label
ret

smul_add_erg_16bit:
add mathergll,math2l ;Multiplikator zum Zwischenergebniss
adc mathergl,math2h ;dazuaddieren
adc mathergh,yl
adc matherghh,yl
ret

;*********Multiplikation 16bit * 16bit Vorzeichenlos HARDWARE
;math2h:math2l * math1h:math1l = matherhh:mathergh:mathergl:mathergll
; r10:r11 r8:r9 = r12 : r13 : r14 : r15
hmul_2_16bit:
rcall clr_erg ;löschen
mul math1l,math2l ;multiplizieren
add mathergll,r0 ;
adc mathergl,r1 ;Ergebnisse addieren

mul math1l,math2h ;multiplizieren
add mathergl,r0
adc mathergh,r1 ;Ergebnisse addieren

mul math1h,math2l ;multiplizieren
add mathergl,r0
adc mathergh,r1 ;Ergebnisse addieren
adc matherghh,yh

mul math1h,math2h ;multiplizieren
add mathergh,r0
adc matherghh,r1 ;Ergebnisse addieren

r et

;*********Division 16bit / 16bit Vorzeichenlos
;math1h:math1l / math2h:math2l = matherhh:mathergh:mathergl:mathergll
; r8:r9 r10:r11 = r12 : r13 : r14 : r15
sdiv_2_16bit:
rcall clr_erg ;Ergreg löschen
cp math2l,yl
cpc math2h,yh
breq sdiv_2_16bit4
ldi cnt,$10 ;bitcnt
mov yl,math1l ;Divident in Y-Pointer schieben
mov yh,math1h ;
sdiv_2_16bit1:
lsl yl ;pro Durchgang x2
rol yh ;links shiften
rol mathergll ;Restbildung
rol mathergl ;
cp mathergll,math2l ;
cpc mathergl,math2h ;
brcs sdiv_2_16bit3 ;Rest < DIVISOR
sdiv_2_16bit2:
adiw yh:yl,$01 ;Ergebniss +1
sub mathergll,math2l ;
sbc mathergl,math2h ;
sdiv_2_16bit3:
dec cnt
brne sdiv_2_16bit1
sdiv_2_16bit4:
push mathergl ;wieder tauschen
push mathergll ;das alles in den ErgRegs steht
mov mathergll,yl ;
mov mathergl,yh ;
pop yl ;hier steht der Rest diesen *10, dann wieder teilen = Kommastellen
pop yh ;oder Divident *10,100,1000 usw dann teilen Kommastellen vorgezogen
ret

;original AtmelRoutine
div_2_16bit:
rcall clr_erg ;ergreg löschen
cp math2l,yl
cpc math2h,yh ;vergleich Divisor
breq div_2_16bit6 ;= 0 sprung
l di cnt,$11
clc
div_2_16bit2:
rol math1l
rol math1h ;DIVIDENT Teilender
dec cnt
brne div_2_16bit3
rjmp div_2_16bit5
div_2_16bit3:
rol mathergll ;RESTbildung
rol mathergl
sub mathergll,math2l ;Erg minus DIVISOR Teiler
sbc mathergl,math2h ;
brcc div_2_16bit4 ;
add mathergll,math2l ;Erg + DIVISOR
adc mathergl,math2h ;rückgängig machen
clc ;Carry löschen
rjmp div_2_16bit2 ;sprung zu Label
div_2_16bit4:
sec ;Carry setzen
rjmp div_2_16bit2 ;sprung zu Label
div_2_16bit5:
push mathergl
push mathergll ;Rest puschen
mov mathergll,math1l ;alles so drehen
mov mathergl,math1h ;das es in den ErgRegs steht
pop yl ;Rest popen
pop yh
div_2_16bit6:
ret

;***************Ergebnissregister löschen************
clr_erg: clr yl ;löschen
clr yh
clr matherghh
clr mathergh
clr mathergl
clr mathergll
ret
/*
;**********Wandlungsvorbereitung von HEX in DEZ******
load_hex_dez:
mov zh,matherghh ;highhigh
mov zl,mathergh ;highlow
mov xh,mathergl ;high
mov xl,mathergll ;low
ret

hex_dez: ;lds zh ;wenn ZH=ff>>LCD=42949967295
;lds zl ;wenn ZL=ff>>LCD=16777215 bei ZH=0
;lds xh, ;wenn XH=ff>>LCD=65535 bei ZH:ZL=0
;lds xl, ;wenn xl=ff>>LCD=255, bei XH=0
push yl
push yh
push xl
push xh
push zl
push zh
rcall load_Ypontr ;Speicherbereich laden
ldi cnt,$ff ;
num_1000000000: ;Milliarden
inc cnt
subi xh, byte2(1000000000)
sbci zl, byte3(1000000000)
sbci zh, byte4(1000000000)
brcc num_1000000000
swap cnt
st y,cnt
ldi cnt,$0a
num_100000000: ;100Millionen
dec cnt ;+1
subi xh, byte2(-100000000)
sbci zl, byte3(-100000000)
sbci zh, byte4(-100000000)
brcs num_100000000 ;ja
ld temp0,y
or cnt,temp0
st y+,cnt ;fertig speichern
ldi cnt,$ff ;
num_10000000: ;10Millionen
inc cnt
subi xl, byte1(10000000)
sbci xh, byte2(10000000)
sbci zl, byte3(10000000)
sbci zh, 0
brcc num_10000000
swap cnt
st y,cnt
ldi cnt,$0a
num_1000000: ;1Million
dec cnt ;+1
subi xl, byte1(-1000000) ;
sbci xh, byte2(-1000000) ;vergleich auf >1000000
sbci zl, byte3(-1000000)
brcs num_1000000 ;ja
ld temp0,y
or cnt,temp0
st y+,cnt ;fertig speichernn
ldi cnt,$ff ;
num_100000: ;100Tausend
inc cnt
subi xl, byte1(100000)
sbci xh, byte2(100000)
sbci zl, byte3(100000)
brcc num_100000
swap cnt
st y,cnt
ldi cnt,$0a
num_10000: ;10Tausend
dec cnt ;+1
subi xl, byte1(-10000) ;
sbci xh, byte2(-10000) ;vergleich auf >10000
sbci zl, byte3(-10000)
brcs num_10000 ;ja
ld temp0,y
or cnt,temp0
st y+,cnt ;fertig speichern
ldi cnt,$ff
num_1000: ;Tausender
inc cnt
subi xl, low(1000)
sbci xh, high(1000)
brcc num_1000
swap cnt
st y,cnt
ldi cnt,$0a
num_100: dec cnt ;100
subi xl, low(-100)
sbci xh, high(-100)
brcs num_100
ld temp0,y
or cnt,temp0
st y+,cnt
ldi cnt,$ff
num_10: inc cnt ;Zehner + Einer
subi xl, 10
brcc num_10
subi xl, -10
swap cnt
or cnt,xl
st y+,cnt
pop zh
pop zl
pop xh
pop xl
pop yh
pop yl
ret

load_Ypontr:
ldi yh,high(erg_k)
ldi yl,low(erg_k) ;speicherpunkt laden
ret
*/