- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 10 von 10

Thema: assembler: "kommazahlen" addieren

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.10.2004
    Ort
    ferd. Waldmüllerg. 7/2
    Alter
    40
    Beiträge
    456
    OK, so schlau werd ich aus diesem Ding auch net :S

    Also, ich hab mich mal hingesetzt und etwas zusammengespielt:

    Code:
    ;usefull Macros and defines
    
    	list      p=16F84A            ; list directive to define processor
    	#include <p16F84A.inc>        ; processor specific variable definitions
    
    
    
    movlf MACRO register, literare
    	movlw literare
    	movwf register
    	ENDM
    
    #define clock D'156'
    
    ;memory
    CBLOCK 20h
    	c_timer  ;starts with 10 and ends with 20,
    			  ;and together with timer0 it'll 
    			  ;generate "interrupts" in an intervalle between 1ms
    			  ;and 2ms
    	t_timer
    	W_TEMP
    	STATUS_TEMP
    ENDC
    
    ;data
    org 0x000
    	goto main
    
    org 0x004
    	goto interrupt
    
    interrupt
    	;backup important registers
    	movwf W_TEMP 		 ; Copy W to TEMP register,
    	swapf STATUS, W 	 ; Swap status to be saved into W
    	movwf STATUS_TEMP 	 ; Save status to STATUS_TEMP register
    
    ISR
    	;Was it a PORTB-Interrupt?
    	btfsc INTCON,0
    	call  portb_int
    
    	;Was it the timer?
    	btfsc INTCON,2
    	call  timer_int
    
    	swapf STATUS_TEMP, W ; Swap nibbles in STATUS_TEMP register
    						 ; and place result into W
    	movwf STATUS 		 ; Move W into STATUS register
    						 ; (sets bank to original state)
    	swapf W_TEMP, F 	 ; Swap nibbles in W_TEMP and place result in W_TEMP
    	swapf W_TEMP, W 	 ; Swap nibbles in W_TEMP and place result into W
    	retfie
    
    ;the portb-interrupt function
    portb_int
    	bcf		INTCON,3
    	;test, if we have 20 in the c_timer register
    	movfw	c_timer
    	sublw	D'20'
    	BZ		port_is_null
    	incf	c_timer
    	return
    port_is_null
    	movlf	c_timer,D'10'
    	return
    
    
    ;the timer-interrupt function
    timer_int
    	bcf		INTCON,2
    	;test if t_temp = c_temp
    	movlf	TMR0,clock
    	movfw	t_timer
    	subwf	c_timer,W
    	BNZ		timer_not_ready
    	clrf	t_timer
    	banksel PORTA
    
    	btfss	PORTA,0
    	goto	set_it
    	bcf		PORTA,0
    	return
    
    set_it
    	bsf		PORTA,0
    	return
    
    timer_not_ready
    	incf	t_timer
    	return
    
    ;the main routine
    main
    	;Because we are using a 4MHz PIC, 
    	;we will get set timer0 to a prescale of 
    	;to get an overflow every 100µs.
    	movlf	c_timer,D'10'
    	banksel	OPTION_REG
    	clrf	OPTION_REG
    
    	;setup PORTB
    	banksel	PORTB
    	clrf	PORTB
    	clrf	PORTA
    	banksel	TRISB
    	movlf	TRISB,B'00010000' ;all Ports except rb.4 are outputs 
    							  ;and should be pulled to GND or VCC
    	clrf	TRISA
    	
    	;enable Interrupts for timer0 and Portb-changes
    	movlf	INTCON,B'10101000'
    
    	banksel	TMR0
    	movlf	TMR0,clock
    
    	;do nothing, interrupts make the rest
    loop
    	goto loop
    
    	end
    Das ganze Programm beruht auf eine etwas andere Art und Weise, wie du es machen wolltest:
    Ich benutzt den timer0 mit einem Prescale von 1 (d.h. alle 1 µs eine erhöhung des TMR0's) und lade 156 (d.h. 100 µs bis zu einem overflow) in den TRM0. Danach setzt ich zwei Interrupts, eines ist der Timer selber, das Andere PortB.4 low --> high (c_timer 10 --> 20).
    Wenn ein Timer interrupt passiert, checke ich mit einer Laufvariable von (10 --> 20 in 1er Schritten), wie viele µs ich schon hinter mir habe und wenn es = c_timer (counter_timer) ist, invertire ich das Bit PORTA.0 und lösche den t_timer register (temporary_timer). Wenn es dies nicht ist, erhöhe t_timer einfach um eines und verlasse den Interrupt.
    Wenn ein PortB-change interrupt auftritt, schaue ich, ob c_timer = 20 ist, wenn ja dann wird c_timer = 10, wenn nicht, erhöhe ich c_timer um eins (1).

    Dadurch dass der timer jeden 100µs überläuft und der software-prescale (ich nenn solche Laufvariablen halt so ) 10-20 ist, erreiche ich eine Wartezeit von 1 ms --> 2ms in 100µs Schritten.

    Leider habe ich mit Servos nicht viel am Hut, aber ich skiziere mal, was für einen Bild du mit einem Osci am Pin PORTA.0 erhälst (PortA musste ich deshalb wählen, weil beim Simulator irgendwie kein Interrupt ankam, wenn ich immer PORTB.0 verändert habe... interessant, ist aber so :-/ )
    Code:
    +-----1000µs-----+-----1000µs-----+-----1000µs-----+
                     |----------------|
    -----------------|                |-----------------
    MfG
    Mobius

    €dit: ich habe den Code nur im Simulator von MPLAB getestet, d.h. ich kann nicht wirklich viel über das Timing aussagen, außer, dass es stimmen müsste.

    €€dit: na, wieder einmal ein Beispiel gebracht, wie ein Code NICHT aussehen sollte ^^ Layout war noch nie meine Stärke gewesen...
    Angehängte Dateien Angehängte Dateien

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress