- Labornetzteil AliExpress         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 16 von 16

Thema: 2 MEGA8 mit UART

  1. #11
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Anzeige

    Powerstation Test
    Klaro, jetzt haben wir eine Runde, wo jeder mal reden kann. Aber wenn z.B. zwei Master (o.k, nacheinander) dem dritten gegenseitig die register und commands niederschreiben, kann es haarig werden.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  2. #12
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    28.02.2005
    Ort
    Salzburg
    Alter
    44
    Beiträge
    464
    Wie könnte ich den nbei I2C den Mega8 eine Slaveadresse geben.
    Das Register ist bei mir nicht verfügbar. Ich hab gelesen, dass es eine eigene
    Library in Bascom gibt, mit der ich mit Hi-Level-Befehlen arbeiten kann.
    Oder wenn jemand einen Beispielcode für den Slavebetrieb hat, wäre ich sehr dankbar.
    Ich möchte damit Single-Werte und Befehle, also Strings an den anderen übertragen.

  3. #13
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Bei Atmega... heißt der I2C TwoWireSerialInterface (TW)
    Der mega8 hat alle register (samt Slave Addr), die der Mensch braucht und die sind im Datasheet recht genau beschrieben
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  4. #14
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    28.02.2005
    Ort
    Salzburg
    Alter
    44
    Beiträge
    464
    wenn ich es schaffe den mc eine slaveadresse zu geben, wohin wird dann das byte das ich sende im anderen mc geschrieben?
    By the way, die Subroutinen für die TWI funktioniernen bei mir.
    Habe schon externe serielle eeprom´s beschrieben und ausgelesen.
    Nur wie das mei 2 mc´s geht weis ich nicht.
    Logischerweise würde ich vermuten, dass die byte´s in den eigenen eeprom
    geschrieben werden mir einer adresse die ich bei der twi angebe.
    Ist das richtig so?

  5. #15
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    "SLAVE" heißt, daß er einen Interrupt startet, wenn irgendein Master deine Adresse in den Bus geschrieben hat. (+ R/W)
    WAS der slave mit den empfangenen Bytes macht, und als was er sie interpretiert, hängt von ihm ab. Schau dir z.B. die diversen I2C Peripheriegeräte an, da siehst du ja, was alles möglich ist.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  6. #16
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    37
    Beiträge
    215
    Ja PicNick hat recht. Es wird einfach ein TWI Interrupt gestartet. Dort kann man das TWBR Register abfragen.
    Theoretisch hab ich sowas mal gemacht mit WinAVR. Vielleicht hilfts dir.
    Es gibt 5 read only Register und 5 write only Register.
    Code:
    #include <avr/io.h>
    #include <avr/signal.h>
    #include <avr/interrupt.h>
    #include <avr/twi.h>
    
    #define i2c_slave_init TWCR= _BV(TWEA) | _BV(TWEN) | _BV(TWIE) 
    // Slave init und I2C Interrupt enable
    
    #define slave_addr_init TWAR |= _BV(TWA0)
    // Slave addresse auf 0x10 also auf 10, keine reaktion auf globale anfragen
    
    // Die read_only Register werden im Hauptprogramm regelmäßig mit z.B. Sensorwerten aktuallisiert
    // Die write_only Register werden regelmäßig im Hauptprogramm ausgelesen um auf deren Werte zu reagieren
    volatile unsigned char read_register1,read_register2,read_register3,read_register4,read_register5;
    volatile unsigned char write_register1,write_register2,write_register3,write_register4;
    volatile unsigned char regwrite_flag=0; 
    volatile unsigned char regvalue=0;
    
    SIGNAL(SIG_2WIRE_SERIAL)
    {
       if(TWSR==TW_SR_SLA_ACK|TWSR==TW_SR_ARB_LOST_SLA_ACK|TWSR==TW_SR_DATA_ACK)   // Slave Reciever Datenpaket empfangen
       {
          if(regwrite_flag==1)
    	  {
    	     if(regvalue==6){                
    		   write_register1=TWDR;
    		   regwrite_flag=0;
    		   regvalue=0;}
    	     if(regvalue==7){                
    		   write_register1=TWDR;
    		   regwrite_flag=0;
    		   regvalue=0;}
    		 if(regvalue==8){                
    		   write_register1=TWDR;
    		   regwrite_flag=0;
    		   regvalue=0;}
    		 if(regvalue==9){                
    		   write_register1=TWDR;
    		   regwrite_flag=0;
    		   regvalue=0;}
    		 if(regvalue==10){                
    		   write_register1=TWDR;
    		   regwrite_flag=0;
    		   regvalue=0;}
    	  }
    	  else
    	  {
    	  if(TWDR==1){                          // Register 1 until 5 only read; 
    	     TWDR=read_register1;
    		 TWCR|=(1<<TWINT);}
    	  else if(TWDR==2){
    	     TWDR=read_register2;
    		 TWCR|=(1<<TWINT);}
    	  else if(TWDR==3){
    	     TWDR=read_register3;
    		 TWCR|=(1<<TWINT);}
    	  else if(TWDR==4){
    	     TWDR=read_register4;
    		 TWCR|=(1<<TWINT);}
    	  else if(TWDR==5){
    	     TWDR=read_register5;
    		 TWCR|=(1<<TWINT);}
    	  else if(TWDR==6||TWDR==7||TWDR==8||TWDR==9||TWDR==10){ 	  // Register 6-10 write only register.
             regwrite_flag=1;   // Flag wird gesetzt damit beim nächsten mal der TWDR Wert als Registerinhalt
    		 regvalue=TWDR;     // und nicht als Registernummer interpretiert wird.
    		 TWCR|=(1<<TWINT);}
    	  
    		 
    	  // Hier könnte man noch weiter Befehle eingeben die dann mit der Entsprechenden TWDR ausgeführt werden
          }
       }	  
       else if(TWSR==TW_SR_DATA_NACK)
          TWCR = (1<<TWINT) | (1<<TWEA);
       else if(TWSR==TW_ST_SLA_ACK|TWSR==TW_ST_ARB_LOST_SLA_ACK|TWSR==TW_ST_DATA_ACK) // Dann ist Slave Transmitter mode und es wird einfach das byte in TWDR
          TWCR |= (1<<TWINT);                     // Versand
       else if(TWSR==TW_ST_DATA_NACK|TWSR==TW_ST_LAST_DATA)
          TWCR = (1<<TWINT) | (1<<TWEA);
       else if(TWSR==TW_SR_STOP)              // STOP condition has been recevied
          TWCR=(1<<TWINT) | (1<<TWEA);
    TWCR |= 0b10000000;
    }
    
    
    void main(void)
    {
       i2c_slave_init;
       slave_addr_init;
       for(;;)
       {
          /* read_register1=   ;
    	     read_register2=   ;
    	     read_register3=   ;
    	     read_register4=   ;
    	     read_register5=   ;
    	   
             if(write_register1==  )
    		 
    	     if(write_register2==  )
    
    	     if(write_register3==  )
    
    	     if(write_register4==  )
    
    	     if(write_register5==  )
    
          */
       }
    }
    Ich hab auch mal was für SPI geschrieben. Dabei können beide Master und Slave werden. Allerdings auch nur theoretisch, also ich hatte noch keine Möglichkeit es zu testen. Hab leider keine zwei ATmega.
    Code:
    /* Es gibt hier keinen Slave oder Master. Beide können beides werden. Es wird jeweils der SS_Master 
       Pin des einen  mit dem SS_Slave Pin des anderen verbunden. In SPI_init wird der SS_Master Pin auf
       high gesetzt womit der SS_Slave Pin(SSPin/PB4 beim ATMEga32) des anderen auf high ist. In 
       SPI_Transmitt wird der SS_Master auf low gesetzt und damit SS_Slave des anderen auch auf low. 
       Damit geht der mit SS_Slave auf low in den Interrupt. Im Interrupt werden erst die angekommenen 
       Daten dem Empfangsbuffer angehängt, dann wird wieder in den Master Modus geschaltet, außer der 
       SS_Slave Pin ist noch auf low, d.h. der aktuelle Master will noch was senden.
       Wird etwas versand geht der andere Mikrocontroller in den Interrupt
       und bei ihm geschieht das gleiche. 
    
    */
    
    #include <avr/io.h>
    
    #define SS_Master   PB3                // Pin zum Slave
    #define SS_Slave    PB4                // Pin vom Slave
    #define MOSI        PB5 
    #define MISO        PB6
    #define SCK         PB7
    #define DDR_SPI     DDRB
    #define PORT_SPI    PORTB
    #define MAX         99           // Bytes des SPI Lesebuffers max. 255 !! 255 sind 256Bytes
    
    volatile unsigned char data;
    
    volatile unsigned char Buffer[MAX];      // Empfangs buffer
    volatile unsigned char Buffer_count=0;   // Wieviele Bytes sind im Buffer
    
    SIGNAL (SIG_SPI)        // SPI Recieve
    {
       data=SPDR;         // SPI Datenregister in data laden.
       Buffer[Buffer_count]=data;      // data in Buffer laden
       Buffer_count++;     // 1 Byte mehr im Empfangsbuffer
       
       // Prüfen ob SS_Slave schon wieder high ist --> empfang vorbei
       if(PORT_SPI & (1<<SS_Slave))       
       {  
          // Wieder Master werden
          SPCR|=(1<<MSTR);
          // Daten versenden oder gleich raus aus Interrupt und nur wieder Master
          // SPI_Transmitt(' ');
       }
    }
    
    
    
    void SPI_Init(void)
    {
       // Set MOSI and SCK output, all others input
       DDR_SPI = (1<<MOSI) | (1<<SCK) | (1<<SS_Master); 
       PORT_SPI|=(1<<SS_Master);  //SS Pin zum  SPI Slave auf high
       // SPI enable, Master enable, fck/16, SPI Interrupt enable
       SPCR= (1<<SPE) | (1<<MSTR) | (1<<SPR0) | (1<<SPIE);  
    }
    
    unsigned char SPI_getc(void)           // holt das letzte Byte seit dem letzten Aufruf
    {
       unsigned char data,i=1;
       if(Buffe_count!=0)    // Neue Daten seit dem letzten Aufruf
       {      
    	  data = Buffer[0];
          // Buffer neu ordnen damit letztes Byte wieder auf  Buffer[0] ist. 
          for(i;i<=Buffer_count;i++)
             Buffer[i-1]=Buffer[i];
          Buffer_count--;      // 1 Byte weniger im Empfangsbuffer      
          return data;
       }
    }
    
    void SPI_Transmitt_Raw(unsigned char data)  // Sollte im eigenen Programm nicht verwendet werden
    {
        SPDR = data;
    	while(!(SPSR & (1<<SPDIF))) asm volatile ("nop");
    }
    
    void SPI_putc(unsigned char data)         // Das ist die Funktion um ein Byte zu senden 
    {                                           // z.B. SPI_putc('c'); --> sendet ein c
                                                // unsigend char c;
          PORT_SPI &= ~(1<<SS_Master);         // SPI_putc(c); --> sendet den Inhalt der Variable c
          SPDR = data;
          while(!(SPSR & (1<<SPDIF))) asm volatile ("nop");
          PORT_SPI|=(1<<SS_Master);   
       
    }
    
    void SPI_puts (unsigned char *s)             // sendet einen Buffer aus mehreren Bytes
    {                                    // z.B.  SPI_puts("hallo");  --> ist aber blödes Beispiel mit hallo
        PORT_SPI &= ~(1<<SS_Master);    // unsigned char buffer[100];
    	while (*s)                      // SPI_puts(buffer)
        {   /* so lange *s != NULL */
            SPI_Transmitt_Raw(*s);
            s++;
        }
        PORT_SPI|=(1<<SS_Master);
    }
    Also vielleicht hilfts dir ja weiter, wenn du kein C dann ist es näturlich schade.
    Gruß Muraad

Seite 2 von 2 ErsteErste 12

Berechtigungen

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

Labornetzteil AliExpress