SPI auf XMEGA

OP #4095163
Lesenswert?

Hallo ,

ich versuche seit Stunde die SPI auf einen XMEGA zum Laufen zu bringen, 
leider vergeblich. hier ist mein Code :

#include <avr/io.h>
#define F_CPU 32000000UL
#define SPIPort PORTD
#define SPICTRL SPID
#define SPIMO   5
#define SPIMI   6
#define SPISC   7
#define SPISS   0

char SPIDir = 0 ;

void spiopen(void)
{
    SPIDir = SPIPort.DIR ;
    SPIPort.DIRCLR = (1<<SPIMI);
    SPIPort.DIRSET = (1<<SPIMO) | (1<<SPISC) | (1<<SPISS) ; // Make sure 
slave select is an output
    SPICTRL.CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_MODE_0_gc | 
SPI_PRESCALER_DIV64_gc;
}



void spiclose(void)
{
    SPICTRL.CTRL = 0;
    SPIPort.DIR = SPIDir ;
    SPIPort.DIRSET = (1<<SPIMI);
}

uint8_t spi(uint8_t val)
{
    SPICTRL.DATA = val ;
    while(!(SPICTRL.STATUS & (1<<7)));
    return SPICTRL.DATA;
}


int main(){
 OSC.CTRL = OSC_RC32MEN_bm; /* Enabling the 32MHz RC oscillator */
    while (!(OSC.STATUS & OSC_RC32MRDY_bm)); /* wait for ready */
        CCP = CCP_IOREG_gc;/* allow changing CLK.CTRL */
        CLK.CTRL = CLK_SCLKSEL_RC32M_gc ;/* system clock is internal 
32MHz RC */
   spiopen();
while(1){
   spi('U');
}
return 0;
}


Ich kann  auf alle PINs ( MOSI SLC SS ) kein Signal messen ?  kann 
jemand mir verraten wo der Fehler ist ?
Danke
Gast #4100298
Lesenswert?

Hallo
Ich suche nun seit gut einem Nachmittag fehler beim XMega SPI Register. 
Ich will nicht die Application notes nehmen, da ich die SPI selbst 
Porgrammieren will. (challange & verständniss)
nun komme ich selbst aber nicht mehr vom Fleck und messe an den Pins des 
Xmega auch kein singnal oder CLk.

Hier der Code:

1
void init_SPI(void)
2
{  
3
  SPIE.CTRL = 0b11110010;  //Controllregister
4

5
  SPIE.INTCTRL = 0b00000010;  //Interrupt Control register
6

7
  SPIE.STATUS = 0b00000000;     //Status register
8
                      
9
  SPIE.DATA = 0b00000000;  //Send and Recive data       
10
}
11

12
void send_Data_SPI(unsigned char ucData);
13
{  SPIE.DATA = ucData;
14
  
15
  while(!(SPIE.STATUS & (1<<7)));
16
  
17
}


Ich hoffe jemand weiss wo der Fehler liegt..
Gast #4100336
Lesenswert?

Da währe der komplette code

[c]
void PortInit(void)
{
  PORTE.DIR = 0b10011100; //SPI [7:4]
}
void init_SPI(void)
{
  SPIE.CTRL = 0b11110010;  //Controllregister

  SPIE.INTCTRL = 0b00000010;    //Interrupt Control register

  SPIE.STATUS = 0b00000000;  //Status register

  SPIE.DATA   = 0b00000000;  //Send and Recive data
}

void send_Data_SPI(unsigned char ucData)
{  SPIE.DATA = ucData;

   while(!(SPIE.STATUS & (1<<7)));

}

int main(void)
{ unsigned char i = 0;
  SetupExtOscPLL();
  PortInit();

  init_SPI();
  while(1)
  {  send_Data_SPI(i);
     wait_1ms(10);
     i++;
  }
}[c/]
#4100419
Lesenswert?

> PORTE.DIR = 0b10011100; //SPI [7:4]

Ist PORTE Pin7 nicht SCK und PORTE Pin5 nicht MOSI...?

Chipselect hast du nicht? Solltest du beim Zugiff auf Low ziehen, das 
macht nicht die Hardware ("In master mode, the SPI interface has no 
automatic control of the SS line")

Bitte versuche die verständlichen Bitmasken zu vewenden, dann weiß man 
auch gleich was passiert:

SPIE.CTRL |= SPI_ENABLE_bm | SPI_MASTER_bm | SPI_MODE_2_gc | 
SPI_PRESCALER_DIV16_gc; // etc.

oder eben das _bp Äquivalent
#4100473
Lesenswert?

In einem früherem Projekt von mir wollte ich den SPI des Xmega 
verwenden, allerdings hatte ich die entsprechenden Pins nicht mehr frei.
Deswegen hab ich das ganze versucht softwaretechnisch zu lösen. Und das 
hat auch so funktioniert.
Ich kann dir gerne morgen ein Beispiel hier posten, wenn dir das eine 
Hilfe sein sollte.
#4100529
Lesenswert?

Software SPI ist ja nicht das Prob:
1
#define CS_HIGH() PORTE.OUTSET = (1<<PIN1)
2
#define CS_LOW()  PORTE.OUTCLR = (1<<PIN1)
3

4
void Soft_SPI_init(){  
5
  
6
  PORTE.DIR = (1<<PIN2) | (1<<PIN1) |(1<<PIN0);  //MOSI & CSN & CE
7
  PORTA.DIR = (1<<PIN0);  //SCK
8
  
9
  PORTA.OUTCLR = (1<<PIN0); //SCK low
10
  
11
  CSN_HIGH();
12
  CE_LOW();
13

14
}
15

16

17
unsigned char SPI_transfer( unsigned char value )
18
{
19

20
  uint8_t bit_ctr;
21
  
22
  for(bit_ctr=0;bit_ctr<8;bit_ctr++)   // output 8-bit
23
  {
24
    if(value & 0x80)
25
    {
26
      PORTE.OUTSET = (1<<PIN2);
27
    }
28
    else
29
    {
30
      PORTE.OUTCLR = (1<<PIN2);
31
    }
32

33
    value = (value << 1);           // shift next bit into MSB..
34
    PORTA.OUTSET = (1<<PIN0);    // Set SCK high..
35
    if(PORTE.IN & (1<<PIN3))
36
      value |= 1;             // capture current MISO bit
37
    else
38
      value &= ~1;
39
    
40
    PORTA.OUTCLR = (1<<PIN0); // ..then set SCK low again
41
  }
42
  return(value);                 // return read UINT8
43
  
44
}
45

46
void SPI_Write_Reg(uint8_t reg, uint8_t value)                 
47
{
48

49
  CE_LOW();
50

51
  SPI_transfer(reg);  // select register
52
  SPI_transfer(value);  // ..and write value to it..
53

54
  CE_HIGH();
55
}      
56

57
uint8_t SPI_Read_Reg(uint8_t reg)                               
58
{                                                           
59
  uint8_t value;
60

61
  CE_LOW();
62

63
  SPI_transfer(reg);            // Select register to read from..
64
  value = SPI_transfer(0);    // ..then read register value
65

66
  CE_HIGH();
67

68

69
  return(value);        // return register value
70
}
Aber Hardware ist auch nicht schwieriger und ist halt noch etwas 
schneller und kann ggf. auch per DMA gemacht werden

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren