-         

Ergebnis 1 bis 2 von 2

Thema: AtMega8 kleine Bibliothek

  1. #1
    Benutzer Stammmitglied Avatar von avr_racer
    Registriert seit
    01.04.2014
    Ort
    MecklenburgVorpommern
    Beiträge
    92

    AtMega8 kleine Bibliothek

    Anzeige

    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
    Code:
    ;######################################
    ;# 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!!!!!!!!!!!!!!!
    Code:
    /*
    .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
    Code:
    ;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
    Code:
    ;*************************************
    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
    Code:
    ;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
    Code:
    ;*****************************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
    Code:
    ;************************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
    Angehängte Dateien Angehängte Dateien
    Geändert von avr_racer (12.08.2017 um 13:25 Uhr) Grund: man kanns besser machen

  2. #2
    Benutzer Stammmitglied Avatar von avr_racer
    Registriert seit
    01.04.2014
    Ort
    MecklenburgVorpommern
    Beiträge
    92
    zeitschleifen.asm
    Code:
    ;************************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
    Code:
    .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
    		 dc			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
    */

Ähnliche Themen

  1. [ERLEDIGT] Mein ATMega8 hat eine kleine Output Power?
    Von Elektrobot im Forum AVR Hardwarethemen
    Antworten: 5
    Letzter Beitrag: 03.10.2012, 19:41
  2. ASURO-Bibliothek in C++ ?
    Von ehenkes im Forum Asuro
    Antworten: 3
    Letzter Beitrag: 13.06.2007, 19:34
  3. ASURO-Bibliothek
    Von Cortes im Forum Asuro
    Antworten: 6
    Letzter Beitrag: 01.08.2006, 21:24
  4. DOS - Bibliothek
    Von hacker im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 14.04.2006, 02:54
  5. datenblatt bibliothek
    Von djdune im Forum Konstruktion/CAD/Sketchup und Platinenlayout Eagle & Fritzing u.a.
    Antworten: 3
    Letzter Beitrag: 18.02.2005, 13:37

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •