Hi Leute,
ich probiere seid ein paar Tagen einen Sensor via SPI auszulesen.
Bei dem Sensor handelt es sich um einen BMP280, der schon auf einer
Leiterplatte angebracht ist. (siehe Breadboard)
Mittels N-Kanal Mosfet (2N 7000) und 2 10k Pull-Up Widerständen habe ich
die Logic Level angepasst, da der Sensor mit 3V3 arbeitet.
Der µC ist ein AtMega 328P auf dem Entwicklungsboard xplained mini.
Bis dahin funktioniert auch alles.
Ich kann mit Multimeter die eingestellten Pegel messen.
Leider habe ich kein Oszi.
Software seitig gibt es 2 Dinge die mich stören:
1. Der Debugger zeigt mir im Atmel Studio 7 immer ein leeres SPDR an,
egal ob ich etwas rein schreibe (SPDR = 0xD0) das SPDR bleibt leer.
2. Wenn ich mein Programm laufen lasse empfange ich als ID 0xFF welche
eigentlich 0x58 sein sollte. Habe mir nichts weiter dabei gedacht und
weiter programmiert um die "pressure Werte" auszulesen, MSB und LSB
bekomme ich auch als 0xFF angezeigt.
Weis jemand wo das Problem liegt? bzw liegen könnte?
hier ist der Code:
main.c:
1 |
|
2 | /*
|
3 | * BMP280-SPI.c
|
4 | *
|
5 | * Created: 17.06.2017 11:45:17
|
6 | * Author : MattZe
|
7 | */
|
8 |
|
9 | #ifndef F_CPU
|
10 | #define F_CPU 16000000UL
|
11 | #endif
|
12 |
|
13 | #include <avr/io.h>
|
14 | #include "spi.h"
|
15 | #include <util/delay.h>
|
16 | #include <avr/interrupt.h>
|
17 |
|
18 | #define char uint8_t
|
19 | #define unsigned int uint16_t
|
20 | #define IDAddr 0xD0 // see Datasheet BMP280 page 31 & 24 ff.
|
21 |
|
22 |
|
23 | int main(void)
|
24 | {
|
25 | DDRC = 0xF0;
|
26 | PORTC |= (1 << DDC5);
|
27 |
|
28 | uint8_t ID = 0x00;
|
29 | uint8_t pressMSB = 0x00;
|
30 | uint8_t pressLSB = 0x00;
|
31 | uint16_t press = 0x00;
|
32 |
|
33 |
|
34 | // initialize SPI as Master, MSB first, Interrupt off, clock rate: f(osc)/128, Mode: 00
|
35 | spi_master_init (); // SPI wird nicht eingeschaltet (SPE nicht gesetzt)
|
36 | PORTB |= (1 << DDB2); // zur Sicherheit nochmal auf VCC ziehen
|
37 |
|
38 | SPCR |= (1 << SPE); // enable SPI
|
39 |
|
40 | // start communication
|
41 | PORTB &= ~(1<<DDB2);
|
42 | // get ID
|
43 | ID = spi_fast_shift (0xD0);
|
44 | // determinate Communication
|
45 | PORTB |= (1<<DDB2);
|
46 |
|
47 | spiConfigBMP280 ();
|
48 |
|
49 | while (1)
|
50 | {
|
51 | /* write Register-Addr without MSB
|
52 | MSB is 1 if read access
|
53 | MSB is 0 if write access
|
54 | */
|
55 | ID = SPIMasterSend (0xD0);
|
56 | if (ID == 0x00) // wurde keine ID gelesen wird die LED an PC5 ausgeschaltet
|
57 | PORTC &= ~(1 << DDC5);
|
58 |
|
59 | press = spiPressBMP280 (pressMSB, pressLSB);
|
60 |
|
61 | ID = 0x00;
|
62 | }
|
63 |
|
64 | while (1);
|
65 |
|
66 | return 1;
|
67 | }
|
spi.c
1 | #include "spi.h"
|
2 |
|
3 | #include <avr/io.h>
|
4 | #include <avr/interrupt.h>
|
5 |
|
6 | #define PORT_SPI PORTB
|
7 | #define DDR_SPI DDRB
|
8 | #define DD_MISO DDB4
|
9 | #define DD_MOSI DDB3
|
10 | #define DD_SS DDB2
|
11 | #define DD_SCK DDB5
|
12 |
|
13 | void spi_master_init (void)
|
14 | {
|
15 | SPCR = 0x00; // vorbeugend
|
16 | DDRB |= ((1<<DD_SCK) | (1<<DD_MOSI) | (1<<DD_SS)); // setze SCK,MOSI,PB2 (SS) als Ausgang
|
17 | DDRB &= ~(1<<DD_MISO); // setze MISO als Eingang
|
18 | PORTB |= ((1<<DD_SCK) | (1<<DD_SS)); // SCK low und PB2 high (ist mit SS am Slave verbunden)
|
19 | SPCR |= ((1<<MSTR) | (1<<CPHA) | (1<<SPR0) | (1<<SPR1)); //Master, Taktrate fck/128
|
20 | }
|
21 | uint8_t spi_fast_shift (uint8_t data)
|
22 | // Clocks only one byte to target device and returns the received one
|
23 | {
|
24 | SPDR = data;
|
25 | while(!(SPSR & (1<<SPIF)));
|
26 | return SPDR;
|
27 | }
|
28 |
|
29 | uint8_t SPIMasterSend(uint8_t data)
|
30 | {
|
31 | // start communication
|
32 | PORTB &= ~(1<<DDB2);
|
33 | // send data
|
34 | SPDR = data;
|
35 | // wait for transmition complete
|
36 | while (!(SPSR &(1<<SPIF)));
|
37 | // Empfangene Daten in Variable zurück schreiben
|
38 | data = SPDR;
|
39 | // determinate Communication
|
40 | PORTB |= (1<<DDB2);
|
41 |
|
42 | return data;
|
43 | }
|
BMP280.c:
1 | /*
|
2 | **
|
3 | **
|
4 | */
|
5 | #define ConfigAddr 0x74 // see Datasheet BMP280 page 31 & 24 ff.
|
6 | #include "spi.h"
|
7 | #include <avr/io.h>
|
8 |
|
9 | uint8_t spiConfigBMP280 (void)
|
10 | {
|
11 | // start communication
|
12 | PORTB &= ~(1<<DDB2);
|
13 | // configure Sensor
|
14 | spi_fast_shift (ConfigAddr);
|
15 | spi_fast_shift (0xB7);
|
16 | // determinate Communication
|
17 | PORTB |= (1<<DDB2);
|
18 |
|
19 | // start communication
|
20 | PORTB &= ~(1<<DDB2);
|
21 | // configure Sensor
|
22 | spi_fast_shift (ConfigAddr+1U);
|
23 | spi_fast_shift (0x10);
|
24 | // determinate Communication
|
25 | PORTB |= (1<<DDB2);
|
26 |
|
27 | return 1;
|
28 | }
|
29 |
|
30 | uint16_t spiPressBMP280 (uint8_t MSB, uint8_t LSB)
|
31 | {
|
32 | // start communication
|
33 | PORTB &= ~(1<<DDB2);
|
34 | // get pressure Value
|
35 | MSB = spi_fast_shift (0xF7);
|
36 | // determinate Communication
|
37 | PORTB |= (1<<DDB2);
|
38 |
|
39 | // start communication
|
40 | PORTB &= ~(1<<DDB2);
|
41 | // get pressure Value
|
42 | LSB = spi_fast_shift (0xF8);
|
43 | // determinate Communication
|
44 | PORTB |= (1<<DDB2);
|
45 |
|
46 | return ((MSB<<8U) + LSB);
|
47 | }
|
das ganze Projekt habe ich nochmals bei Google Drive hoch geladen:
https://drive.google.com/open?id=0B99TRuv5UwfWZzMxSmhVbF9VWVk
ich hoffe ich habe alles einigermaßen verständlich erklärt,
vielen Dank schon mal vor ab