-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Byte auswerten ?

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    20.02.2007
    Beiträge
    341

    Byte auswerten ?

    Anzeige

    Hi,

    ich müsste für mein Projekt ein Byte auswerten und damit einen Port Des Controllers für 500ms schalten.

    Das Byte wird über rs485 an den Controller übertragen. Wenn es nun z.B. eine 1 enthält, soll es PORTB.0 schalten. Wenn es eine 2 enthält PORTA.1 usw.

    Hat da jemand eine bessere Lösung als für jeden einzelnen zu schaltenden Port eine If Abfrage zu machen ?

    mfg Blamaster

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    25.12.2006
    Alter
    29
    Beiträge
    51
    Hi Blamaster,

    Wie du wahrscheinlich weist, besteht ein Byte aus 8 Bit. Wenn du nun ein Byte überträgst, kann es es z.B. in einer Variablen speichern und mit dem PortB gleichsetzen, z.B.
    Code:
    Config Portb as output
    PortB=Empfangenes_Byte
    Wenn du also einfach den Ascii-Code per RS485 überträgst, kannst du damit den gesamten Port schalten wie du möchtest.
    Ist der Ascii-Code 0 so schaltet kein Ausgang, bei 1 schaltet PortB.0 bei 2 PortB.1, bei 4 PortB.2 usw.
    Natürlich kannst du so auch mehrere Ports gleichzeitig schalten.

    Gruß
    Monday

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    20.02.2007
    Beiträge
    341
    Öhm joa aber was ist mit PORTA , PORTB , PORTC dann haut es ja nichtmehr hin.

    Denn dann würde ja jeweils auf allen 3 PORTS der entsprechende pin schalten.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    11.04.2005
    Beiträge
    1.469
    Hi,
    dann musst du wohl doch eine If Abfrage (oder select case) machen..
    Sind ja nur 8.. (Wenn du pro Bit einen Pin schalten willst)

    Code:
    if meinbyte.0 = 1 then
       portb.0=1
     else 
      portb.0=1
    endif
    ..
    ..
    ..
    ..
    if meinbyte.7 = 1 then
       portba.5=1
    else 
      porta.5=1
    endif
    Gruß
    Christopher

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.12.2005
    Beiträge
    535
    Blamaster,

    die Alternative ist eine Tabelle: Das Datenbyte, das Du über den RS485 empfangen hast, dient als Zeiger auf ein Element in einer Tabelle von bis zu 255 Bytes. Jedes Byte in der Tabelle enthält die Angabe, an welchem Port welche Pins zu setzen sind. Das hat den Vorteil, dass Du alle möglichen Bitkombinationen im Datenbyte verarbeiten kannst.

    mare_crisium

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    25.12.2006
    Alter
    29
    Beiträge
    51
    Zitat Zitat von Blamaster
    Öhm joa aber was ist mit PORTA , PORTB , PORTC dann haut es ja nichtmehr hin.

    Denn dann würde ja jeweils auf allen 3 PORTS der entsprechende pin schalten.
    Nein, das ist nicht der Fall, da du nur ja nur einen Port, in dem Fall PortB der Variablen gleich setzt.

    Ich benutze die Gleiche Technik um einen SRAM zu beschreiben, bzw auszulesen. Da wird auch ein Byte auf einem Port ausgegeben.

    Gruß
    Monday

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    20.02.2007
    Beiträge
    341
    @ mare_crisium
    Hört sich sehr interessant an. Praktisch eine Sprungtabelle. Könntest du ggf. anhand von einem code beispiel verdeutlichen wie das funkt ?

    mfg Blamaster


    Edit. hatte garnicht gesehen da so viel gepostet wurde. Ich sollte vielleicht nochmal näher beschreiben was geschehen soll. Datenspeicher(3) ist ein Byte welches die Nummer des Kanals enthält. Diese soll nun folgende Kanäle auslösen:

    Datenspeicher(3) = 1 Löse aus PORTA.0
    Datenspeicher(3) = 2 Löse aus PORTA.1
    Datenspeicher(3) = 3 Löse aus PORTA.2
    Datenspeicher(3) = 4 Löse aus PORTA.3
    Datenspeicher(3) = 5 Löse aus PORTA.4
    Datenspeicher(3) = 6 Löse aus PORTA.5
    Datenspeicher(3) = 7 Löse aus PORTA.6
    Datenspeicher(3) = 8 Löse aus PORTA.7
    Datenspeicher(3) = 9 Löse aus PORTB.0
    Datenspeicher(3) = 10 Löse aus PORTB.1
    .
    .
    .
    usw.

    Nun ist es aber wohl sehr unschlauf nachher "hundert" ifs zu haben die jeden zustand einzeln abfragen.

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Am einfachsten ist für sowas eine Tabelle mit Port-Adresse und Pin-Maske
    (sieht schräger aus, als es ist)
    Code:
    PORT_TAB:
       DATA    &H3B, 1     ' PORTA  Pin 0            virtuell 0
       DATA    &H3B, 2     ' PORTA  Pin 1            virtuell 1
       DATA    &H3B, 4     ' PORTA  Pin 2            virtuell 2
       DATA    &H3B, 8     ' PORTA  Pin 3            virtuell 3
       DATA    &H3B, 16     ' PORTA  Pin 4          virtuell 4
       DATA    &H3B, 32     ' PORTA  Pin 5          virtuell 5
       DATA    &H3B, 64     ' PORTA  Pin 6          virtuell 6
       DATA    &H3B, 128     ' PORTA  Pin 7        virtuell 7
       DATA    &H38, 128     ' PORTB  Pin 0        virtuell 8
    
       DATA    &H38, 128     ' Port B  Pin 7         virtuell 9
       DATA    &H38, 2         ' Pin 1                   virtuell 10
       DATA    &H38, 128     ' Pin 7                    virtuell 11
    
     u.s.w.
       DATA    &H35, 1     ' Port C  Pin 0         virtuell xxx
    
       DATA    &H32, 1     ' Port D  Pin 0         virtuell xxx
    Code:
    DIM  Portadr as byte
    DIM  Portmsk as byte 
    DIM  Tabv as word  at Portadr overlay
    DIM  Temp as byte
    
              Temp =  datenspeicher(3)
              Tabv = lookup ( temp,  PORT_TAB)
    
    ' z.B.  einzelnes PortPin setzen (die anderen nicht anrühren):
              Temp = INP ( Portadr)               
              TEMP = TEMP OR Portmsk
              OUT ( Portadr, TEMP)               
    
    ' z.B.  einzelnes PortPin löschen (die anderen nicht anrühren):
              Temp = INP ( Portadr)               
              Portmsk = Portmsk XOR &HFF     
              TEMP = TEMP AND portmsk
              OUT ( Portadr, TEMP)
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.12.2005
    Beiträge
    535
    blamaster,

    so wie's PicNick in Basic geschrieben hat, hatte ich's auch gemeint. In Assembler sieht's ganz ähnlich aus. Nach ein bisschen Herumprobieren kam mir eine echte Sprungtabelle als die einfachste Methode (in Assembler) vor. Dann braucht man aber doppelt soviel Platz für die Tabelle, als wenn man Port- und Pin-Nummer in einem Byte kodiert ablegt. Es ist aber einfacher, über die Sprungtabelle direkt eine Auswertungsprozedur anzuspringen, als das gelesene Tabellenbyte zu dekodieren. Das kommt daher, dass man beim Atmel die Ports nur direkt (immediate) adressieren kann.

    Zur Information hänge ich das Beispiel unten an.

    mare_crisium

    Code:
    ;*-----------------------------------
    ; BEISPIEL Tabelle_V01.asm
    ; Entwicklungsversion
    ;*-----------------------------------
    ;* 	Einbinden
    ;*
    
    .device  ATmega8
    .include "m8def.inc"
    
    ;*-----------------------------------
    ;* 	Definitionen
    ;*
    
    .equ	PORTA = 0x1B
    
    
    ;*------------------------------------
    ;*	PROCEDURE TBL_CALL
    ;*
    ;* Die Prozedure TBL_JMP liest aus einer Sprung-
    ;* tabelle, die im Programmspeicher abgelegt 
    ;* ist, ein 2-Byte-Adresse aus. Sie wird als
    ;* Programmadresse angesprungen.
    ;
    ; Eingangsvariablen
    ;	zh:zl:  enhält den Zeiger auf die RAM-Adresse,
    ;	     an der die Sprungtabelle beginnt
    ;	r16: enthält den Index der Adresse, die 
    ;	     angesprungen werden soll
    ;
    ; Ausgangsvariablen
    ;	keine
    ;
    ; geänderte Register
    ;	zh,zl
    ;
    ; geänderte Ports
    ;	keine
    ;
    
    TBL_CALL:
    	push r17
    	in r17,SREG
    	push r17
    
    
    	clr r17
    	add zl,r16
    	adc zh,r17
    	add zl,zl
    	adc zh,zh
    
    	lpm r17,z+
    	lpm zh,z
    	mov zl,r17
    
    	pop r17
    	out SREG,r17
    	pop r17
    
    	ijmp	
    
    
    /*------------------------------------ 
    
    SPRUNGTABELLE
    
    
    */
    //   0.0  0.1   0.2   0.3   0.4   0.5   0.6  0.7 
    SPRUNG_TBL:
    .dw SET_PORTA0,	RES_PORTA0						; ... usw.
    
    //...
    
    .dw SET_PORTC7,	RES_PORTC7
    
    
    /*------------------------------------
    	PROCEDURE EVAL_RS485
    
    Die Prozedure EVAL_RS485 wertet ein Datenbyte aus,
    das über die RS485 empfangen wurde. Das Datenbyte dient
    als Zeiger in die Sprungtabelle SPRUNG_TBL. Die Einträge 
    enthalten die Adresse je einer Prozedur, die an einem
    bestimmten Port einen bestimmten Pin setzt oder zurücksetzt.
    
    Eingangsvariablen
    	r16: enthält den das Datenbyte, das 
    	     ausgewertet werden soll
    
    Ausgangsvariablen
    	r16: enthält das ungeänderte Datenbyte
    
    geänderte Register
    	keine
    
    geänderte Ports
    	PORTA,PORTB,PORTC, je nach Datenbyte
    */
    
    
    EVAL_RS485:
    	push r16
    	push zl
    	in zl,SREG
    	push zl
    	push zh
    
    	ldi zl,low(SPRUNG_TBL); zh:zl := Adresse der Tabelle
    	ldi zh,high(SPRUNG_TBL)
    	rcall TBL_CALL	; ausgewählte Prozedure anspringen
    
    	pop zh
    	pop zl
    	out SREG,zl
    	pop r16
    	ret			;
    
    /*------------------------------------
    	PROZEDUREN SET_PORTA0/RES_PORTA0 bis SET_PORTC7/RES_PORTC7
    
    Hier kommen die Prozeduren, die die ausgewählten Ports und
    Pins ansprechen.
    
    Eingangsvariablen
    	keine
    
    Ausgangsvariablen
    	keine
    
    geänderte Register
    	keine
    
    geänderte Ports
    	PORTA,PORTB,PORTC, je nach Datenbyte
    */
    
    SET_PORTA0:
    	sbi PORTA,0
    	ret
    
    RES_PORTA0:
    	cbi PORTA,0
    	ret
    
    // und so weiter
    
    SET_PORTC7:
    	sbi PORTC,7
    	ret
    
    RES_PORTC7:
    	cbi PORTC,7
    	ret
    
    //------------------------

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    43
    Beiträge
    2.240
    a_byte=udr
    if a_byte.0=1 then
    set relais_0
    else
    reset relais_0
    endif
    if a_byte.1=1 then
    set relais_1
    else
    reset relais_1
    endif
    if a_byte.2=1 then
    set relais_2
    else
    reset relais_2
    endif

    ... and so on
    Vor den Erfolg haben die Götter den Schweiß gesetzt

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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