-
        

Ergebnis 1 bis 5 von 5

Thema: Anfängerfrage zu einem Programm

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    07.04.2009
    Beiträge
    9

    Anfängerfrage zu einem Programm

    Anzeige

    Hi @ all,

    lese mich gerade ein und hab mein erstes kleines programm in assembler
    geschrieben. leider funzt es noch nicht. könnt ihr mir sagen was ich
    falsch mache`? habe das myavrusb board und benutze myavrdemo plus:



    Code:
    main:	ldi	r16,lo8(RAMEND)
    	out	SPL,r16
    	ldi	r16,hi8(RAMEND)
    	out	SPH,r16
    
    
    
    
    
    
    	ldi	r16,0xFF
    	out	DDRB,r16
    
    
    	ldi	r17,0x00
    	out	DDRC,r17
    
    
    
    
    loop:
    
    	ldi	r16,0x01
    	out	PORTB,r16
    	
    	in	r17,PINC
    
    
    	cp	r16,r17
    
    	breq	mainloop
    
    	rjmp	loop
    
    
    ;------------------------------------------------------------------------
    mainloop:	wdr
    	ldi	r16,0b11101111
    	out	PORTB,r16
    
    	rjmp	mainloop
    ich möchte einfach das wenn ich am portc am bit 0 eine 1 anliegt, der gesamte portb auf 1 schaltet. woran liegts?

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Was mir bei deinem Programm fehlt ist die Interrupt Vektortabelle.
    Eigentlich müsste dein Programm auch ohne funktionieren, ich würd Sie aber trotzdem immer am Anfang des Programms einfügen.

    Bei den zuweisungen für den SPL und SPH kenn ich das mit
    ldi r16,low(ramend)
    ...
    ldi r16,high(ramend)
    ...
    Ob das auch mit deinen Zuweisungen geht weiß ich nicht.

    Da Du aber keine Subroutinen verwendest sollte das auch kein Problem sein.
    Lass doch mal das Stückchen Code im Simulator vom AVR Studio laufen und guck was das passiert.

    Den WDR kannst Du Dir sparen, solange Du den Watchdog weder in der Hardware, noch in der Software aktiviert hast.

    Vor das Programm hab ich auch immer Speicherdefinitionen gemacht.
    .cseg
    .org 0x0000
    ; Programm...

    P.S. Prügel mich nicht, wenn die Syntax nich 100% stimmt, hab in Assembler schon länger nichts mehr gemacht.

  3. #3
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Aus dem "mainloop" kommt er niemals wieder raus, jedenfalls in diesem Leben.
    Wie ist das mit den Pull-Up ? Oder schaltest du auf +5V ?
    Meistens (oft) wird ja ein Pin mit dem Taster auf GND geschaltet, mit dem Internen Pull up wäre das
    Code:
       ldi   r17,0x00 
       out   DDRC,r17 
       ldi   r17,0xFF              ; alles auf "1" ----> internern Pullup 
       out   PORTC,r17
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Ich hab dein Programm ein wenig modifiziert und im Simulator getestet.
    Code:
    .include "m8def.inc"
    main:   
       ldi   r16,low(RAMEND)
       out   SPL,r16
       ldi   r16,high(RAMEND)
       out   SPH,r16
    
    
    
    
    
    
       ldi   r16,0xFF
       out   DDRB,r16
    
    
       ldi   r17,0x00
       out   DDRC,r17
    
    
    
    
    loop:
    
       ldi   r16,0x01
       out   PORTB,r16
       
       in   r17,PINC
    
    
       cp   r16,r17
    
       breq   mainloop
    
       rjmp   loop
    
    
    ;------------------------------------------------------------------------
    mainloop:   wdr
       ldi   r16,0b11101111
       out   PORTB,r16
    
       rjmp   mainloop
    Zuerst wird auf Port B der Wert 0x01 ausgegeben.
    Und zwar so lange bis der Pin C.0 High wird.
    Dann verzweigt das Programm in den Mainloop, aus dem es nie wieder zurückkommt.
    Ist noch zusätzlich ein anderer PIN des Port C aktiv bleibt das Programm in der Schleife loop:
    Was soll denn nun das Progrämmchen machen ?

    Nichts desto trotz solltest Du die beschriebenen Verbesserungen deines Programmcodes machen.
    Du möchtest ja auch mal schwierigere Sachen in Assembler basteln.
    Es sein denn es handelt sich hierbei um inline Code für einen Compiler.
    Da musst Du dann aber das Handbuch deines Compilers befragen, welche Register für Assembler nutzbar sind.
    Die Infromationen, die Du uns hier gibst sind leider etwas mager.

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    07.04.2009
    Beiträge
    9
    erstmal danke, habe es auch zum laufen gebracht. es war auch gedacht das er im mainloop bleibt. das war einfach nur ne kleine spielerei, das programm dient keinem echten zweck. dafür meine nächstes programm.

    es soll ein kettenschmierimpuls an meiner motorradkette auslösen. sprich wenn ich ca 60km fahre gibt der mikrocontroller einen schmierimpuls weiter.

    gezählt wird über einen reedkontakt am rad. ich benötige 50000 signale sprich 50000 radumdrehungen. danach soll die kette kurz schmieren und das ganze geht von vorne los. hier mal mein vorschlag:



    Code:
    ;**********************************************************
    .include "m8def.inc"	
    ;**********************************************************
    
    
    
    
    
    .org INT_VECTORS_SIZE
    
    
    .org 0x00
             	rjmp main            ; Reset Handler
    
    .org INT0addr
             	rjmp int0_handler    ; IRQ0 Handler
    
    
    
    
    .def temp = r16
    
    main:		ldi temp,low(RAMEND)	; Stackpointer initialisieren
    			out SPL,temp
    
    			ldi	temp,high(RAMEND)
    			out	SPH,temp
    			
    			ldi r18, 0
    
    			ldi r19, 0
    
    			ldi	temp,0xFF
    			out	DDRB,temp
    
    	
    			ldi r17,0x00
    			out	DDRD,r17
    
    
    			ldi temp, 0b00001111  ; INT0 und INT1 konfigurieren
      			out MCUCR, temp
     
     		    ldi temp, 0b11000000  ; INT0 und INT1 aktivieren
       			out GICR, temp
     
       			sei                   ; Interrupts allgemein aktivieren
    
    loop:		rjmp loop
    
    
    
    
    int0_handler:
    
    
    			ldi r16, 200	  ; zählt bis 200
    			inc r18 
    			cp 	r16, r18
    
    			breq step
    
    			reti
    
    
    
    reset1: 	ldi r19, 0x00         ; resetet r19	
    			
    
    
    
    reset2: 	ldi r18, 0x00		  ; resetet r18			
    			reti
    
    
    
    
    step:
    			ldi r16, 250   ; zählt bis 250
    			inc r19
    			cp r16, r19
    
    			breq schmieren
    
    			rjmp reset2
    
    
    schmieren:						; "fehlt noch"
    			
    			inc r20  			;"zählt anzahl der schmierungen"
    
    			rjmp reset1


    ich zähle das r18 auf 200 danach springt es zum "step" und resetet sich selbst. im step zählt das r19 auf 250 und wenn die erreicht sind gehts zur "schmierung" anschließend wieder von vorn (250x200 = 50000). die schmierung ansich fehlt aber noch. meint ihr das wäre so realisierbar wenn ich vor dem reedschalter noch einen A/D Wandler setze?


    gruss ralph

Berechtigungen

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