Forum: Mikrocontroller und Digitale Elektronik TWI Probelm


von Dd D. (neo120484)


Lesenswert?

Guten tag alle miteinander ich hänge zur zeit wieder an einem kleinen
problem ... diesmal ist es die TWI komunnikation zwischen eines Masters
und einigen Slaves

ziel des programms sollte es sein das ich über die UART an den master
eine art identifiere schicke in dem fall (r,g,b) und darauf hin einen
wert. Der master soll diesen identifiere und den Wert dann weiter an
die  Slaves schicken die an dem TWI bus hängen was ich in diesem fall
mit einem Broadcast(senden an alle) machen wollte.

Später sollen auch noch einzeilne slaves angesprochen werden können was
aber dann nicht mehr all zu schwierig sein sollte sofern die
kommunikation erst einmal funktioniert.


Hier mal mein Code bis dto.


Master:

//------------------------------------Includes-------------------------- 
---------
#include <avr/io.h>
#include <stdint.h>
#include <compat\ina90.h>
#include <avr/eeprom.h>
#include <util\twi.h>
#include "TWI_Master.h"


//------------------------------------Defines--------------------------- 
---------
#define FOSC 3686400
#define BAUD 9600
#define MYUBRR (FOSC/(16L*BAUD))-1

static uint8_t rot;
static uint8_t blau;
static uint8_t gruen;

//------------------------------------Functions------------------------- 
---------
//###################################################################### 
#########
//##################################USART############################### 
#########

//=============Init function=========================
void USART_INIT(unsigned int ubrr)
{
  //Set Bautrate
  UBRR0H =(unsigned char) (ubrr >>8);
  UBRR0L =(unsigned char)ubrr;

  //Enable receive and transive
  UCSR0B |= (1<<RXEN0) | (1<<TXEN0);

  //Set Frame format
  UCSR0C |= (1<<USBS0)|(1<<UCSZ00);
}



//=============Receive Enable========================
void USART_EnableRX()
{
    UCSR0B |= ( 1 << RXEN0);
}



//=============Receive function======================
unsigned char USART_Rx(void)
{
    while (!(UCSR0A & (1<<RXC0)));
    return UDR0;
}



//###################################################################### 
#########
//####################################TWI############################### 
#########
void TWI_INIT(void)
{
  TWBR |= (1 << 0);    //TWI frequenz = 3686400/(16+2*1*1)= 204800

  TWCR |= (1 << TWEN) | (0<< TWIE); //Enabele TWI and TWI interrupt
}


int TWI_SEND(int slaveadresse,int anzahl,char *data)
{
  _NOP();
  TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);  //send Start
condition
  _NOP();
  while(!(TWCR & (1 << TWINT)));            //wait for transmitted start
condition
  _NOP();
  if((TWSR & 0xF8) != TW_START)            //check for coroupt Start
condition
    return 0;


  _NOP();
  TWDR = slaveadresse;                //set Slaveadress
  _NOP();
  TWCR = (1 << TWINT) | (1 << TWEN);          //start transmission of 
adress
  _NOP();
  while(!(TWCR & (1 << TWINT)));            //wait for acknowlege
  _NOP();
  if((TWSR & 0xF8) != TW_MT_SLA_ACK)          //check for coroupt 
Slaveadress
transmission
    return 0;


  _NOP();
  int i;
  _NOP();
  for(i=0; i < anzahl;i++)
  {
    _NOP();
    TWDR = data[i];                    //write data into TWIDataRegister
    _NOP();
    TWCR = (1 << TWINT) | (1 << TWEN);          //sart transmisson of 
data
    _NOP();
    while(!(TWCR & (1 << TWINT)));            //wait for acknowlege
    _NOP();
    if((TWSR & 0xF8) != TW_MT_DATA_ACK)          //check for coroupt 
data
transmission
      return 0;
  }

  _NOP();
  TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);    //send stop
condition


  return 1;
}





//###################################################################### 
#########
//##################################Sonstige############################ 
#########

void setred(void)
{  int check;
  uint8_t receive;
  receive = USART_Rx();
  _NOP();
  rot = receive;
  check = TWI_SEND(0,1,"r");
  check = TWI_SEND(0,1,&receive);
}


void setblue(void)
{
  int check;
  uint8_t receive;
  receive = USART_Rx();
  _NOP();
  blau = receive;
  check = TWI_SEND(0,1,"b");
  check = TWI_SEND(0,1,&receive);
}


void setgreen(void)
{
  int check;
  uint8_t receive;
  receive = USART_Rx();
  _NOP();
  gruen = receive;
  check = TWI_SEND(0,1,"g");
  check = TWI_SEND(0,1,&receive);
}


int main(void)
{
  DDRC &= (0 << DD5) & (0 << DD4);
  PORTC |= (1 << PC5) | (1 << PC4);


  //LED's auf Port C
  DDRC  |= (1 << DD3) | (1 << DD2) | (1 << DD1) | (1 << DD0);
  PORTC |= (1<<PC4) | (1<<PC3) | (1<<PC2);


  //USART initialisieren
  USART_INIT(MYUBRR);


  //TWI initialisieren
  TWI_INIT();

  uint8_t a = 10;
  uint8_t a1 = 20;
  uint8_t a2 = 30;
  uint8_t e;
  uint8_t e1;
  uint8_t e2;


  //Setzen auf dne zuletzt gespeicherten wert
  eeprom_busy_wait();
  e = eeprom_read_byte (&a);
  rot = e;
  TWI_SEND(0,1,"r");
  TWI_SEND(0,1,&e);
  eeprom_busy_wait();
  e1 = eeprom_read_byte (&a1);
  blau = e1;
  TWI_SEND(0,1,"b");
  TWI_SEND(0,1,&e1);
  eeprom_busy_wait();
  e2 = eeprom_read_byte (&a2);
  gruen = e2;
  TWI_SEND(0,1,"g");
  TWI_SEND(0,1,&e2);



  while(1)
  {
    unsigned char receive;
    receive = USART_Rx();
    _NOP();

    if(receive =='r')
    {
      setred();
    }


    if(receive =='b')
    {
      setblue();
    }



    if(receive =='g')
    {
      setgreen();
    }



    //Speichern der aktuellen einstellungen?????
    if(receive =='s')
    {
    eeprom_busy_wait();
    eeprom_write_byte (&a,rot);
    eeprom_busy_wait();
    eeprom_write_byte (&a1,blau);
    eeprom_busy_wait();
    eeprom_write_byte (&a2,gruen);
    }




  }

}



-----------------------------------------------------------------
Slave:

//------------------------------------Includes-------------------------- 
---------
#include <avr/io.h>
#include <stdint.h>
#include <compat\ina90.h>
#include <avr/eeprom.h>
#include <util\twi.h>

//------------------------------------Functions------------------------- 
---------
//###################################################################### 
#########
//####################################TWI############################### 
#########
void TWI_INIT(void)
{
  TWBR |= (1 << 0);    //TWI frequenz = 3686400/(16+2*1*1)= 204800

  TWAR &= (0 << TWA6) & (0 << TWA5) & (0 << TWA4) & (0 << TWA3) & (0 <<
TWA2) & (0 << TWA1);
  TWAR |= (1 << TWA0) | (1 << TWGCE);  // set Slaveadress

  TWCR |= (1 << TWEA) | (1<< TWEN); //Enabele TWI and Acknowlege
}


char TWI_RECEIVE(void)
{
  uint8_t receive;
  while(!(TWCR & (1 << TWINT)));            //wait for aktivitie on bus
  if((TWSR & 0xF8) == 0x80);              //looking if data is reveived 
and
acknowlege is send
    receive = TWDR;                  //reading data

  TWCR = (1 << TWINT);                //setting bus receive end


  return receive;
}

//###################################################################### 
#########
//####################################Other############################# 
#########
void red(void)
{
  char empf;
  empf = TWI_RECEIVE();
  OCR0A = empf;

}


void blue(void)
{
  char empf;
  empf = TWI_RECEIVE();
  OCR1A = empf;
}

void green(void)
{
  char empf;
  empf = TWI_RECEIVE();
  OCR2A = empf;
}






int main(void)
{
  char empfangen;

  //PWM Ausgänge auf "aus" setzen
  OCR0A = 0;
  OCR1A = 0;
  OCR2A = 255;


  //PWM Ausgang OC0A
  TCCR0A = (1 << COM0A1) | (1 << COM0A0)|(1 << WGM01)|(1 << WGM00);
//invert Fast PWM 8bit
  TCCR0B = (1<<CS00);          // no prescale -> enable counter
  PORTD |= (1 << 6);      // enable pull-ups for inputs, set outputs
high
  DDRD  |= (1 << 6);



  //PWM Ausgang OC1A
  TCCR1A = (1 << COM1A1) | (1 << COM1A0)|(0 << WGM11)|(1 << WGM10);
//invert Fast PWM 8bit
  TCCR1B = (1<<CS10);        // no prescale -> enable counter
  PORTB |= (1 << 3) |(1 << 1);      // enable pull-ups for inputs, set
outputs high 0xff
  DDRB  |= (1 << 3) | (1 << 1);    // Pin LED auf 1 setzen


  //PWM Ausgang OC0A
  TCCR2A = (1 << COM0A1) | (1 << COM2A0)|(1 << WGM21)|(1 << WGM20);
//invert Fast PWM 8bit
  TCCR2B = (1<<CS20);          //no prescale -> enable counter


  //TWI initialisieren
  TWI_INIT();


  DDRC  |= 0xcf;
  PORTC |= (1<<PC6) | (1<<PC5) | (1<<PC4) | (1<<PC3) | (1<<PC2)  |
(1<<PC1);

  while(1)
  {
    empfangen = TWI_RECEIVE();

    if(empfangen == 'r')
      red();

    if(empfangen == 'b')
      blue();

    if(empfangen == 'g')
      green();


  }

}



Ps. ich weiß wirklich sauber ist das bis jetzt nicht programmiert G

von Hegy (Gast)


Lesenswert?

Hi,

fuer die TWI-Kommik habe ich das fertige Teil von Atmel genommen und es
lief auf Anhieb. Bei mir sind's ein Master und 3 Skalven.

Ich meine den hier:
AVR155: Accessing I2C LCD display using the AVR TWI
AVR311: Using the TWI module as I2C slave.pdf
AVR315: Using the TWI module as I2C master.pdf

liegen bei Atmel auffe Heimatseite.

von Dd D. (neo120484)


Lesenswert?

danke das kenn ich schon ich werd mich wohl nochmals  damit versuchen
stell mich wohl nur zu blöd an

gruß dominik

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.