-
        

Ergebnis 1 bis 10 von 10

Thema: Frage zu 'Stimmungslampe' mit Tiny12 in Assembler

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685

    Frage zu 'Stimmungslampe' mit Tiny12 in Assembler

    Anzeige

    Moin!
    Beim letzten Einkauf habe ich 'aus versehen' ein paar Tiny12 mitbestellt und habe entsetzt feststellen müssen, daß ich die gar nicht in C programmieren kann mangels RAM. Naja, da habe ich die Gelegenheit ergriffen und mich in die Tiefen des Assemblers gestürzt (sowas hab ich zuletzt vor Jahrzehnten mit dem C64 gemacht...). Als Projekt bot sich eine sogenannte 'Stimmungslampe' an, da sich mein Kollege so eine bei Aldi gekauft hatte, und ich angeberisch hab verlauten lassen : Das kann ich auch !! \/ Also kurz einen Prototypen gebaut bestehend aus einem Tiny12, einem Taster, 4 Transistoren BC547B mit 750Ohm Basiswiderstand sowie 4 LED's (Gelb, Grün, Rot, Weiß) mit jeweils einfach 160 Ohm davor, was anderes hatte ich leider grad nicht. Und weil ich grad gut drauf war, habe ich gleich auch noch zum ersten mal in meinem Leben den Timer benutzt und eine Interruproutine geschrieben.... Das Grundkonzept ist eigentlich ganz einfach, es läuft eine Endlosschleife, die quasi mittels Software-PWM die 4 LED's dimmt, und in dem Timer IRQ wird einfach der Vergleichswert für das SW-PWM erhöht. Das funktioniert auch eigentlich ganz gut, allerdings steh ich jetzt grad auf dem Schlauch, da ich die LED's im Moment nur in eine Richtung dimme, also immer von An nach Aus, danach macht's 'plopp' und die LED ist wieder an. Also muß ich mir ja irgendwie merken, ob ich die aktuelle LED gerade dunkler oder heller machen muß, ich hab aber grad keine Idee, wie ich das sinnvoll machen kann. Vielleicht hat ja jemand einen kleinen Tipp für mich,hier ist erstmal mein 1. Assemblerprogramm für den AVR überhaupt!!!
    Code:
    .NOLIST                
    .INCLUDE <tn12def.inc>
    .LIST                   
    .CSEG               
    
    .def tmp = r16 		;arbeitsregister
    .def cnt1 = r17		;Helligkeit LED1
    .def cnt2 = r18		;Helligkeit LED2
    .def cnt3 = r19		;Helligkeit LED3
    .def cnt4 = r20		;Helligkeit LED4
    
    .equ led1 = 1		;Bit an PortB
    .equ led2 = 2		;Bit an PortB
    .equ led3 = 3		;Bit an PortB
    .equ led4 = 4		;Bit an PortB
    .equ waittime = 200	;Timer preload, Geschwindigkeit
    
    .def dir = r21		;Flag für Auf/Abblenden
    ;------------------------------------------------------
    ;     Start Adresse 0000
    ;------------------------------------------------------
    .org 0000
    RESET:
        rjmp INIT           
    
    ;------------------------------------------------------
    ;     ISR VECTORS
    ;------------------------------------------------------
    .org OVF0addr 
    	rjmp Timer  
    
    .ORG INT_VECTORS_SIZE
    
    INIT:
    	;PortB konfigurieren
    	ldi tmp,(1<<1)| (1<<2)| (1<<3)| (1<<4)	;binär 00011110, Leds auf Ausgang, Taster als Eingang
    	out DDRB,tmp							;DDRB setzen
    	sbi PORTB,0								;Pullup für PB0, Taster schaltet gegen GND
    	;Timer konfigurieren
    	ldi tmp,(1<<CS00) | (1<<CS02)			; prescaler 1024
    	out TCCR0,tmp
    	ldi tmp,(1<<TOIE0)						; IRQ anschalten
    	out TIMSK,tmp
    	ldi tmp,waittime
    	out tcnt0,tmp
    
    	ldi cnt1,127							;starthelligkeit für LED1
    	ldi cnt2,127							;starthelligkeit für LED2
    	ldi cnt3,127							;starthelligkeit für LED3
    	ldi cnt4,127							;starthelligkeit für LED4
    	ldi dir,0								;
    	sei
    
    MAIN:
    	ldi tmp,255		;zähler für Soft-PWM auf Maximum
    
    loop1:
    	cp tmp,cnt1		;Zähler mit Helligkeit vergleichen
    	brlo led1_off	;wenn kleiner, dann led ausschalten
    	sbi portb,led1	;ansonsten LED einschalten
    	rjmp skip1		;und weiter mit Soft-PWM
    led1_off:
    	cbi portb,led1	;Led ausschalten, nur tmp < cnt1
    skip1:
    	dec tmp			;tmp - 1
    	brne loop1		;solange, bis tmp = 0
    	
    	ldi tmp,255
    loop2:
    	cp tmp,cnt2
    	brlo led2_off
    	sbi portb,led2
    	rjmp skip2
    led2_off:
    	cbi portb,led2
    skip2:
    	dec tmp
    	brne loop2
    
    	ldi tmp,255
    loop3:
    	cp tmp,cnt3
    	brlo led3_off
    	sbi portb,led3
    	rjmp skip3
    led3_off:
    	cbi portb,led3
    skip3:
    	dec tmp
    	brne loop3
    
    	ldi tmp,255
    loop4:
    	cp tmp,cnt4
    	brlo led4_off
    	sbi portb,led4
    	rjmp skip4
    led4_off:
    	cbi portb,led4
    skip4:
    	dec tmp
    	brne loop4
    		
    	rjmp main
    
    
    
    Timer:
    
    	inc cnt1
    	inc cnt2
    	inc cnt3
    	inc cnt4
    		
    	ldi tmp,waittime
    	out tcnt0,tmp
    	reti
    Hier ist ein kleines Video der ganzen Konstruktion in Aktion, was auch ein wenig seltsam ist, ist der starke Helligkeitssprung, nachdem die LED wieder an ist, liegt das an meinem Programm oder ist das ein Effekt der PWM? (Dieses Pulsieren der LED's sieht man nicht, das kommt von der Belichtungszeit meiner Kamera....) http://fokker.no-ip.com/moodlight.avi
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo

    Sehr hübsch. Vielleicht in der ISR ein kleiner Schalter?
    Code:
    Timer:
    If schalter = 1 then
    
       inc cnt1
       inc cnt2
       inc cnt3
       inc cnt4
    	if cnt1 = 255 schalter = 0
    
    else
    
    	dec cnt1
    	dec cnt2
    	dec cnt3
    	dec cnt4
    	if cnt1 = 0 schalter = 1
    
    end if
    	
    
       ldi tmp,waittime
       out tcnt0,tmp
       reti
    255 ist der hellste, 0 der dunkelste Wert. Sorry, aber ich kann auch kein avr-Assembler. Statt if und else muss natürlich ein bedingter Sprung rein der, in Abhängigkeit vom Schalter, zum auf- oder abzählenden Teil der ISR springt. Wenn der gewünschte Hell- oder Dunkelwert erreicht ist, wird der Schalter umgeschaltet.

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    Moin!
    Sowas hab ich mir auch schon überlegt, ich bräuchte das halt für jede LED einzeln und würde es in einem Register in ein paar Bits speichern, ich dachte nur, daß es evtl. eine nicht so komplizierte Lösung gibt ... Naja, ich implementier grad mal meinen Bit-Krams und stell das auch noch mal hier zur Diskussion. Und bis gestern konnte ich auch kein AVR-Assembler
    MfG Volker
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    In der Interrruptroutine wird vergessen das Statusregister zu sichern und auch das temp Register wird in der ISR und im Hauptprogramm benutzt. Das ist ein Typischer Anfängerfehler der zu ziehmlich unberechenbaren (soweit bei einem Computer möglich) verhalten führen kann. Die typischen interrruptsroutine beginnt daher mit
    IN Reg1,SREG und endet mit out SREG,Reg1. Das retten der Register auf den Stack kommt beim Tiny12 mangels RAM kaum in Frage. Man nimmt also seperate Register für die Interrrupts und das Hauptprogram.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    Moin!
    Ah, danke, war mir gar nicht aufgefallen.... ich habe jetzt mal ein weiteres Register für die ISR genommen (t_tmp).Ich bin mittlerweile weiter, allerdings klappt das alles jetzt gar nicht mehr, obwohl im Simulator die Werte von cnt1 bis cnt4 wunderschön hoch und runtergezählt werden.... Ich fürchte auch, meine ISR ist ein wenig zu voll geraten, allerdings sollte es ja trotzdem irgendwie gehen, da ja höchstens ein paar Timer-IRQ's verlorengehen, also dürfte es höchstens langsamer werden, oder nicht? Leider leuchten die LED's jetzt bloß irgendwie vor sich hin...
    Mein Code sieht mittlerweise so aus
    Code:
    .NOLIST                
    .INCLUDE <tn12def.inc>
    .LIST                   
    .CSEG               
    
    .def tmp = r16 		;arbeitsregister
    .def t_tmp = r22	;hilfsregister
    .def sreg_store=r23	;zum Statusregister sichern
    .def cnt1 = r17		;Helligkeit LED1
    .def cnt2 = r18		;Helligkeit LED2
    .def cnt3 = r19		;Helligkeit LED3
    .def cnt4 = r20		;Helligkeit LED4
    
    .equ led1 = 1		;Bit an PortB
    .equ led2 = 2		;Bit an PortB
    .equ led3 = 3		;Bit an PortB
    .equ led4 = 4		;Bit an PortB
    .equ waittime = 140	;Timer preload, Geschwindigkeit
    
    .def dir = r21		;Flag für Auf/Abblenden
    ;------------------------------------------------------
    ;     Start Adresse 0000
    ;------------------------------------------------------
    .org 0000
    RESET:
        rjmp INIT           
    
    ;------------------------------------------------------
    ;     ISR VECTORS
    ;------------------------------------------------------
    .org OVF0addr 
    	rjmp Timer  
    
    .ORG INT_VECTORS_SIZE
    
    INIT:
    	;PortB konfigurieren
    	ldi tmp,(1<<1)| (1<<2)| (1<<3)| (1<<4)	;binär 00011110, Leds auf Ausgang, Taster als Eingang
    	out DDRB,tmp							;DDRB setzen
    	sbi PORTB,0								;Pullup für PB0, Taster schaltet gegen GND
    	;Timer konfigurieren
    	ldi tmp,(1<<CS00) | (1<<CS02)			; prescaler 1024
    	out TCCR0,tmp
    	ldi tmp,(1<<TOIE0)						; IRQ anschalten
    	out TIMSK,tmp
    	ldi tmp,waittime
    	out tcnt0,tmp
    
    	ldi cnt1,255							;starthelligkeit für LED1
    	ldi cnt2,195							;starthelligkeit für LED2
    	ldi cnt3,127							;starthelligkeit für LED3
    	ldi cnt4,63								;starthelligkeit für LED4
    	ldi dir,0									;
    	sei
    
    MAIN:
    	ldi tmp,255		;zähler für Soft-PWM auf Maximum
    
    loop1:
    	cp tmp,cnt1		;Zähler mit Helligkeit vergleichen
    	brlo led1_off	;wenn kleiner, dann led ausschalten
    	sbi portb,led1	;ansonsten LED einschalten
    	rjmp skip1		;und weiter mit Soft-PWM
    led1_off:
    	cbi portb,led1	;Led ausschalten, nur tmp < cnt1
    skip1:
    	dec tmp			;tmp - 1
    	brne loop1		;solange, bis tmp = 0
    	
    	ldi tmp,255
    loop2:
    	cp tmp,cnt2
    	brlo led2_off
    	sbi portb,led2
    	rjmp skip2
    led2_off:
    	cbi portb,led2
    skip2:
    	dec tmp
    	brne loop2
    
    	ldi tmp,255
    loop3:
    	cp tmp,cnt3
    	brlo led3_off
    	sbi portb,led3
    	rjmp skip3
    led3_off:
    	cbi portb,led3
    skip3:
    	dec tmp
    	brne loop3
    
    	ldi tmp,255
    loop4:
    	cp tmp,cnt4
    	brlo led4_off
    	sbi portb,led4
    	rjmp skip4
    led4_off:
    	cbi portb,led4
    skip4:
    	dec tmp
    	brne loop4
    		
    	rjmp main
    
    
    
    Timer:
    	in sreg_store,sreg
    
    _Led1:
    	mov t_tmp,dir
    	andi t_tmp,(1<<Led1)
    	breq _inc1a
    	dec cnt1
    	brne _Led2
    	ldi t_tmp,(1<<Led1)
    	eor dir,t_tmp
    	rjmp _Led2
    _inc1a:
    	inc cnt1
    	brne _Led2
    	ori dir,(1<<Led1)
    
    _Led2:
    	mov t_tmp,dir
    	andi t_tmp,(1<<Led2)
    	breq _inc2a
    	dec cnt2
    	brne _Led3
    	ldi t_tmp,(1<<Led2)
    	eor dir,t_tmp
    	rjmp _Led3
    _inc2a:
    	inc cnt2
    	brne _Led3
    	ori dir,(1<<Led2)
    
    _Led3:
    	mov t_tmp,dir
    	andi t_tmp,(1<<Led3)
    	breq _inc3a
    	dec cnt3
    	brne _Led4
    	ldi t_tmp,(1<<Led3)
    	eor dir,t_tmp
    	rjmp _Led4
    _inc3a:
    	inc cnt3
    	brne _Led4
    	ori dir,(1<<Led3)
    
    _Led4:
    	mov t_tmp,dir
    	andi t_tmp,(1<<Led4)
    	breq _inc4a
    	dec cnt4
    	brne t_end
    	ldi t_tmp,(1<<Led4)
    	eor dir,t_tmp
    	rjmp t_end
    _inc4a:
    	inc cnt4
    	brne t_end
    	ori dir,(1<<Led4)
    
    
    t_end:		
    	ldi t_tmp,waittime
    	out tcnt0,t_tmp
    	out sreg,sreg_store
    	reti
    /edit: Grmpfl. Mein USBTinyISP wahr Schuld, der mag diese Schaltung nicht so richtig und hat den Controller nicht richtig programmiert.... Das ganze über 'nen klasischen Parallelportprogrammer mit 'nem 74hct244 und Ponyprog, und schon gehts... Naja, fast zumindest, ich muß wohl nochmal meine Schleifen feintunen,da es bei den Maximal und Minimalwerten zu einem unschönen 'blitzen' kommt, hier ein aktuelles Video :
    http://fokker.no-ip.com/moodlight2.avi
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.05.2005
    Ort
    Kaiserslautern
    Beiträge
    794
    Hi,

    abgesehen von deinem Problem..

    Wieso kann man Tiny12er nicht mit C programmieren? (Nur bevor ich mir selber welche kaufe ^^)

    Gruß, CowZ

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    Moin!
    Naja, um einen µC in C programmieren zu können, benötigt dieser RAM, der Tiny12 hat aber kein RAM, sondern nur Flash fürs Programm, ein par Bytes Eeprom und seine 32 Register... muß man in den Beschreibungen aufpassen, das steht da manchmal etwas irreführend/missverständlich als 32 bytes Ram drin (oder ich war zu doof zum lesen). Auch Bascom geht wohl nicht so toll, einige Befehle gehen wohl, die meisten aber nicht. Allerdings ist das Hörensagen, da ich mich mit Bascom bisher nicht wirklich beschäftigt habe. Das ganze ist trotzdem relativ einfach (mir haben meine 6502 Assemblerkenntnisse vom C64 sehr geholfen), und in C muß ich mich auch mit Registern und Bits rumschlagen, da ist der Unterschied bei so kleinen Progrämmchen eh nicht so schlimm...
    Also drauf achten, daß der Tiny außer seinen Registern auch noch ein wenig RAM hat, sonst ist ein Assembler-crashkurs angesagt

    MFG und frohes RestFest,

    Volker
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.05.2005
    Ort
    Kaiserslautern
    Beiträge
    794
    Ah, ok, danke

    War mir nicht bewusst, dass ich den RAM für C umbedingt benötige. Das lässt sich auch nicht abstellen?

    Gruß, CowZ

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    Soweit ich weiß, nicht, das ist wohl eine Grundvoraussetzung für den Gcc....

    MfG
    Volker
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.05.2005
    Ort
    Kaiserslautern
    Beiträge
    794
    Ok, danke für die Info

    Gruß, CowZ

Berechtigungen

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