-         

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 30

Thema: Mit Assembler eine Blinkschaltung bauen

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168

    Mit Assembler eine Blinkschaltung bauen

    Anzeige

    Hallo Leute,

    ich habe vor eine Blinkschaltung mit den LEDs D15 und D16 zu schreiben.
    Auf Assemblerbassis ...
    Ist das möglich?
    Könntet ihr mir ein bisschen helfen?

    Code:
    .include "m8def.inc"
    
    LDI r16, 0b00000011 ; Hier kommt der Kommentar ... :D <-- Lade Register 16 mit 01000000
    OUT DDRC, r16		; R16 wird nach DDRD (Datenrichtungsregister!) übertragen
    OUT PORTC, r16
    
    LDI r17, 0b11100000
    OUT DDRD, r17
    
    main: RJMP main
    Für die Back-LEDs habe ich den obrigen Code benutzt ...
    Nun soll abwechselnd die eine und dann die Andere leuchten, wie mache ich das?

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    61
    Beiträge
    531
    Hallo,

    schreib dir mal so ein Program in 'C' und guck dann in die automatisch generierten assembler Tekst Dateien .lst or .lss im gleichen Verzeichnis wie die 'C' Datei.

    Eine Warteschleiffe wie
    for(i=0;i<...;i++){
    for(j=0;j<...;j++){
    }}
    ist vermutlich notwendig um genugend verzogerung zu generieren. Die verzogerung kann mann ausprobieren oder ausrechnen...

    Tip: im 'C' Datei schreib mal etwas Tekst dazu wie:
    //xyz

    da kann mann in die .lst/.lss Dateien einfach suchen auf "xyz"

    Gruss,

    Henk

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    05.07.2007
    Beiträge
    44

    Blinker

    Guten tag.

    Versuche es doch mal damit.

    MfG
    A.Hoffmann


    Code:
    .include "m8def.inc"
    .def		temp	=	r16			; Arbeitsregister
    .def		temp2	=	r17			; Arbeitsregister
    
    .equ		CLOCK	=	8000000
    
    .dseg
    
    timer_1:	.byte		1	; 8 Bit
    timer_6:	.byte		1	; milisekunden Zähler
    
    .cseg
    
    .org 0x000
    		    rjmp	Prog_Initial ;	Interruptvektoren überspringen
    			reti				;	INT0addr - Externer Interrupt 0
    			reti				;	INT1addr - Externer Interrupt 1
    			reti		  		;	OC2addr  - Output Compare2
    			reti				;	OVF2addr - Overflow2
    			reti				;	ICP1addr - Input Capture1
    			reti				;	OC1Aaddr - Output Compare1A
    			reti				;	OC1Baddr - Output Compare1B
    			reti				;	OVF1addr - Overflow1
    			rjmp	delay		;	OVF0addr - Overflow0
    			reti				;	SPIaddr  - SPI
    			reti	    		;	URXCaddr - USART Receive Complete
    			reti				;	UDREaddr - USART Data Register Empty
    			reti				;	UTXCaddr - USART Transmit Complete
    			reti				;	ADCCaddr - Analog Digital wandler
    			reti				;	ERDYaddr - EEPROM 
    			reti				;	ACIaddr  - Analog Comparator
    			reti				;	TWIaddr  - Two - Wire Interface
    			reti				;	SPMaddr  - SPM complete
    
    
    Prog_Initial:
    
    ;*********************************************************
    ;                               Stack Pointer setzen     *
    ;*********************************************************
    
    			ldi		temp,	LOW(RAMEND)		; Stack Pointer low
    			out		SPL,	temp			; setzen
    			ldi		temp,	HIGH(RAMEND)	; Stack Pointer high
    			out		SPH,	temp 			; setzen
    
    ;********************************************************
    ;*                        Init  Timer / Counter 0       *
    ;********************************************************
    
    ;Preclaer Divisions Factor = 64
    
    			ldi		temp,	131			; Counter = (256 - 125)	
    			out		TCNT0,	temp ; nach 125 Takten erfolgt ein Überlauf
    			ldi		temp,	0b00000011	; CS00 + CS01 = 1	
    			out		TCCR0,	temp		; Prescaler Division = 64
    			in		temp,	TIMSK
    			ori		temp,	0b00000001	; Interrupt
    			out		TIMSK,	temp		; erlauben
    
    ;*********************************************************
    ;*                           Init LEDs                   *
    ;*********************************************************
    
    			sbi		DDRB,	DDB0		; Duo LED grün
    			sbi		DDRD,	DDD2		; Duo LED rot
    			cbi		PORTB,	PORTB0		; aus
    			cbi		PORTD,	PORTD2		; schalten
    			sbi		DDRD,	DDD6		; Front LED
    			cbi		PORTD,	PORTD6		; aus
    			sbi		DDRD,	DDD7		; Back LEDs
    			cbi		PORTD,	PORTD7		
    			sbi		DDRC,	DDC0
    			sbi		DDRC,	DDC1
    			cbi		PORTC,	PORTC1
    			cbi		PORTC,	PORTC1		; ausschalten
    			ldi		temp,	0x00
    			sts		timer_1,		temp	; max
    			sts		timer_6,		temp	; max 255 mili Sekunden
    
    
    			sei							; Interrupts erlauben
    			
    
    
    ;****************   Ende Init  ****************************	
    				  						
    Prog_Run:
    loop:
    			rcall	back_led_l_on;
    			rcall	back_led_r_on;
    			ldi		temp2,	1		; 1 sekunde nichts tun
    			rcall	wait_timer_1
    			rcall	back_led_l_off
    			rcall	back_led_r_off
    			ldi		temp2,	1		; 1 sekunde nichts tun
    			rcall	wait_timer_1
    
    			rjmp	loop
    
    
    ;*********************************************************
    ;*                  Interrupt Routine für Timer 0        *
    ;*********************************************************
    delay:		
    			push	ZH
    			push	ZL
    			push	temp2
    			push	temp
    			in		temp,	SREG
    			push	temp			; sichern
    			lds		temp,	timer_6	; Milisekunenden
    			inc		temp			; Zähler
    			sts		timer_6,	temp ; + 1
    			adiw	r25:r24,	1	; Counter + 1
    			ldi		temp,	 	0xE8 ;0xE8	; 0x03E8 = 1000
    			ldi		temp2,		0x03 ;0x03
    			cp		r24,	temp	; Counter Low / 16 Bit compare
    			cpc		r25,	temp2	; Counter High 
    			brne	next_step		; noch keine Sekunde vergangen
    			lds		temp,	timer_1	; erhöhe die Sekunden Zähler um 1
    			inc		temp
    			sts		timer_1,		temp
    			ldi		r24,	0
    			ldi		r25,	0
    
    next_step:
    			ldi		temp,	131		; Counter Register
    			out		TCNT0,	temp	; neu Vorbelegen							
    			pop		temp			; Register
    			out		SREG,	temp
    			pop		temp
    			pop		temp2
    			pop		ZL
    			pop		ZH				; wieder herstellen
    			reti
    			
    ;********************************************************
    ;*                Hintere LED rechts Ein                *
    ;********************************************************
    back_led_r_on:
    			sbi		DDRD,	DDD7		
    			cbi		PORTD,	PORTD7		
    			sbi		DDRC,	PORTC0
    			sbi		PORTC,	PORTC0
    			ret
    
    ;*******************************************************
    ;*                Hintere LED rechts Aus               *
    ;*******************************************************
    back_led_r_off:
    			cbi		PORTC,	PORTC0
    			ret
    
    ;******************************************************
    ;*                          Hintere LED links Ein     *
    ;******************************************************
    back_led_l_on:
    			sbi		DDRD,	DDD7		
    			cbi		PORTD,	PORTD7		
    			sbi		DDRC,	PORTC1
    			sbi		PORTC,	PORTC1
    			ret
    
    ;******************************************************
    ;*                       Hintere LED links Aus        *                        
    ;******************************************************
    back_led_l_off:
    			cbi		PORTC,	PORTC1
    			ret
    
    
    ;***************************************************************
    ;*                warten auf timer_1                  		   *
    ;*   in temp2 wird die  Verzögerungs Zeit in Sekunden übergeben*
    ;***************************************************************
    
    wait_timer_1:
    			push	temp2					; Register
    			push	temp
    			in		temp,	SREG
    			push	temp					; sichern
    			ldi		temp,	0x00			; timer_1	
    			sts		timer_1,		temp	; auf Null setzen
    w_t_1:
    			lds		temp,	timer_1
    			cp		temp,	temp2			; timer_1 => temp2
    			brsh	ret_t_1							; ja
    			rjmp	w_t_1		
    ret_t_1:
    			pop		temp			; Register
    			out		SREG,	temp
    			pop		temp
    			pop		temp2			; wieder herstellen
    			ret
    
    
    
    ;******************************************************************************
    ;*                warten auf timer_6                 						  *
    ;*   in temp2 wird die  Verzögerungs Zeit in mili Sekunden übergeben          *
    ;******************************************************************************
    wait_timer_6:
    			push	temp2					; Register
    			push	temp
    			in		temp,	SREG
    			push	temp					; sichern
    			ldi		temp,	0x00			; timer_6	
    			sts		timer_6,		temp	; auf Null setzen
    w_t_6:
    			lds		temp,	timer_6
    			cp		temp,	temp2			; timer_6 => temp2
    			brsh	ret_t_6					; ja
    			rjmp	w_t_6		
    ret_t_6:
    			pop		temp					; Register
    			out		SREG,	temp
    			pop		temp
    			pop		temp2					; wieder herstellen
    			ret

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168
    Ja das funktioniert!
    Danke ...

    Aber wie kann ich die Geschwindigkeit des Blinkens ändern?
    Und Sie haben so viel geschrieben!
    Wann kommen die anderen LEDs dran?

    EDIT:

    Mich würde einfach nur noch interessieren, wie ich den Timer schneller machen kann ...

  5. #5
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Jena
    Alter
    31
    Beiträge
    3.912
    der timer wird schneller durch einen kleineren prescaler...
    hast du dich schonmal mit assembler beschäftigt?
    kleinschreibung ist cool!

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168
    Ich bin am lernen ...

    Ich habe nun einfach folgendes gemacht:
    Code:
    ldi      temp2,      0x00 ;0x03
    Und dann geht es auch schneller!
    Wo genau stelle ich den Prescaler ein?

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    05.07.2007
    Beiträge
    44
    Gute tag zusammen.

    Um die Blinkdauer zu verändern gibt es zwei Routinen in dem Programm.
    wait_timer_1 ist ein 8 Bit Sekunden Zähler.
    Also
    ldi temp2, Verzöerungszeit in Sekunden ( max 255 )
    rcall wait_timer_1 ; warten

    oder den Timer

    wait_timer_6
    8 Bit milisekunden Zähler

    ldi temp2, milisekunden ( max 255 )
    rcall wait_timer_6 ; warten


    Mfg
    A.Hoffmann

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    05.07.2007
    Beiträge
    44

    Blinkschaltung mit Assembler und ASURO

    Hallo
    Hier eine Programmversion, die alle LEDs des ASURO ansteuert.
    Code:
    .include "m8def.inc"
    .def	temp	=	r16		; Arbeitsregister
    .def	temp2	=	r17		; Arbeitsregister
    
    .equ	CLOCK	=	8000000
    
    .dseg
    
    timer_1: .byte		1	; 8 Bit Sekunden Zähler
    timer_6: .byte		1	; 8 Bit milisekunden Zähler
    
    .cseg
    
    .org 0x000
     rjmp	Prog_Initial ;Interruptvektoren überspringen
     reti			;INT0addr - Externer Interrupt 0
     reti			;INT1addr - Externer Interrupt 1
     reti		  	;OC2addr  - Output Compare2
     reti			;OVF2addr - Overflow2
     reti			;ICP1addr - Input Capture1
     reti			;OC1Aaddr - Output Compare1A
     reti			;OC1Baddr - Output Compare1B
     reti			;OVF1addr - Overflow1
     rjmp	delay	;OVF0addr - Overflow0
     reti			;SPIaddr  - SPI
     reti	    	;URXCaddr - USART Receive Complete
     reti			;UDREaddr - USART Data Register Empty
     reti			;UTXCaddr - USART Transmit Complete
     reti			;ADCCaddr - Analog Digital wandler
     reti			;ERDYaddr - EEPROM 
     reti			;ACIaddr  - Analog Comparator
     reti			;TWIaddr  - Two - Wire Interface
     reti			;SPMaddr  - SPM complete
    
    
    Prog_Initial:
    
    ;*********************************************
    ;                   Stack Pointer setzen     *
    ;*********************************************
    
     ldi	temp,	LOW(RAMEND)	; Stack Pointer low
     out	SPL,	temp		; setzen
     ldi	temp,	HIGH(RAMEND) ; Stack Pointer high
     out	SPH,	temp 		; setzen
    
    ;********************************************
    ;*            Init  Timer / Counter 0       *
    ;********************************************
    
    ;Preclaer Divisions Factor = 64
    
     ldi	temp,	131			; Counter = (256 - 125)	
     out	TCNT0,	temp ;125 Takten erfolgt ein Überlauf
     ldi	temp,	0b00000011	; CS00 + CS01 = 1	
     out	TCCR0,	temp		; Prescaler Division = 64
     in		temp,	TIMSK
     ori	temp,	0b00000001	; Interrupt
     out	TIMSK,	temp		; erlauben
    
    ;**********************************************
    ;*                   Init LEDs                *
    ;**********************************************
    
     sbi		DDRB,	DDB0		; Duo LED grün
     sbi		DDRD,	DDD2		; Duo LED rot
     cbi		PORTB,	PORTB0		; aus
     cbi		PORTD,	PORTD2		; schalten
     sbi		DDRD,	DDD6		; Front LED
     cbi		PORTD,	PORTD6		; aus
     sbi		DDRD,	DDD7		; Back LEDs
     cbi		PORTD,	PORTD7		
     sbi		DDRC,	DDC0
     sbi		DDRC,	DDC1
     cbi		PORTC,	PORTC1
     cbi		PORTC,	PORTC1		; ausschalten
     ldi		temp,	0x00
     sts		timer_1,	temp	; max
     sts		timer_6,	temp	; max 255 mili Sekunden
    
    
     sei							; Interrupts erlauben
    			
    
    
    ;****************   Ende Init  **********
    				  						
    Prog_Run:
    loop:
     rcall	back_led_r_on
     ldi		temp2,	1	; 1 sekunde nichts tun
     rcall	wait_timer_1
     rcall	back_led_r_off
     rcall	back_led_l_on
     ldi		temp2,	1	; 1 sekunde nichts tun
     rcall	wait_timer_1
     rcall	back_led_l_off
     rcall	front_led_on
     ldi		temp2,	1	; 1 sekunde nichts tun
     rcall	wait_timer_1
     rcall	front_led_off
     rcall	gruen_ein
     ldi		temp2,	1	; 1 sekunde nichts tun
     rcall	wait_timer_1
     rcall	rot_ein
     ldi		temp2,	1	; 1 sekunde nichts tun
     rcall	wait_timer_1
     rcall	gelb_ein
     ldi		temp2,	1	; 1 sekunde nichts tun
     rcall	wait_timer_1
     rcall	duo_led_aus
     rjmp	loop
    
    ;*****************************************************
    ;*                  Interrupt Routine für Timer 0    * 
    ;*****************************************************
    delay:		
     push	ZH
     push	ZL
     push	temp2
     push	temp
     in		temp,	SREG
     push	temp			; sichern
     lds	temp,	timer_6	; Milisekunenden
     inc	temp			; Zähler
     sts	timer_6,	temp ; + 1
     adiw	r25:r24,	1	; Counter + 1
     ldi	temp,	 	0xE8 ;0xE8	; 0x03E8 = 1000
     ldi	temp2,		0x03 ;0x03
     cp		r24,	temp	; Counter Low / 16 Bit compare
     cpc	r25,	temp2	; Counter High 
     brne	next_step ; noch keine Sekunde vergangen
     lds	temp,	timer_1	; erhöhe die Sekunden Zähler um 1
     inc	temp
     sts	timer_1,		temp
     ldi	r24,	0
     ldi	r25,	0
    
    next_step:
     ldi	temp,	131		; Counter Register
     out	TCNT0,	temp	; neu Vorbelegen							
     pop	temp			; Register
     out	SREG,	temp
     pop	temp
     pop	temp2
     pop	ZL
     pop	ZH				; wieder herstellen
     reti
    			
    ;********************************************
    ;*                Hintere LED rechts Ein    *         
    ;********************************************
    back_led_r_on:
    		sbi		DDRD,	DDD7		
    		cbi		PORTD,	PORTD7		
    		sbi		DDRC,	PORTC0
    		sbi		PORTC,	PORTC0
    		ret
    
    ;*******************************************
    ;*                Hintere LED rechts Aus   *
    ;*******************************************
    back_led_r_off:
    		cbi		PORTC,	PORTC0
    		ret
    
    ;*******************************************
    ;*               Hintere LED links Ein     *
    ;*******************************************
    back_led_l_on:
    		sbi		DDRD,	DDD7		
    		cbi		PORTD,	PORTD7		
    		sbi		DDRC,	PORTC1
    		sbi		PORTC,	PORTC1
    		ret
    
    ;*******************************************
    ;*            Hintere LED links Aus        *                        
    ;*******************************************
    back_led_l_off:
    		cbi		PORTC,	PORTC1
    		ret
    
    
    
    ;******************************************
    ;*                  DUO LED grün ein      *
    ;******************************************
    gruen_ein:
    		sbi		PORTB,	PORTB0
    		cbi		PORTD,	PORTD2
    		ret
    
    ;******************************************
    ;*         UO LED rot ein                 *
    ;******************************************
    rot_ein:
    		cbi		PORTB,	PORTB0
    		sbi		PORTD,	PORTD2
    		ret
    
    ;******************************************
    ;*            DUO LED gelb ein            *
    ;******************************************
    gelb_ein:
    		sbi		PORTB,	PORTB0
    		sbi		PORTD,	PORTD2
    		ret
    
    ;******************************************
    ;*                          DUO LED Aus   *
    ;******************************************
    duo_led_aus:
    		cbi		PORTB,	PORTB0
    		cbi		PORTD,	PORTD2
    		ret
    
    ;******************************************
    ;*                     Front LED Ein      *
    ;******************************************
    front_led_on:
    		sbi		PORTD,	PORTD6
    		ret
    			
    ;******************************************
    ;*          Front LED Aus                 *
    ;******************************************
    front_led_off:
    		cbi		PORTD,	PORTD6
    		ret
    
    
    
    ;******************************************
    ;*                warten auf timer_1       
    ;*temp2  Zeit in Sekunden übergeben       *
    ;******************************************
    
    wait_timer_1:
     push	temp2				; Register
     push	temp
     in		temp,	SREG
     push	temp				; sichern
     ldi		temp,	0x00	; timer_1	
     sts		timer_1, temp ;auf Null setzen
    w_t_1:
     lds		temp,	timer_1
     cp		temp,	temp2	; timer_1 => temp2
     brsh	ret_t_1			; ja
     rjmp	w_t_1		
    ret_t_1:
     pop		temp			; Register
     out		SREG,	temp
     pop		temp
     pop		temp2		; wieder herstellen
     ret
    
    
    
    ;***********************************************
    ;*                warten auf timer_6           *
    ;*temp2  Zeit in mili Sekunden übergeben       *
    ;***********************************************
    wait_timer_6:
     push	temp2 ; Register
     push	temp
     in		temp,	SREG
     push	temp  ; sichern
     ldi		temp,	0x00 ; timer_6	
     sts		timer_6, temp ; auf Null setzen
    w_t_6:
     lds		temp,	timer_6
     cp		temp,	temp2 ;timer_6 => temp2
     brsh	ret_t_6				; ja
     rjmp	w_t_6		
    ret_t_6:
     pop		temp	; Register
     out		SREG,	temp
     pop		temp
     pop		temp2	; wieder herstellen
     ret
    MfG
    A.Hoffmann

  9. #9
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Jena
    Alter
    31
    Beiträge
    3.912
    hab mal die quote-tags in deinem beitrag durch code-tags ersetzt... quote=zitat, code=codebox. =)
    kleinschreibung ist cool!

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    05.07.2007
    Beiträge
    44
    Hallo damaltor
    Danke. Ich habe das in der Eile ganz übersehen.

    MfG
    A.Hoffmann

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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