PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Motor langsam anfahren lassen ...



H3llGhost
07.01.2008, 21:51
Hallo Leute,

ich habe folgenden Code:



.include "m8def.inc"

;31248 1 Sek
.EQU TIME05 = 65536 - 15624 ; 0,5 Sekunden
.EQU TIME2 = 65536 - 62496 ; zwei Sekunde
.EQU TIME1 = 65536 - 31248 ; eine Sekunde

.def temp = r16
.def speed = r21
.def updown = r22

.org 0x0000
rjmp start
.org OVF0addr ;Interrupt-handler für 8 Bit Timer0
rjmp interrupt


start:
ldi updown, 0b00000000

ldi r20,HIGH(TIME2) ;Trick, um Timer0 auf 16 Bit zu erweitern
ldi temp,LOW(TIME2) ;Starwert Timer
out TCNT0,temp
ldi temp,(1<<CS02|1<<CS00) ;Prescaler Systemtakt/1024
out TCCR0,temp
ldi temp,(1<<TOIE0) ;Timer Interrupt über TOV0 erlauben
out TIMSK,temp ; "

ldi temp, (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1)
out TCCR1A, temp
ldi temp, (1 << CS11)
out TCCR1B, temp

ldi speed,0
out OCR1BH, speed
out OCR1BL, speed
out OCR1AH, speed
out OCR1AL, speed


cbi DDRD, PD7
cbi PORTD, PD7
sbi PORTC, PC0
sbi PORTC, PC1

sei ;global Interrupts einschalten

;Stackpointer setzen wg. Unterprogramm
ldi temp,HIGH(RAMEND)
out SPH,temp
ldi temp,LOW(RAMEND)
out SPL,temp

SBI DDRB, DDB1 ; Motordatenrichtungsbit setzen
SBI DDRB, DDB2
SBI DDRB, DDB4
SBI DDRB, DDB5
SBI DDRD, DDD4
SBI DDRD, DDD5
SBI PORTB, PB1 ; Motorenports PB1 und PB2 auf 5V schalten
SBI PORTB, PB2
sbi PORTD, PD5
sbi PORTB, PB5

sbi DDRC, DDC0
sbi DDRC, DDC1

;Hauptprogramm:
loop: ;leere Schleife
rjmp loop

;Interrupt Handler
interrupt: ;LEDs toggeln
inc r20 ;Timererweiterung inkrementieren
brne interrupt2 ;wenn r20=0, zu interrupt2 springen
ldi r20,HIGH(TIME2) ;sonst Starwert Timer neu setzen
;cbi PORTD, PD5
;cbi PORTB, PB5

sbrs updown,7 ;0 hoch, 1 runter
rjmp hoch
sbrc updown,7
rjmp runter

hoch:
inc speed ;1
inc speed ;2
inc speed ;3
inc speed ;4
inc speed ;5
inc speed ;6
inc speed ;7
inc speed ;8
inc speed ;9
inc speed ;10
inc speed ;11
inc speed ;12
inc speed ;13
inc speed ;14
inc speed ;15
inc speed ;16
rjmp testcompare

runter:
dec speed ;1
dec speed ;2
dec speed ;3
dec speed ;4
dec speed ;5
dec speed ;6
dec speed ;7
dec speed ;8
dec speed ;9
dec speed ;10
dec speed ;11
dec speed ;12
dec speed ;13
dec speed ;14
dec speed ;15
dec speed ;16

testcompare:

out OCR1AH, speed ; für den linken Motor
out OCR1AL, speed ; für den linken Motor
out OCR1BH, speed ; und für den rechten Motor
out OCR1BL, speed ; und für den rechten Motor

brvs noswitch
brne noswitch2

switch:
; sbrs updown,7
; rjmp noswitch2
sbrc updown,7
rjmp noswitch
;rjmp noswitch

noswitch:
ldi updown, 0b10000000
cbi DDRC, DDC0
cbi DDRC, DDC1
rjmp interrupt2

noswitch2:
ldi updown, 0b00000000
sbi DDRC, DDC0
sbi DDRC, DDC1
rjmp interrupt2

;sbi PORTD, PD5
;sbi PORTB, PB5


interrupt2:
ldi temp,LOW(TIME2) ;Startwert Timer neu
out TCNT0,temp
reti


Der soll bewirken, dass der Asuro langsam beschleunigt und dann wieder abbremst.
Leider bekomme ich das einfach im Moment nicht hin ... :(
Kann mir jemand helfen?

Danke im Voraus!

radbruch
07.01.2008, 22:32
Hallo H3llGhost

Mit Assembler kenn ich mich noch gar nicht aus, deshalb fand ich die letzte Version deines Codes noch weniger verwirrend als diese Version jetzt. Könntest du mal nur den Teil des Codes posten, der die Motoren jeweils mit einem festen PWM-Wert laufen läßt. Möglichst links und rechts verschieden.

Was mir bei der letzten Version aufgefallen war:

interrupt: ;LEDs toggeln
inc r20 ;Timererweiterung inkrementieren
brne interrupt2 ;wenn r20=0, zu interrupt2 springen
ldi r20,HIGH(TIME2) ;sonst Starwert Timer neu setzen
cbi PORTD, PD5
cbi PORTB, PB5

inc temp

out OCR1AH, temp ; für den linken Motor
out OCR1AL, temp ; für den linken Motor
out OCR1BH, temp ; und für den rechten Motor
out OCR1BL, temp ; und für den rechten Motor

sbi PORTD, PD5
sbi PORTB, PB5


interrupt2:
ldi r16,LOW(TIME2) ;Startwert Timer neu
out TCNT0,r16
reti


temp(r16) wurde nicht initialisiert, es hat noch diesen Wert:
;Stackpointer setzen wg. Unterprogramm
ldi r16,HIGH(RAMEND)
out SPH,r16
ldi r16,LOW(RAMEND)
out SPL,r16

und bei Interrupt2 wird wieder r16 verwendet, dass kann doch nicht stimmen, oder? Vielleicht sollte oben ein anderes temp definiert werden:

.def temp = r16

btw springt brne wenn r20 nicht 0 ist zu interrupt2 (lowbyte neu laden), aber da stimmt nur der Kommentar nicht.

Gruß

mic

H3llGhost
08.01.2008, 09:17
Also die festen Werte zu dem PWM werden hier gesetzt:



ldi speed,0
out OCR1BH, speed
out OCR1BL, speed
out OCR1AH, speed
out OCR1AL, speed


Was meinst du eigentlich mit


temp(r16) wurde nicht initialisiert, es hat noch diesen Wert:
;Stackpointer setzen wg. Unterprogramm
ldi r16,HIGH(RAMEND)
out SPH,r16
ldi r16,LOW(RAMEND)
out SPL,r16


r16 benutze ich bei interrupt2 wieder, da r16 meine Tempvariable ist.

Das kann ich nicht beurteilen ...
Ich weiß nur das der Debugger vom AVR Studio nicht ordentlich den Code abläuft.

Kann ich eigentlich nicht einfach das TIFR-Register benutzen?
Da müsste doch sowas auch drin stehen oder?

radbruch
08.01.2008, 16:47
Hallo

Na, das hab ich schon erkannt, ich dachte mit PWM-Code rausstellen auch die Initialisierung der Timer. Aber Egal. In der ISR verwendest du temp für die OCR-Werte:

inc temp

out OCR1AH, temp ; für den linken Motor
out OCR1AL, temp ; für den linken Motor
out OCR1BH, temp ; und für den rechten Motor
out OCR1BL, temp ; und für den rechten Motor


Weil temp aber r16 ist (.def temp = r16) hat temp zu beginn den Wert low_RAMEND (ldi r16,LOW(RAMEND)) und nach der ISR den Wert low_time2 (ldi r16,LOW(TIME2))

Gruß

mic

H3llGhost
08.01.2008, 18:04
Äh ...
ich benutze jetzt die Variable speed für die OCR!

Wie kann ich eigentlich überprüfen ob das OCR-Register überläuft?

EDIT:
Braucht man garnicht ... xD
Habe das mit der Branch-Reihe erledigt ... :)