- LiTime Speicher und Akkus         
Seite 1 von 5 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 42

Thema: Controller als I2C Slave mit Bascom

  1. #1
    Newbie
    Gast

    Controller als I2C Slave mit Bascom

    Anzeige

    LiFePo4 Akku selber bauen - Video
    BasCom verfügt ja schon über eingebaute I2C-Befehle. Eigentlich feine Sache.

    Kann man damit irgendwie einen Controller als Slave betreiben so das er von anderm Controller per I2C angesprochen wird? Ich Suche ein paar Beispiele.

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    19.11.2003
    Alter
    45
    Beiträge
    97
    Beim Ultraschallsensor SFR04 und SFR08, sowie dem Kompass CMPS03 werden PICs für die Auswertung und Aufbereitung der Sensordaten verwendet. Diese sind über den I2C-Bus (als Slave) auslesbar.

    Mit Code kann ich leider nicht dienen.
    mfg
    Judgeman

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    07.11.2003
    Beiträge
    26
    Ich hab einige Zeilen gefunden


    Code:
    '
    ' SLAVE-Adresse 100
    ' nur Daten empfangen möglich/erforderlich --> MASTER-WRITE
    ' 5 Servos
    ' Im Feld Daten wird die Nr. des Servo's  und dessen Laufrichtung verschlüsselt übergeben
    '
    '******************************************
    
    Servo1 Alias Portb.1
    Servo2 Alias Portb.2
    Servo3 Alias Portb.3
    Servo4 Alias Portb.4
    Servo5 Alias Portb.5
    
    Dim Daten As Byte
    Dim I As Byte
    
    $baud = 9600
    
    On Int0 Ext_int0
    On Ovf0 Tim0_ovf
    Goto Reset
    $asm
    
    ;***************************************************************************
    ;* Refers to the application note AVR302 documentation for more
    ;* detailed description.
    ;*
    ;* USAGE
    ;* Insert user code in the two locations marked "insert user code here".
    ;*
    ;* NOTES
    ;* Minimum one instruction will be executed between each interrupt.
    ;*
    ;* STATISTICS
    ;* Code Size         : 160
    ;* Register Usage    : 5 High, 0 Low
    ;* Interrupt Usage   : EXT_INT0 and TIM0_OVF
    ;* Port Usage        : PD4(T0) and PD2(INT0)
    ;* XTAL              :  - I2C Fast Mode     : min 16.0MHz
    ;*                      - I2C Standard Mode : min  3.0MHz
    ;*
    ;***************************************************************************
    
    ;**** Includes ****
    
    .include "2313def.inc"
    
    
    ;**** Global I2C Constants ****
    
    
    ;.def Devadr = 0x50 ; Slave Device Address        geändert
    ;.def Devadrm = 0x7f ; Slave Multi Address Mask   geändert
    
    ;.def Pinmaskx = 0x14 ; <=>(1 << Pd4) +(1 << Pd2)  geändert
    
    ;**** Global Register Variables ****
    
    .def Temp = R16 ; Temporary Variable
    .def Etemp = R17 ; Extra Temporary Variable
    .def I2cdata = R18 ; I2C Data Register
    .def I2cadr = R19 ; I2C Address And Direction Register
    .def I2cstat = R20 ; I2C Temporary Sreg Storage
    
    ;**** Interrupt Vectors ****
    ;     Anpassung wegen Umstellung von 1200 auf 2313 !!!
    
    ;         rjmp RESET          ;Reset handle
    ;         rjmp EXT_INT0        ;INT0 handle
    ;         rjmp Xxx             ;int_1                          eingefügt
    ;         rjmp Xxx             ;time1_capt                     eingefügt
    ;         rjmp xxx             ;time1_compa                    eingefügt
    ;         rjmp xxx             ;time1_compb                    eingefügt
    ;         Rjmp Xxx             ;Time1_ovfl                     eingefügt
    ;         rjmp TIM0_OVF        ;Timer 0 overflow handle
    ;
    ; ( rjmp ANA_COMP ) ; ( Analog comparator handle )
    ;
    ;Xxx:
    
    ;***************************************************************************
    ;*
    ;* INTERRUPT
    ;* EXT_INT0 / i2c_wakeup
    ;*
    ;* DESCRIPTION
    ;* Detects the start condition and handles the data transfer on
    ;* the I2C bus.
    ;*
    ;* Received data is stored in the r0 register and r0 is transmitted
    ;* during a master read transfer.
    ;*
    ;* NOTE
    ;* This interrupt code, in some cases, jumps to code parts in the
    ;* TIM0_OVF / i2c_skip section to reduce code size.
    ;*
    ;***************************************************************************
    
    Ext_int0:
               in i2cstat,SREG    ; store SREG
    
    
    ;*************************
    ;* Get I2C Slave Address *
    ;*************************
    
    I2c_get_adr:
              ldi i2cadr,1        ; initialize address register
    Wlo_ga0:
              Sbic Pind , Pind4   ; Wait For Scl Low
              rjmp wlo_ga0
              rjmp first_ga
    Do_ga:
                                  ; Do
    
    Wlo_ga:
             Sbic Pind , Pind4    ; Wait For Scl Low
             rjmp wlo_ga
    
             mov  temp,i2cadr     ; test address
    
         ;orginal andi    temp,Devadrm      ; mask register full floating bit
             andi R16,0x7f                                               ;geändert
    
         ;orginal cpi     temp,devadr         ; if device addressed
    
    ;*****************************************************************************
    ;*****************************************************************************
    
             cpi  R16,0x32        ;dig.Adresse (RR&Co)  = 100             geändert
                                  ;0x32 = binär 0110010 + 0 (R/W-Bit)
                                  ;100  = binär 01100100
    
    ;*****************************************************************************
    ;*****************************************************************************
    
             in   temp,SREG       ; set T flag ("T = Z")
             bst  temp,1
    
    
    First_ga:
             sec                  ; set carry
    Whi_ga:
             Sbis Pind , Pind4    ; Wait For Scl High
             rjmp whi_ga
             sbis PIND,PIND2      ; if SDA low
             clc                  ; clear carry
             rol i2cadr           ; shift carry into address register
    
             brcc do_ga           ; while register not full
    
    Wlo_ca:
             Sbic Pind , Pind4    ; Wait For Scl Low
             rjmp wlo_ca
    
    ;**** Check Address ****
                                  ; if T flag set (device addressed)
             brts i2c_adr_ack     ; acknowledge address
                                  ; else
             rjmp i2c_adr_miss    ; goto address miss handle
    
    ;**** Acknowledge Address ****
    
    I2c_adr_ack:
             sbi DDRD,DDD2        ; assert acknowledge on SDA
    Whi_aa:
             Sbis Pind , Pind4    ; Wait For Scl High
             rjmp whi_aa
    
    ;**** Check Transfer Direction ****
    
             lsr i2cadr           ; if master write
             brcc i2c_master_write; goto master write handle
    
    
    ;*******************************
    ;* Transmit Data (master read) *
    ;*******************************
    
    I2c_master_read:
    
    ;**** Load Data (handle outgoing data) ****
    
    ;!INSERT USER CODE HERE !
    ;!NOTE! If the user code is more than ONE instruction then wait
    ; states MUST be inserted as shown in description.
    
             mov i2cdata,r0       ; insert data in "serial"
                                  ; register (user code example)
             sec                  ; shift MSB out and "floating empty flag" in
             rol i2cdata
    
    Wlo_mr:
             Sbic Pind , Pind4    ; Wait For Scl Low
             rjmp wlo_mr
    
    
    ;**** Transmitt data ****
    
             brcc fb_low_mr       ; if current data bit high
             cbi DDRD,DDD2        ; release SDA
             rjmp fb_mr           ; goto read loop
    Fb_low_mr:
                                  ; Else
             sbi DDRD,DDD2        ; force SDA
    Fb_mr:
             Lsl I2cdata          ; If Data Register Not Empty
    
    Loop_mr:
    Whi_mr:
             Sbis Pind , Pind4    ; Wait For Scl High
             rjmp whi_mr
    Wlo_mr2:
             Sbic Pind , Pind4    ; Wait For Scl Low
             rjmp wlo_mr2
    
             brcc b_low_mr        ; if current data bit high
    
             cbi DDRD,DDD2        ; release SDA
             lsl i2cdata          ; if data register not empty
             brne loop_mr         ; loop
             rjmp done_mr         ; done
    B_low_mr:
                                  ; Else
             sbi DDRD,DDD2        ; force SDA
             lsl i2cdata          ; if data register not empty
             brne loop_mr         ; loop
    
    Done_mr:
    Whi_mr2:
             Sbis Pind , Pind4    ; Wait For Scl High
             rjmp whi_mr2
    Wlo_mr3:
             Sbic Pind , Pind4    ; Wait For Scl Low
             rjmp wlo_mr3
    
             cbi DDRD,DDD2        ; release SDA
    
    ;**** Read Acknowledge from Master ****
    
    Whi_ra:
             Sbis Pind , Pind4    ; Wait For Scl High
             rjmp whi_ra
    
             sec                  ; read acknowledge
             sbis PIND,PIND2
             clc
             brcc i2c_master_read ; if ack transfer (next) data
    
    Wlo_ra:
             Sbic Pind , Pind4    ; Wait For Scl Low
             rjmp wlo_ra
    
             rjmp i2c_wait_cond   ; goto wait condition (rep. start or stop)
    
    
    ;*******************************
    ;* Receive Data (master write) *
    ;*******************************
    
    I2c_master_write:
    
    Wlo_mw0:
             Sbic Pind , Pind4    ; Wait For Scl Low
             rjmp wlo_mw0
             cbi DDRD,DDD2        ; remove acknowledge from SDA
    
    Whi_mw:
             Sbis Pind , Pind4    ; Wait For Scl High
             rjmp whi_mw
    
             in temp,PIND         ; sample SDA (first bit) and SCL
    
          ;orginal: andi temp,pinmask
             andi R16,0x14        ; mask out SDA and SCL              geändert
    Do_mw:
                                  ; Do
             in etemp,PIND        ; new sample
    
          ;orginal: andi etemp,pinmask
             andi R17,0x14        ; mask out SDA and SCL              geändert
             cp etemp,temp
             breq do_mw           ; while no change
    
             sbrs etemp,PIND4     ; if SCL changed to low
             rjmp receive_data    ; goto receive data
    
             sbrs etemp,PIND2     ; if SDA changed to low
             rjmp i2c_get_adr     ; goto repeated start
                                  ; else
             rjmp i2c_stop        ; goto transfer stop
    
    Receive_data:
             ldi i2cdata,2        ; set i2cdata MSB to zero
             sbrc temp,PIND2      ; if SDA sample is one
             ldi i2cdata,3        ; set i2cdata MSB to one
    
    Do_rd:
                                  ; Do
    Wlo_rd:
             Sbic Pind , Pind4    ; Wait For Scl Low
             rjmp wlo_rd
             sec                  ; set carry
    Whi_rd:
             Sbis Pind , Pind4    ; Wait For Scl High
             rjmp whi_rd
    
             sbis PIND,PIND2      ; if SDA low
             clc                  ; clear carry
             rol i2cdata          ; shift carry into data register
    
             brcc do_rd           ; while register not full
    
    ;**** Acknowledge Data ****
    
    I2c_dat_ack:
    Wlo_da:
             Sbic Pind , Pind4    ; Wait For Scl Low
             rjmp wlo_da
             sbi DDRD,DDD2        ; assert acknowledge on SDA
    Whi_da:
             Sbis Pind , Pind4    ; Wait For Scl High
             rjmp whi_da
                                  ; (acknowledge is removed later)
    
    ;**** Store Data (handle incoming data) ****
    ; insert wait states here if nessesary
    
             Sbi Ddrd , Ddd4      ;(start Wait State)             aktiviert
    
    ;!INSERT USER CODE HERE !
    ;!NOTE! If the user code is more than TWO instruction then wait
    ; states MUST be inserted as shown in description.
    
             mov r0,i2cdata       ; Store data receved in "serial"
                                  ; register (user code example)
    
    
             Gosub Bearbeitung
    
    
             cbi DDRD,DDD4        ; (end wait state)              aktiviert
             cbi DDRD,DDD2        ; remove acknowledge from SDA
    
             ;Rjmp I2c_master_write ; Start On Next Transfer      geändert / nur Datenempfang
             rjmp I2c_stop
    
    ;***************************************************************************
    ;*
    ;* INTERRUPT
    ;* TIM0_OVF / i2c_skip
    ;*
    ;* DESCRIPTION
    ;* This interrupt handles a "address miss". If the slave device is
    ;* not addressed by a master, it will not acknowledge the address.
    ;*
    ;* Instead of waiting for a new start condition in a "busy loop"
    ;* the slave set up the counter to count 8 falling edges on SCL and
    ;* returns from the current interrupt. This "skipping" of data
    ;* do not occupies any processor time. When 8 egdes are counted, a
    ;* timer overflow interrupt handling routine (this one) will check
    ;* the next condition that accure. If it       's a stop condition
    ;* the transfer ends, if it   's a repeated start condition a jump
    ;* to the i2c_wakeup interrupt will read the new address. If a new
    ;* transfer is initiated the "skipping" process is repeated.
    ;*
    ;***************************************************************************
    
    Tim0_ovf:
                                  ; (timer 0 Overflow Handle )
             in i2cstat,SREG      ; store SREG
    
    I2c_adr_miss:
    
    ;**** Drop Acknowledge ****
    
    Whi_dac:
             Sbis Pind , Pind4    ; Wait For Scl High
             rjmp whi_dac
    Wlo_dac:
             Sbic Pind , Pind4    ; Wait For Scl Low
             rjmp wlo_dac
    
                                  ; disable timer 0 overflow interrupt
    
    
         ;orginal: ldi temp,(0<<TOIE0)
    
             clr temp             ;                                eingefügt
             sbr temp,&b00000000  ;                                geändert
             Out Timsk , Temp
                                  ; enable external interrupt request 0
    
         ;orginal: ldi temp,(1<<INT0)
    
             clr temp             ;                                eingefügt
             sbr temp,&b01000000  ;                                geändert
             Out Gimsk , Temp
    
    
    ;************************
    ;* Wait for a Condition *
    ;************************
    
    I2c_wait_cond:
    Whi_wc:
             Sbis Pind , Pind4    ; Wait For Scl High
             rjmp whi_wc
    
             in temp,PIND         ; sample SDA (first bit) and SCL
    
         ;orginal:andi temp,pinmask ; mask out SDA and SCL
             andi R16,0x14        ;                                geändert
    Do_wc:
                                  ; Do
             in etemp,PIND        ; new sample
    
         ;orginal: andi etemp,pinmask  ; mask out SDA and SCL
             andi R17,0x14        ;                                geändert
             cp etemp,temp
             breq do_wc           ; while no change
    
             sbrs etemp,PIND4     ; if SCL changed to low
             rjmp i2c_skip_byte   ; goto skip byte
    
             sbrs etemp,PIND2     ; if SDA changed to low
             rjmp i2c_get_adr     ; goto repeated start
                                  ; else
                                  ; goto transfer stop
    
    
    ;*************************
    ;* Handle Stop Condition *
    ;*************************
    
    I2c_stop:
                   ;! Set INT0 to generate an interrupt on low level,
                   ;! then set INT0 to generate an interrupt on falling edge.
                   ;! This will clear the EXT_INT0 request flag.
    
      ;orginal: ldi temp,(0<<ISC01)+(0<<ISC00)
    
             clr temp             ;                             eingefügt
             sbr temp,&b00000000  ;                             geändert
             Out Mcucr , Temp
    
      ;orginal: ldi temp,(1<<ISC01)+(0<<ISC00)
    
             clr temp             ;                             eingefügt
             sbr temp,&b00000010  ;                             geändert
             Out Mcucr , Temp
    
             Out Sreg , I2cstat ; Restore Sreg
             reti                  ; return from interrupt
    
    
    ;****************
    ;* Skip byte(s) *
    ;****************
    
    I2c_skip_byte:
                                  ; set counter initial value
             ldi temp,-7
             Out Tcnt0 , Temp
                                  ; enable timer 0 overflow interrupt
       ;orginal: ldi temp,(1<<TOIE0)
    
             clr temp             ;                             eingefügt
             sbr temp,&b00000010  ;                             geändert
             Out Timsk , Temp
                                  ; disable external interrupt request 0
       ;orginal: ldi temp,(0<<INT0)
    
             clr temp             ;                             eingefügt
             sbr temp,&b00000000  ;                             geändert
             Out Gimsk , Temp
    
             Out Sreg , I2cstat ; Restore Sreg
             reti
    
    
    ;***************************************************************************
    ;*
    ;* FUNCTION
    ;* i2c_init
    ;*
    ;* DESCRIPTION
    ;* Initialization of interrupts and port used by the I2C interface
    ;* and waits for the first start condition.
    ;*
    ;* USAGE
    ;* Jump to this code directly after a reset.
    ;*
    ;* RETURN
    ;* none
    ;*
    ;* NOTE
    ;* Code size can be reduced by 12 instructions (words) if no transfer
    ;* is started on the I2C bus (bus free), before the interrupt
    ;* initialization is finished. If this can be ensured, remove the
    ;* "Wait for I2C Start Condition" part and replace it with a "sei"
    ;* instruction.
    ;*
    ;***************************************************************************
    
    Reset:
    I2c_init:
    
    ;**** PORT Initialization ****
    
                ; Initialize PD2 (INT0) for open colector operation (SDA in/out)
    
        ;orginal: ldi temp,(0<<DDD4)+(0<<DDD2)
    
             clr temp             ;                             eingefügt
             sbr temp,&b00000000  ;                             geändert
             Out Ddrd , Temp
    
                ; Initialize PD4 (T0) for open colector operation (SCL in/out)
    
        ;orginal: ldi temp,(0<<PD4)+(0<<PD2)
    
             clr temp             ;                             eingefügt
             sbr temp,&b00000000  ;                             geändert
             Out Portd , Temp
    
    ;**** Interrupt Initialization ****
    
                ; Set INT0 to generate an interrupt on falling edge
    
        ;orginal: ldi temp,(1<<ISC01)+(0<<ISC00)
    
             clr temp             ;                             eingefügt
             sbr temp,&b00000010  ;                             geändert
             Out Mcucr , Temp
    
                ; Enable INT0    -> Freigeben INT0 !!!
    
    
             clr temp
             sbr temp,&b01000000  ;setzt bit 6 des Reg. Gimsk ( = INT0) auf 1 / on
             Out Gimsk , Temp
    
    
                ; Set clock to count on falling edge of T0
    
        ;orginal: ldi temp,(1<<CS02)+(1<<CS01)+(0<< CS00)
    
             clr temp             ;                             eingefügt
             sbr temp,&b00000110  ;                             geändert
             Out Tccr0 , Temp
    
    
    ;***************************************************
    ;* Wait for I2C Start Condition (13 intstructions) *
    ;***************************************************
    
    Do_start_w:
                                  ; Do
    
             in temp,PIND         ;  sample SDA & SCL
             com temp             ; invert
         ;orginal: andi temp,pinmask  ; mask SDA and SCL
             andi R16,0x14        ;                             geändert
             brne do_start_w      ; while (!(SDA && SCL))
    
             in temp,PIND         ; sample SDA & SCL
         ;orginal: andi temp,pinmask  ; mask out SDA and SCL
             andi R16,0x14        ;                             geändert
    Do_start_w2:
                                  ; Do
             in etemp,PIND        ; new sample
         ;orginal: andi etemp,pinmask ; mask out SDA and SCL
             andi R17,0x14        ;                             geändert
             cp etemp,temp
             breq do_start_w2     ; while no change
    
             sbrc etemp,PIND2     ; if SDA no changed to low
             rjmp do_start_w      ; repeat
    
             rcall i2c_get_adr    ; call(!) interrupt handle (New transfer)
    
    
    ;***************************************************************************
    ;*
    ;* PROGRAM
    ;* main - Test of I2C slave implementation
    ;*
    ;***************************************************************************
    
    Main:
             Rjmp Main            ; Loop Forever
    
    
    ;**** End of File ****
    
    $end Asm
    
    
    
    Bearbeitung:
    
       Daten = Peek(0)
       Config Portb = Output
       Portb = &B11111111         'alle LED aus
    
    
       If Daten = 1 Or Daten = 11 Then Gosub Servo_1
       If Daten = 2 Or Daten = 12 Then Gosub Servo_2
       If Daten = 3 Or Daten = 13 Then Gosub Servo_3
       If Daten = 4 Or Daten = 14 Then Gosub Servo_4
       If Daten = 5 Or Daten = 15 Then Gosub Servo_5
    
    
    Return
    
    Servo_1:
    
       If Daten = 11 Then Goto Servo_1_links
    
    '-----------------------------------------------
    Servo_1_rechts:
    
       For I = 1 To 18            'nach rechts
          Portb.1 = 0
          Waitms 20
          Portb.1 = 1
          Waitms 1
       Next I
       Portb.1 = 0
    Return
    
    Servo_1_links:
    
       For I = 1 To 18            'nach links
          Portb.1 = 1
          Waitms 20
          Portb.1 = 0
          Waitms 20
       Next I
    
    Return
    '-----------------------------------------------
    Servo_2:
    
       If Daten = 12 Then Goto Servo_2_links
    
       For I = 1 To 18            'nach rechts
          Portb.2 = 0
          Waitms 20
          Portb.2 = 1
          Waitms 1
       Next I
       Portb.2 = 0
    Return
    
    Servo_2_links:
    
       For I = 1 To 18            'nach links
          Portb.2 = 1
          Waitms 20
          Portb.2 = 0
          Waitms 20
       Next I
    
    Return
    '-----------------------------------------------
    Servo_3:
       If Daten = 13 Then Goto Servo_3_links
    
       For I = 1 To 18            'nach rechts
          Portb.3 = 0
          Waitms 20
          Portb.3 = 1
          Waitms 1
       Next I
       Portb.3 = 0
    Return
    
    Servo_3_links:
    
       For I = 1 To 18            'nach links
          Portb.3 = 1
          Waitms 20
          Portb.3 = 0
          Waitms 20
       Next I
    Return
    '-----------------------------------------------
    Servo_4:
       If Daten = 14 Then Goto Servo_4_links
    
       For I = 1 To 18            'nach rechts
          Portb.4 = 0
          Waitms 20
          Portb.4 = 1
          Waitms 1
       Next I
       Portb.4 = 0
    Return
    
    Servo_4_links:
    
       For I = 1 To 18            'nach links
          Portb.4 = 1
          Waitms 20
          Portb.4 = 0
          Waitms 20
       Next I
    Return
    '-----------------------------------------------
    Servo_5:
       If Daten = 15 Then Goto Servo_5_links
    
       For I = 1 To 18            'nach rechts
          Portb.5 = 0
          Waitms 20
          Portb.5 = 1
          Waitms 1
       Next I
       Portb.5 = 0
    Return
    
    Servo_5_links:
    
       For I = 1 To 18            'nach links
          Portb.5 = 1
          Waitms 20
          Portb.5 = 0
          Waitms 20
       Next I
    Return
    '-----------------------------------------------

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.03.2004
    Ort
    Paderborn
    Alter
    40
    Beiträge
    614
    Irgendwie hilft mir dieser Quelltext beim I2C-Bus nicht sonderlich weiter.
    1. Kann das Programm nur ein PWM-Signal für die Maximalausschläge machen? Also lässt sich keine Position sondern nur eine Richtung angeben und die tatsächliche Servoposition muss gemessen und dann das Servo in die richtige Richtung gedreht werden? Wozu dann ein Co-Controller?
    2. Zu den I2C-Befehlen: Wie ist das mit denen, die Bascom schon hat? Brauch ich diesen Assebler-Kram trotzdem? Eingentlich will ich nur einzelne Werte übertragen und an einem anderen µC empfangen.

  5. #5
    Administrator Robotik Visionär Avatar von Frank
    Registriert seit
    30.10.2003
    Beiträge
    5.116
    Blog-Einträge
    1
    Wenn Du Controller als Slave benutzen willst dann kommst du an Assembler nicht ganz vorbei. Außer du nimmst die I2C-Slave Libary (5 Euro) vom Bascom-Hersteller.

    Wenn es um Servos geht, dann kannst Du ja nun Kjions Servo-Programm in den Atmel Controller 90S2313 laden (im Download Bereich). Zum Beispiel beim Board RNBFRA (ich glaub das hast Du ja). Momentan kann dieser allerdings nicht mit Bascom I2C-Befehlen angesteuert werden da Kjions Software noch nicht die volle I2C Bus-Geschwindigkeit unterstützt (soll aber später noch optimiert werden). Ich hab aber eine kleine Engine geschrieben die neue I2C-Befehle, Servo-Befehl, Port-Befehle etc. für RNBFRA beinhaltet. Ist noch nicht ganz fertig weil ich derzeit selten dazu komme. Werde aber in Kürze schon mal die erste Version posten. Man kann dann einfach per Include die Datei in sein Basic Programm einbinden und kann dann alle wichtigen Funktionen des RNBFRA-Boards bequem per Basic-Subroutine steuern und muß nicht als mit den I2C-Befehlen hantieren. Das schreiben von Programmen wird dann noch ne ganze Ecke einfacher

    Gruß Frank

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.03.2004
    Ort
    Paderborn
    Alter
    40
    Beiträge
    614
    Erstmal danke, Frank: Die Bascom-Befehle sind also nur zum Senden...
    Einen 90S2313, der Servos stellen kann, hab' ich mir schon gebastelt (ne, ähm das RNBFRA-Board hab' ich nicht, sondern 'nen Eigenbau).
    Ich würde jetzt gern die gewünschte Servostellung (insgesamt ca. 10byte für die maximal vorgesehene Anzahl) von einer anderen Quelle entgegennehmen.
    Was ist mit dem Befehl "I2creceive" von Bascom? Kann ich dem Empfänger nicht über einen Interupt oder so mitteilen, dass es neue Werte gibt und der empfängt die dann (oder der Servo-AVR "fragt" regelmäßig bei dem anderen die neuen Werte ab?)? Oder geht der Befehl auch nur mit der extra-Library?
    PS: Wie lange dauert so ein Zyklus dann (die Servos sind ja solange ohne Ansteuerung.)?
    Kann ich das PWM Signal innerhalb eines Modulationsintervalls einfach abbrechen(zum Empfangen der neuen Stellung und dann neu senden) oder ändert das noch die Stellung, wenn der letzte Pulz zu kurz ist?

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.03.2004
    Ort
    Paderborn
    Alter
    40
    Beiträge
    614
    Ach ja: Was passiert eigentlich, wenn während des Sendens mit Bascom-I2C-Befehl ein Interupt 'reinkommt?

  8. #8
    Administrator Robotik Visionär Avatar von Frank
    Registriert seit
    30.10.2003
    Beiträge
    5.116
    Blog-Einträge
    1
    Hi,

    ja sicher man könnte Baustein über einen Port ode IRQ darauf aufmerksam machen das es neue Servodaten gibt und er die quasi als Master abrufen soll. Aber dann hättest du ja das Problem mit dem anderen COntroller - denn der müsste nu als Slave programmiert werden Außerdem wäre es Murks wenn ich es mal so sagen darf.

    Nö ich würde baustein dann schon vernünftig als Slave programmieren, entweder mit der genannten Libary die du für 5 Euro bekommst oder halt mit oberer Assembler Routine (die hab ich aber nicht ausprobiert).
    Das heißt der Hauptcontroller spricht den Servobaustein per I2C an und überträgt ihm die neuen Servo Positionen. Die IC2 Libary nutzt dazu auch einen Interruptfähigen Eingang als I2C-Port.
    Ein Problem besteht dann darin das vermutlich deine Servosteuerung kurz unterbrochen wird (während der I2C Übertragung). Inwieweit das deine Servosteuerung beeinflußt mußt du selbst wissen, mit der genauen Impulsgenerierung für die Servos hab ich mich nicht beschäftigt. Da kann Kjion sicher was zu sagen, denn er kennt das Problem. Er sperrt Interrupts während der Servo-Signalgenerierung soweit ich mich erinnere. Dadurch ist aber dann die volle I2C Geschwindigkeit nicht mehr möglich (es würden Takte verpaßt werden).

    Wozu I2creceive ist weiß ich aus dem stehgreif garnicht. Ich nehme aber an das er die I2C-Grundfunktionen I2CSTART , I2CSTOP , I2CRBYTE
    einfach zusammenfaßt und einige Bytes liest. Abrufen und senden von Bytes ist ja als Master möglich.

    Das Beispiel hab ich gefunden:

    Code:
    Example
    
    Config Sda = Portb.5
    Config Scl = Portb.7
    Dim X As Byte , Slave As Byte
    X = 0                                                       'reset variable
    Slave = &H40                                'slave address of a PCF 8574 I/O IC
    I2creceive Slave , X                                     'get the value
    Print X                                                     'print it
    Das gleiche geht auch mit I2CSTART , I2CSTOP , I2CRBYTE .

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.11.2003
    Beiträge
    991
    Hi,
    PS: Wie lange dauert so ein Zyklus dann (die Servos sind ja solange ohne Ansteuerung.)?
    Beliebig, das ist ja das Problem. Es kann ganz schnell sein, aber theoretisch auch einen Takt pro Stunde...
    Kann ich das PWM Signal innerhalb eines Modulationsintervalls einfach abbrechen(zum Empfangen der neuen Stellung und dann neu senden)
    Kann ab und zu funktionieren, in den meisten Fällen werden allerdings die Servos wild umherzucken.
    ändert das noch die Stellung, wenn der letzte Pulz zu kurz ist?
    Das würde auf jeden Fall passieren...

    Ein Problem besteht dann darin das vermutlich deine Servosteuerung kurz unterbrochen wird (während der I2C Übertragung). Inwieweit das deine Servosteuerung beeinflußt mußt du selbst wissen, mit der genauen Impulsgenerierung für die Servos hab ich mich nicht beschäftigt. Da kann Kjion sicher was zu sagen, denn er kennt das Problem. Er sperrt Interrupts während der Servo-Signalgenerierung soweit ich mich erinnere. Dadurch ist aber dann die volle I2C Geschwindigkeit nicht mehr möglich (es würden Takte verpaßt werden).
    Bei mir ists im Moment so, dass der Empfang der I2C Befehle im Hauptprogramm passiert. Die Servoansteuerung erfolgt über Timerinterrupts im Hintergrund. Das heißt allerdings, dass die Timerinterrupts zu jedem beliebigen Zeitpunkt auftreten können und damit das schöne Timing vermasseln...
    Ohne die Servoansteuerung funktionierts auch mit vollen Geschwindigkeit ( hab mir zum Testen mal ein kleines I2C Display gebastelt )

    Von dem Code der Oben für die Servoansteuerung gepostet wurde hat übrigens noch ein paar größere Fehler:
    Die Servos werden nur angesteuert wenn ein Signal empfangen wurde. Das heißt man muss ständig die Positionen neu senden wenn man das Servo irgendwie belasten will. Des weiteren kann man keine Befehle empfangen während die Servos angesteuert werden. Das heißt man muss nach dem Senden eines Befehls erst eine Pause von mindestens 22 ms einhalten...

    Ach ja: Was passiert eigentlich, wenn während des Sendens mit Bascom-I2C-Befehl ein Interupt 'reinkommt?
    Als Master ist das ja egal, da man da beliebig viel Zeit zum Senden hat. Ansonsten wird halt die Senderoutine kurz unterbrochen und der Interrupt abgearbeitet...

    MfG Kjion

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.03.2004
    Ort
    Paderborn
    Alter
    40
    Beiträge
    614
    Abrufen und senden von Bytes ist ja als Master möglich.
    Als Master ist senden und Empfangen möglich?
    Was spricht dann gegen zwei als Master configurierte AVRs?
    Der Haupt-AVR löst einen Interupt beim Servobaustein aus, wenn sich die Positionswerte verändert haben. Der macht dann noch sein Signal fertig und unterbricht dann kurz und führt I2CReceive oder I2CRBYTE aus. Der sendende AVR wartet dann einfach so lange, bis das Servosignal auf jeden Fall fertig ist (max. 2ms) und schickt dann die neue Position (wenn der Servo-AVR früher schon versucht zu empfangen, sollte dem das nix machen oder?).
    Dass dann ganz kurz garkein Signal zu den Servos kommt, wird denen nix machen (wenn ich die Modellfernsteuerung ausmache, bleiben die ja auch einfach stehen.).

Seite 1 von 5 123 ... LetzteLetzte

Benutzer, die dieses Thema gelesen haben: 0

Derzeit gibt es keine Benutzer zum Anzeigen.

Berechtigungen

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

LiTime Speicher und Akkus