Forum: Compiler & IDEs Problem SPI Atmega16 mit MCP41010


von N. B. (blackstripes)


Lesenswert?

Ich habe ein Porblem mit der SPI Kommunikation!!!

ATMega16 -> MCP41010
MOSI -> SI
SCK -> SCK
SS -> CS(inv.)

Mein Code:

#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

#include "uart.h"
#include "ADC.h"


/* define CPU frequency in Mhz here if not defined in Makefile */
#ifndef F_CPU
#define F_CPU 16000000UL
#endif

/* 9600 baud */
#define UART_BAUD_RATE  9600

void adc(char mux)
{
  int ad = ADC_Read(mux);
  char buffer[10];
  itoa(ad,buffer,10);
  uart_puts(buffer);
  uart_puts("\n\r");
  return;
}

void spi_init(void)
{
  SPCR|=(1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0); //SPI enable, Master,
Freq/128;
}

void spi_write(char data)
{
  PORTB |= (1<<PB4); //CS high
  SPDR = 0x11; // 11 für write und pot1
  SPDR = data;
  PORTB &= ~(1<<PB4); //CS low
}

int main(void)
{
  DDRD &=~((1<<PD2)|(1<<PD3)|(1<<PD4));
  DDRA = 0x00;
  DDRD|=(1<<PD7)|(1<<PD6)|(1<<PD5);
  DDRB |= (1<<PB5)|(1<<PB7); //MOSI u SCK als OUTPUT
  DDRB |= (1<<PB4); // SS als OUTPUT
    uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));
  ADC_Init();
  spi_init();
    sei();
  while (1)
  {
    int read = uart_getc();
    if (read==48) adc(0);
    if (read==49) adc(1);
    if (read==50) adc(2);
    if (read==51) adc(3);
    if (read==52) adc(4);
    if (read==53) adc(5);
    if (read==54) adc(6);
    if (read==55) adc(7);
    if (PIND &(1<<PD2)) spi_write(0xFF); //255
    else spi_write(0x50); // 80
    _delay_ms(1000);
  }
}


Kann mir jemand sagen was ich falsch mache??? Der wert des potis
verändert sich nicht!!!

von Stefan E. (sternst)


Lesenswert?

1
void spi_write(char data)
2
{
3
  PORTB |= (1<<PB4); //CS high
4
  SPDR = 0x11; // 11 für write und pot1
5
  SPDR = data;
6
  PORTB &= ~(1<<PB4); //CS low
7
}
Das Poti hat ein high-aktives CS? Kann ich kaum glauben.

von Krapao (Gast)


Lesenswert?

Ich auch nicht. Reduziert auf die Grundfunktionen:
1
//
2
// Atmega16 @ ? MHz
3
//
4
#include <avr/io.h>
5
#include <util/delay.h>
6
#include <stdlib.h>
7
8
void Deselect_MCP41010(void)
9
{
10
  _delay_us(1);
11
  // Drive /CS HIGH on Slave
12
  PORTB |= (1<<PB4);
13
}
14
15
void Select_MCP41010(void)
16
{
17
  // Drive /CS LOW on Slave
18
  PORTB &= ~(1<<PB4);
19
  _delay_us(1);
20
}
21
22
// siehe Atmel Datasheet
23
void SPI_MasterTransmit(uint8_t data)
24
{
25
  SPDR = data;
26
  while(!(SPSR & (1<<SPIF))){}
27
}
28
29
void spi_init(void)
30
{
31
  DDRB |= (1<<PB4);    // SS (/CS on Slave) als Output
32
  Deselect_MCP41010();
33
  DDRB |= (1<<PB5)|(1<<PB7); // MOSI u. SCK als OUTPUT
34
  // SPI enable, Atmega16 is Master, Freq/128;
35
  SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0); 
36
}
37
38
void spi_write(char data)
39
{
40
  Select_MCP41010();
41
  SPI_MasterTransmit(0x11); // 11 für write und pot1
42
  SPI_MasterTransmit(data);
43
  Deselect_MCP41010();
44
}
45
46
int main(void)
47
{
48
  spi_init();
49
  while(1)
50
  {
51
    if(PIND & (1<<PD2)) 
52
      spi_write(255);
53
    else 
54
      spi_write(80);
55
    _delay_ms(1000);
56
  }
57
}

von N.B. (Gast)


Lesenswert?

Vielen Dank, jetzt geht es endlich. Ich dachte wenn CS invertiert ist 
und im Protokoll drin steht low active dann muss ich den eingang high 
setzten!!! Lg

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.