I2C AVR-Master To AVR-Slave Bytes!

Hogyan programozzak AVR chipet? Programozók beállításai...
Bascom nyelvű programok...
Válasz küldése
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

I2C AVR-Master To AVR-Slave Bytes!

Hozzászólás Szerző: kapu48 »

Némileg módosítottam a rutinokat.
Több Bytes küldése céljából!
Ha valakinek pont ez kellene!

Ezek a rutinok Fix méretű a „Const I2c_bytes = 15”-ben megadot csomag átküldésére jók!
Az „ Dim I2c_byte(i2c_bytes) As Byte ' I2C Bytes tároló tömb „ –be pakolt értékeket küldjük el, és oda is érkezik a Slave oldalon.

Eredetileg 2 csatornás ADC méréseket küldött! (Még benne maradtak a nyomai. de csak a tanulás kedvéért! Ha nem kel kikel gyomlálni!)

Kód: Egész kijelölése


   ' I2C-Master2.bas
   ' Sendet kontinuierlich über I2C-Bus einen Byte-Wert und 2 ADC-Werte (10 Bit) über den Bus.
   ' Dieser Master verwendet das Hardware-TWI.
   ' Der Byte-Wert wird mit Datenpaket inkrementiert. Die ADC-Werte werden per Poti
   ' An den Eingängen ADC0 und ADC1 abgenommen.


   $regfile = "m128def.dat"                                 ' Atmega 8 Controller
   $crystal = 16000000                                      ' intern 8MHz

   Const Slave_address = &H20 * 2                           ' Adresse des Slave (*2)
   'Megadhatod I2C-n átküldött Bytek számát
   Const I2c_bytes = 15                                     'Kötelező: Master.bas = Slave.bas

   '-------------------------------------------------------------------------------
'                                       LCD
'-------------------------------------------------------------------------------
Config Lcdpin = Pin , Db4 = Porta.2 , Db5 = Porta.3 , Db6 = Porta.4 , Db7 = Porta.5 , E = Porta.1 , Rs = Porta.0
Config Lcd = 20 * 4
Initlcd
Cursor Off                                                  'Cursor Off : Cls : Locate 1 , 1
Cls

Config Timer1 = Pwm , Pwm = 8 , Compare C Pwm = Clear Down , Prescale = 1       ' Keyboard
Config Timer3 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Prescale = 1       ' LCD Backlight

Stop Timer0
Enable Interrupts
Pwm3a = 10
Pwm1c = 5

   ' Variablen
'   Dim Adc_wert1 As Word                                    ' ADC_Wert1
'   Dim Adc_wert1l As Byte At Adc_wert1 Overlay              ' Low-Byte  ADC-Wert1
'   Dim Adc_wert1h As Byte At Adc_wert1 + 1 Overlay          ' High-Byte ADC_Wert1

'   Dim Adc_wert2 As Word                                    ' ADC_Wert2
'   Dim Adc_wert2l As Byte At Adc_wert2 Overlay              ' Low-Byte  ADC-Wert2
'   Dim Adc_wert2h As Byte At Adc_wert2 + 1 Overlay          ' High-Byte ADC_Wert2

   Dim Bytewert As Byte                                     ' Byte-Wert
   Dim I2c_byte(i2c_bytes) As Byte                          ' I2C Bytes tároló tömb
   Dim I As Byte

   Config Adc = Single , Prescaler = Auto , Reference = Internal
   Start Adc

   $lib "i2c_twi.lbx"                                       ' Hardware-TWI verwenden
   Config Twi = 100000                                      ' Übertragungsrate 100000 Bits/Sek.
   Config Sda = Portd.1                                     ' SDA-Port
   Config Scl = Portd.0                                     ' SCL-Port

   I2cinit                                                  ' Initialisierung der TWI
   Waitms 500

'  ------------------------------------------------------------------
'     Hauptschleife
'  ------------------------------------------------------------------
'   Adc_wert1l = 1
'   Adc_wert1h = 1
'  I2c_byte() Tömb feltöltése
For I = 1 To I2c_bytes
     I2c_byte(i) = I                                        ' Ide rakjad a küldendő Byte-ket
Next I
   Do
      'Adc_wert1 = Getadc(0)                                 ' erster ADC-Wert einlesen
      'Adc_wert2 = Getadc(1)                                 ' zweiter ADC-Wert einlesen
      'Incr Bytewert

      ' Daten an den Slave per Slave-Adresse senden
      ' Reigenfolge der Datenbytes beachten
'(
      I2cstart                                              ' Start Senden
         I2cwbyte Slave_address                             ' Slave-Adresse (&h20)
         I2cwbyte Bytewert                                  ' 1. Datenbyte: Bytewert senden
         I2cwbyte Adc_wert1l                                ' 2. Datenbyte: Low-Byte ADC-Wert1 senden
         I2cwbyte Adc_wert1h                                ' 3. Datenbyte: High-Byte ADC-Wert1 senden
         I2cwbyte Adc_wert2l                                ' 4. Datenbyte: Low-Byte ADC-Wert2 senden
        I2cwbyte Adc_wert2h                                 ' 5. Datenbyte: High-Byte ADC-Wert2 senden
      I2cstop                                               ' Stop senden
')
      I2cstart                                              ' Start Senden
         I2cwbyte Slave_address                             ' Slave-Adresse (&h20)
'         I2cwbyte Bytewert                                  ' 1. Datenbyte: Bytewert senden
         For I = 1 To I2c_bytes
            I2cwbyte I2c_byte(i)                            '  I2c_bytes számú Bytes átküldés
         Next I
      I2cstop                                               ' Stop senden
      Waitms 20
      Cls : Locate 1 , 1 : Lcd I2c_byte(i)                  ' Oszi synchronisiert besser
   Loop
A hozzászólást 6 alkalommal szerkesztették, utoljára kapu48 2011. december 18. vasárnap, 15:00-kor.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Kód: Egész kijelölése


   ' I2C-Slave2.bas
   ' Demo zur Verwendung des Moduls TWI_Slave_Receiver.bas

   ' erstellt:          09.01.2010
   ' letzte Änderung:   09.01.2010
   ' Autor:             M. Ruhwald (www.MitchSoft.de)

   ' Beschreibung:
   ' Dieser Slave generiert mit Timer1 eine Hardware-PWM (10 Bit)
   ' Die empfangenen ADC-Werte des Masters (Poti) werden zur Steuerung der PWM
   ' OC1A und OC1B verwendet.

   ' Der Empfang ist auf Interrupt gestellt, kein General Call aktiviert.


   $regfile = "m88pdef.dat"                                 ' Atmega 8 Controller
   $crystal = 16000000                                      ' intern 8MHz
   'Megadhatod I2C-n Vett Bytek számát
   Const I2c_bytes = 15                                     'Kötelező: Master.bas = Slave.bas

   ' Variablen
'   Dim Adc_wert1 As Word                                    ' ADC_Wert1
'   Dim Adc_wert1l As Byte At Adc_wert1 Overlay              ' Low-Byte  ADC-Wert1
'   Dim Adc_wert1h As Byte At Adc_wert1 + 1 Overlay          ' High-Byte ADC_Wert1

'   Dim Adc_wert2 As Word                                    ' ADC_Wert2
'   Dim Adc_wert2l As Byte At Adc_wert2 Overlay              ' Low-Byte  ADC-Wert2
'   Dim Adc_wert2h As Byte At Adc_wert2 + 1 Overlay          ' High-Byte ADC_Wert2

   Dim Bytewert As Byte                                     ' ByteWert
   Dim Twi_byte_nummer As Byte                              ' Zähler für empfangene Datenbytes
   Dim I2c_byte(i2c_bytes) As Byte                          ' I2C Bytes tároló tömb
   Dim I As Byte
   Dim I2crec_ok As Bit                                     'I2C Adatok érkeztek jelző

   ' Timer für 10-Bit PWM konfigurieren (PWM-Frequenz 488 Hz)
  ' Config Timer1 = Pwm , Pwm = 10 , Prescale = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
   'Config Portb.1 = Output                                  ' OC1A-Port als Ausgang
   'Config Portb.2 = Output                                  ' OC1B-Port als Ausgang
   Config Portc.0 = Output
   Lr1 Alias Portc.0
   $include "TWI_Slave_Receiver2.bas"                       ' Einbinden und Initialisieren TWI

   '  I2c_byte() Tömb törlése
   For I = 1 To I2c_bytes
      I2c_byte(i) = 0                                       ' Ide rakja a kapot Byte-ket
   Next I
   I2crec_ok = 0
   Enable Interrupts                                        ' Interrupts müssen aktiviert sein

   Do
      'rcall _TWI_Slave_DatenEmpfang                         ' Bei Polling Empfangsroutine aufrufen
      NOP
      'Itt feldolgozhatod a beérkezett biteket Főprogramban
      If I2crec_ok = 1 Then
          'I2C érkezett Adat feldolgozás ....
'  I2c_byte() Tömb feldolgozása

      For I = 1 To I2c_bytes
         Print I2c_byte(i) = I ; ","                        ' Idéglenesen Ki irja a fogadot Byte-ket
      Next I
      I2crec_ok = 0                                         'Feldolgozás megtörtént
      End If
   Loop

   ' Daten verarbeiten vom Master
   ' Routine wird bei letztem empfangenen Datenbyte
   ' von TWI-Empfangs-Routine aufgerufen
   'Itt feldolgozhatod a beérkezett biteket  Megszakításban
   Twi_daten_ok:
   '  I2c_byte() Tömb feldolgozása

      For I = 1 To I2c_bytes
         Print I2c_byte(i) = I ; ","                        ' Idéglenesen Ki irja a fogadot Byte-ket
      Next I
      Print

   Return
'(
   Twi_daten_verarbeiten:
      If Adc_wert1 = 257 Then
         Set Lr1
        Else
        Reset Lr1
      End If

      'Compare1a = Adc_wert1                                 ' OC1A-PWM
      'Compare1b = Adc_wert2                                 ' OC1B-PWM
      ' ByteWert könnte für 3. PWM-Kanal werwendet werden
   Return
')
A hozzászólást 2 alkalommal szerkesztették, utoljára kapu48 2011. december 18. vasárnap, 14:52-kor.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Kód: Egész kijelölése


 'TWI_Slave_Receiver2.bas
 ' Modósítva Bytes fogadásra  By: Kapu48
'  *********************************************************
'  *  I2C-Bus Empfänger (Slave Receiver)                   *
'  *                                                       *
'  *  Eigenschaften:                                       *
'  *     - Datenempfang per Interrupt wird unterstützt     *
'  *     - Datenempfang per Polling wird unterstützt       *
'  *     - General Call wird unterstützt                   *
'  *     - Einfache Einbindung per Include                 *
'  *                                                       *
'  *********************************************************

'  Modul für TWI_Slave_Receiver2.bas
'  Autor:            M. Ruhwald (www.MitchSoft.de)
'  erstellt:         09.01.2010
'  letzte Änderung:  09.01.2010

'  ------------------------------------------------------------------------------------------------

   $nocompile                                               ' Hardware TWI Receiver-Modul

'  ----------------------------------------------------------------------------
'  Konfiguration des Slave-Receiver
'  ----------------------------------------------------------------------------

   ' die folgenden drei Konstanten bitte angeben

   Const Twi_general_call = 0                               ' General Call verwenden ( 1 = an / 0 = aus )
   Const Twi_use_interrupt = 1                              ' Interrupt-Empfang ( 1 = an / 0 = aus )
   Const Twi_slave_address = &H20                           ' Slave-Adresse dieses Moduls (Voreingestellt Adresse &h40)


'  ----------------------------------------------------------------------------
'  Initialisierung
'  ----------------------------------------------------------------------------

   ' Berechnung Addressregister
   Const _twi_slave_init_address = Twi_slave_address * 2 + Twi_general_call

   Dim Twi_status As Byte


   #if Twi_use_interrupt = 1                                ' Initialisierung (Interrupt)
      On Twi _twi_slave_datenempfang                        ' Festlegen der Empfangs-Routine
      rcall _Twi_slave_init                                 ' Initialisieren der TWI
      Enable Twi                                            ' Interrupt einschalten
   #else                                                    ' Initialisierung (Polling)
      rcall _Twi_slave_init                                 ' Initialisieren der TWI
   #endif

'  ----------------------------------------------------------------------------
   rjmp _TWI_Slave_Exit
'  ----------------------------------------------------------------------------



'  ----------------------------------------------------------------------------
'  TWI-Routinen
'  ----------------------------------------------------------------------------

'  Initialisierungs-Routine der TWI
   _twi_slave_init:
      Twsr = 0                                              ' Statusregister löschen
      Twbr = 0                                              ' Bautratenregister muss 0 sein
      Twdr = &HFF                                           ' Datenregister auf Default setzen
      Twar = _twi_slave_init_address                        ' Slave-Adresse festlegen
      Twcr = &B01000100                                     ' Initialisierung (TWAE + TWEN setzen)
   Return

'  -------------------------------------------------
'  TWI-Empfangs-Routine

   _twi_slave_datenempfang:
   #if Twi_use_interrupt = 0
      If Twcr.twint = 1 Then
   #endif
      Twi_status = Twsr And &HF8                            ' Status-Register einlesen (Bit 0-2 ausblenden)
      If Twi_status = &HA0 Then                             ' Stop oder erneute Start-Kondition
         Twi_byte_nummer = 0

      Elseif Twi_status = &H60 Or Twi_status = &H68 Then    ' Adressierung per Slave-Adresse (Master will schreiben)
         Twi_byte_nummer = 0

      Elseif Twi_status = &H80 Or Twi_status = &H88 Then    ' Daten per Slave Adresse empfangen (Master schreibt)
         Incr Twi_byte_nummer
         Select Case Twi_byte_nummer
            Case Is < I2c_bytes :                           ' 1 - 14, Datenbyte:
               I2c_byte(twi_byte_nummer) = Twdr             ' Bytewert aus Datenregister lesen

            Case I2c_bytes :                                ' 15. Datenbyte:
                I2c_byte(twi_byte_nummer) = Twdr
                I2crec_ok = 1                               'I2C Adatpuffer megtelt
               ' jetzt müssen Daten verarbeitet werden. Am besten ein GoSub in eine eigene Routine.
               ' Most, adatot kell feldolgozni. A legjobb saját GoSub rutin
               Gosub Twi_daten_ok                           'Ugrás Ha a megszakításban felakarod dolgozni a kapott adatokat
         End Select

   #if Twi_general_call = 1                                 ' nur bei eingeschaltetem General Call

      Elseif Twi_status = &H70 Or Twi_status = &H78 Then    ' Adressierung per General Call
         NOP

      Elseif Twi_status = &H90 Or Twi_status = &H98 Then    ' Daten per General Call
         Ocr2 = Twdr

   #endif

      End If
   #if Twi_use_interrupt = 1
      Twcr = &B11000101                                     ' bei Interrupt: TWINT + TWAE + TWEN + TWIE setzen
   #else
      Twcr = &B11000100                                     ' bei Polling: TWINT + TWAE + TWEN
      End If                                                ' (gehört zu: 'If TWCR.TWINT=1 then' bei Polling-Betrieb)
   #endif
   Return

'  ----------------------------------------------------------------------------
   _twi_slave_exit:
'  ----------------------------------------------------------------------------
Teszteljétek!?
8)
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Több útmutató:
http://avr.tavir.hu/modules.php?name=Co ... age&pid=17

Illetve az Arduino keretrendszerben (0022) az I2C: wire néven fut. inicializálható egyből Master és Slave módon is :)
Válasz küldése