Forum: Mikrocontroller und Digitale Elektronik Atmega644 SPI bleibt ab dem 2. Byte in der schleife hängen


von Daniel H. (doomstar)


Lesenswert?

Hi

hab mal wieder ein Problem das ich nicht verstehe.

Versuche gerade meine schaltung mit einem Atmega644 und MCP2515 in 
Betrieb zu nehmen leider bleibt der Controller in einer Warteschleife 
hängen bei der er auf die übertragung fertig wartet (wie im Datasheet 
beschrieben). Das passiert nur beim 2 Byte und nur auf dem 644 auf einem 
Atmega32 läuft der Code perfekt.

Hab schon alles so weit geschrumpft das nur noch 2 Byte übertragen 
werden sollen, hab es mit und ohne MCP2515 versucht. Alle Leitung 
durchgemessen mit oszi aber nichts zu machen er bleibt in der schleife 
hängen. Muss also irgendwetwas mit dem 644 zu tun haben

Hier mal mein Code:
int main()
{
  config_ports();

  _delay_ms(1000);

  init_spi(true,3,128);

//  mcp2515_init();

  select_slave(MCP2515,true);
  com_spi(122);
  com_spi(122);

  STATUS_LED_PORT    |= (1<<STATUS_LED_BIT);    //Status LED
  TRIGGER_LED_PORT  |= (1<<TRIGGER_LED_BIT);    //Trigger LED
  while(1)
  {

  }
}

/*********************************************************************** 
********
 *  Name                 :  init_spi
 *  Description          :  Diese Funktion Initalisiert den SPI
 *
 *  Parameter:      masterslave
 *            true = Master Mode
 *            false = Slave Mode
 *
 *            clock_mode
 *            0  =  CPOL 0; CPHA 0
 *            1  =  CPOL 1; CPHA 0
 *            2  =  CPOL 0;  CPHA 1
 *            3  =  CPOL 1; CPAH 1
 *
 *            clock
 *            4, 16, 64, 128 Teiler
 ************************************************************************ 
******/
void init_spi(bool masterslave, uint8_t clock_mode, uint8_t clock)
{
  //Master or Slave
  if(masterslave == true)
  {
    SPI_CONTROL |= (1<<SPI_MASTER_SLAVE_SELECT);
    SPI_MOSI_DDR |= (1<<SPI_MOSI_PIN);
    SPI_MOSI_PORT |= (1<<SPI_MOSI_PIN);
    SPI_SCK_DDR |= (1<<SPI_SCK_PIN);
    SPI_SCK_PORT |= (1<<SPI_SCK_PIN);

    SPI_MISO_DDR &= ~(1<<SPI_MISO_PIN);

    SPI_SLAVE1_DDR |= (1<<SPI_SLAVE1_PIN);
    SPI_SLAVE1_PORT |= (1<<SPI_SLAVE1_PIN);

  //  SPI_SLAVE2_DDR |= (1<<SPI_SLAVE2_PIN);
  //  SPI_SLAVE2_PORT |= (1<<SPI_SLAVE2_PIN);
  }
  else
  {
    SPI_CONTROL &= ~(1<<SPI_MASTER_SLAVE_SELECT);
    SPI_MISO_DDR |= (1<<SPI_MISO_PIN);

    SPI_MOSI_DDR &= ~(1<<SPI_MOSI_PIN);
    SPI_SCK_DDR &= ~(1<<SPI_SCK_PIN);
    SPI_SLAVE1_DDR &= ~(1<<SPI_SLAVE1_PIN);
  }

  //SPI Clock
  switch(clock)
  {
    case 4:    SPI_CONTROL &= ~(1<<SPI_CLOCK_BIT_0); SPI_CONTROL &= 
~(1<<SPI_CLOCK_BIT_1);break;
    case 16:  SPI_CONTROL |= (1<<SPI_CLOCK_BIT_0); SPI_CONTROL &= 
~(1<<SPI_CLOCK_BIT_1);break;
    case 64:  SPI_CONTROL &= ~(1<<SPI_CLOCK_BIT_0); SPI_CONTROL |= 
(1<<SPI_CLOCK_BIT_1);break;
    case 128:  SPI_CONTROL |= (1<<SPI_CLOCK_BIT_0); SPI_CONTROL |= 
(1<<SPI_CLOCK_BIT_1);break;
    default:  SPI_CONTROL |= (1<<SPI_CLOCK_BIT_0); SPI_CONTROL |= 
(1<<SPI_CLOCK_BIT_1);break;
  }

  //SPI Clock Mode
  select_clock_mode(clock_mode);

  //Set Data Order
  SPI_CONTROL |= (1<<SPI_DATA_ORDER);

  //Enable SPI
  SPI_CONTROL |= (1<<SPI_ENABLE);
}
/*********************************************************************** 
********
 *  Name                 :  select_slave
 *  Description          :  This function selects a Slave
 ************************************************************************ 
******/
void select_slave (uint8_t slave, bool connect)
{

  if(slave == 1)
  {
    SPI_CONTROL &= ~(1<<SPI_DATA_ORDER);
    select_clock_mode(0);
    if(connect == true)
    {
      SPI_SLAVE1_PORT &= ~(1<<SPI_SLAVE1_PIN);
    }
    else
    {
      SPI_SLAVE1_PORT |= (1<<SPI_SLAVE1_PIN);
    }
  }
}

/*********************************************************************** 
********
 *  Name                 :  com_spi
 *  Description          :  This function sends a charakter over the spi
 *              in the same it gets one from the Slave
 ************************************************************************ 
******/
uint8_t com_spi (char data)
{
  //Put data into the SPI Data Register
  SPI_DATA = data;

  //wait until SPI comm is done
  while(!( SPI_STATUS & (1<<SPI_INTERRUPT_FLAG)));

  return SPI_DATA;
}

wie gesagt hier in der com_spi funiktion bleibt er hängen aber nur ab 
dem 2. Byte das erste geht sauber durch.

MFG
Daniel

von holger (Gast)


Lesenswert?

>wie gesagt hier in der com_spi funiktion bleibt er hängen aber nur ab
>dem 2. Byte das erste geht sauber durch.

SPI beim Master kann hängen bleiben wenn der SS Pin kein Ausgang ist.
Wenn der SS Pin ein Eingang ist muss er beim Master auf High liegen.

von Daniel H. (doomstar)


Lesenswert?

Holger du bist Goldwert.

Das steht leider so nicht direkt im Datenblatt oder?

war schon am zweifeln

vielen vielen DANK.



Schönen Abden noch.

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.