Hi Leute !!! Ich möchte gern eine Funkstrecke zwischen zwei ATTiny45 mittels zweier nRF24L01+ Module aufbauen, welche über SPI angesprochen werden. Da ich allerdings mit diesem Interface noch nicht gearbeitet habe, wollte ich die SPI-Kommunikation zunächst einmal nur zwischen den direkt miteinander verbundenen µCs testen. Dabei sendet der Master abwechselnd im Abstand von 20 Sekunden jeweils den Wert "1" und "2". Empfängt der Slave eine "1", schaltet er eine LED an, empfängt er eine "2", wieder aus. Als Sendesignal blinkt am Master eine LED kurz. Das Ganze sollte dementsprechend also folgendermaßen ablaufen: > Master-LED blinkt --> Wert "1" wird gesendet --> Slave empfängt "1" --> LED am Slave leuchtet > 20 Sekunden warten > Master-LED blinkt --> Wert "2" wird gesendet --> Slave empfängt "2" --> LED am Slave aus > 20 Sekunden warten usw. ..... Leider tut sich am Slave nichts, d. h. die LED bleibt aus. ------------------------------------------------------------------------ ' MASTER $regfile = "attiny45.dat" $crystal = 128000 $hwstack = 36 $swstack = 8 $framesize = 24 Dim Datatosend As Byte Config Portb.2 = Output ' USCK ----> SCK (Slave) Config Portb.1 = Output ' DO ----> SDI (Slave) Config Portb.0 = Input ' DI ----> SDO (Slave) Portb.0 = 1 ' Pullup Config Portb.4 = Output ' Sende-LED Portb.4 = 0 Usicr = Bits(usiwm0 , Usics1 , Usiclk , Usitc) Do Datatosend = 1 Gosub Transmission Wait 20 Datatosend = 2 Gosub Transmission Wait 20 Loop End Transmission: Portb.4 = 1 Waitms 200 Portb.4 = 0 Usisr = Bits(usioif) ' USIOIF löschen und USI-Zähler auf 0 Usidr = Datatosend ' Datenregister beschreiben While Usisr.usioif = 0 : Set Usicr.usitc : Wend Return ------------------------------------------------------------------------ ' SLAVE $regfile = "attiny45.dat" $crystal = 128000 $hwstack = 36 $swstack = 8 $framesize = 24 Dim Empfangsbyte As Byte Config Portb.2 = Output ' USCK ----> SCK (Slave) Config Portb.1 = Output ' DO ----> SDI (Slave) Config Portb.0 = Input ' DI ----> SDO (Slave) Portb.0 = 1 ' Pullup Config Portb.4 = Output ' Signal-LED Usicr = Bits(usiwm0 , Usics1 , Usiclk , Usitc) Do Usisr = Bits(usioif) ' USIOIF löschen und USI-Zähler auf 0 ' 8 Takte warten bis Byte übertragen While Usisr.usioif = 0 : Set Usicr.usitc : Wend Empfangsbyte = Usidr ' Empfangsbyte aus USI-Datenregister lesen If Empfangsbyte = 1 Then Portb.4 = 1 ' Empfangsbyte = 1 --> LED an If Empfangsbyte = 2 Then Portb.4 = 0 ' Empfangsbyte = 2 --> LED aus Waitms 100 Loop End ------------------------------------------------------------------------ Was mache ich falsch? Grüße, The SphereX
In Bascom mach ich selber nichts. Aber solltest du nicht Bei dem Slave die Ausgänge als Eingänge un die Eingänge als Ausgänge machen? Du hast es doch sogar als Kommentar hinten gemacht. The SphereX schrieb: > Config Portb.2 = Output ' USCK ----> SCK (Slave) > Config Portb.1 = Output ' DO ----> SDI (Slave) > Config Portb.0 = Input ' DI ----> SDO (Slave)
Es ist keine gute Idee, zum Kennenlernen der SPI Schnittstelle einen Master und einen Slave selber zu machen. Besser nimmt man einen funktionierden Slave und spricht den an. Denn das wird man später zu 99% auch tun. Dann muss man nämlich das Datenblatt des Slaves lesen und den Master dazu passend programmieren. Man kann sich nicht den Slave so hinbiegen, dass es irgendwann läuft. Zum SPI allgemein: das sind nur 2 gekoppelte Schieberegister. Siehe http://www.lothar-miller.de/s9y/archives/15-SPI.html
:
Bearbeitet durch Moderator
@ m-obi " ... Aber solltest du nicht Bei dem Slave die Ausgänge als Eingänge un die Eingänge als Ausgänge machen? ... " Ich habe mich an der Bascom-Hilfe zum Thema "Universal Serial Interface" orientiert. Dort ist die Port-Konfiguration für den Slave so vorgegeben. http://avrhelp.mcselec.com/index.html?using_usi_universal_serial_int.htm @ Lothar Miller " ... Es ist keine gute Idee, zum Kennenlernen der SPI Schnittstelle einen Master und einen Slave selber zu machen. Besser nimmt man einen funktionierden Slave und spricht den an. ... " Ich dachte eigentlich gerade, daß meine Vorgehensweise logischer ist, als gleich mit dem in der späteren Anwendung vorgesehenen nRF24L01+ als Slave zu experiementieren. Denn wenn ich schon eine "einfache" µC --> µC Kommunikation nicht hinbekomme, wird das für mich als Anfänger ungleich kompliziertere Ansprechen des Funkmoduls natürlich erst recht nicht funktionieren. Hier kommen nämlich noch zahlreiche weitere Fehlerquellen hinzu, weshalb ich zunächst mal sicherstellen wollte, daß ich SPI (USI bei ATTinys) verstanden habe und dieses ordentlich läuft. Tja, und genau das tut es leider nach wie vor nicht :-( !!! Ich habe den Slave entsprechend der Bascom-Hilfe nochmals modifiziert, ohne Erfolg. ---------------------------------------------------------------------- ' SLAVE $regfile = "attiny45.dat" $crystal = 128000 $hwstack = 36 $swstack = 8 $framesize = 24 Dim Empfangsbyte As Byte Dim Usi_data_ready As Bit Config Portb.2 = Output ' USCK ----> SCK (Slave) Config Portb.1 = Output ' DO ----> SDI (Slave) Config Portb.0 = Input ' DI ----> SDO (Slave) Portb.0 = 1 Config Portb.4 = Output Portb.4 = 1 Waitms 200 Portb.4 = 0 Usicr = Bits(usiwm0 , Usics1 , Usioie) On Usi_ovf Usi_overflow_int Enable Usi_ovf Enable Interrupts Do If Usi_data_ready = 1 Then Reset Usi_data_ready If Empfangsbyte = 1 Then Portb.4 = 1 If Empfangsbyte = 2 Then Portb.4 = 0 End If Loop End Usi_overflow_int: Set Usi_data_ready Empfangsbyte = Usidr Usisr = &B01_000000 'Reset Overflow Flag and reset 4-Bit USI counter Return ------------------------------------------------------------------------ Dann ist auch immer die Rede von "Slave Select" als Leitung, über die der Master dem Slave den Beginn einer Übertragung signalisiert. Diese Funktion ist bei dem USI der Tinys aber gar nicht vorgesehen und kann laut Hilfe offensichtlich in diesem Fall auch weggelassen werden: "... We do not use Slave Select in this example ... ". Das verwirrt mich etwas. Ist es nun notwendig, den Übertragungsstart zu signalisieren, oder nicht? Außerdem verstehe ich nicht so ganz, wie es sich mit der Clock-Einstellung verhält. Im Bascom-Beispiel wird diese für den Master überhaupt nicht definiert, für den Slave dann allerdings schon: " ... Clock Source: External, positive edge ; External, both edges ... " ? Naja, und dann sollte nach meinem Verständnis während der Übertragung doch eigentlich ein Pegel am USCK-Pin (Clock) messbar sein, oder liege ich da falsch? Denn dort messe ich konstant 0 V. Grüße, The SphereX
Aber eine Verbindung von Ausgang zu Ausgang oder von Eingang zu Eingang macht doch nun wirklich keinen Sinn. Dort steht doch auch z.B. DO ----> SDI (Slave), also sollte es doch beim Slave ein input sein, oder was soll dass I bedeuten in SDI? Am Besten verwendet man auch die Bezeichnungen MISO (Master In Slave Out) und MOSI (Master Out Slave In), da sieht man genau wie was sein muss. Und SCK sollte beim Slave ein Einagang sein, da du ja den Takt vom Master bekommst.
Da hast Du absolut recht! Logisch betrachtet macht diese Konfiguration keinen Sinn. Dann gehe ich mal davon aus, daß es sich bei dem Bascom-Beispiel um einen Schreibfehler handelt. Allerdings habe ich es mittlerweile natürlich auch schon mit der logisch korrekten Beschaltung probiert. Aber auch da funktioniert die Datenübertragung nicht. Wenn die 0 V am USCK-Pin des Master während der Übertragung aber wie gesagt tatsächlich bedeuten, daß kein Synchronisationstakt generiert wird, kann's ja auch nicht funktionieren. Nur warum erzeugt der Master den Takt nicht mit: While Usisr.usioif = 0 : Set Usicr.usitc : Wend nach dem Befüllen des Datenregisters? Grüße, The SphereX
The SphereX schrieb: > Ich dachte eigentlich gerade, daß meine Vorgehensweise logischer ist Ist sie nicht. Denn wenn du beim Sender und beim Empfänger den gleichen Fehler ins Programm schreibst, dann kann es sein, dass die Übertragung gerade deshalb trotzdem klappt. Ein echter Slave verzeiht da nichts und du musst das richtige/passende Timing (CPOL+CPHA) verwenden... Mach zum Test deines Masters einfach mal eine Brücke vom MOSI zum MISO. Dann musst du die gesendeten Daten gleich wieder empfangen.
:
Bearbeitet durch Moderator
Ich hab's trotzdem erst mal mit den zwei Tinys durchgezogen ;-). Und nachdem ich die Port-Konfiguration nachmals geändert und auch die Verkabelung unidirektional ausgelegt habe > MASTER USCK (Out) ---> SLAVE USCK (In) > MASTER DO (MISO) ---> SLAVE DI (MOSI) funktioniert's jetzt auch :-). Danke für Eure Hinweise! Grüße, The SphereX
Wenn dann so > MASTER USCK (Out) ---> SLAVE USCK (In) > MASTER DO (MOSI) ---> SLAVE DI (MOSI) Nicht MISO, dass ist Master In Slave Out.
Nee, nee, ich glaube, da liegst Du falsch ;-) ! MISO = DO MOSI = DI Grüße, The SphereX
Findest du bei deinem den Fehler?
> MASTER DO (MISO) ---> SLAVE DI (MOSI)
^ ^ ^^
MISO sollte schon zu MISO und MOSI zu MOSI.
Ja, ist schon klar, und vom Logischen her hast Du ja recht. Aber ich beziehe mich hier auf die PIN-Beschriftung laut Atmel, für mein Beispiel speziell die des ATTiny45. Danach ist beim "Universal Serial Interface" der Tinys eben: > PB1 (MASTER) = DO (Data Out) = MISO und > PB0 (SLAVE) = DI (Data In) = MOSI Folglich ist die Verbindung MASTER ---> SLAVE hier nun mal MISO ---> MOSI, auch wenn's logisch keinen Sinn macht. Um Verwirrungen zu vermeiden hätte Atmel im Datenblatt vielleicht konsequenterweise die Begriffe MISO und MOSI komplett weglassen müssen, wenn man bei USI sowieso andere Bezeichnungen (DO, DI) gewählt hat. Folgende Seite: http://gizmosnack.blogspot.de/2013/04/tutorial-nrf24l01-and-avr.html beschäftigt sich z. B. sehr ausführlich mit dem Thema "nRF24L01 und AVR µC". Auch hier wird extra noch mal hervorgehoben, daß man entgegen der logischen Vorgehensweise, MISO vom µC mit MOSI vom nRF24L01 Funkmodul verbinden muß, damit die Datenübertragung funktioniert. " ... To get the USI to SPI up and running I found out that I had to connect the MOSI pin from the nRF to the MISO pin on the AVR and set it as output. Atmega88: PB3, ATtiny26: PB1, ATtiny85: PB1 ... " Grüße, The SphereX
Laut Figure 32. nRF24L01+ schematic for RF layouts with single ended 50Ω RF output benötigt er 6 Steuersignale. Einem MC mit max 6 IOs zu nehmen dürfte daher sinnlos sein.
Von den 6 ist der IRQ allerdings optional, d. h. für die Datenübertragung nicht erforderlich. Da waren's nur noch 5. Aber selbst wenn: Wofür gibt es denn Deinen super Fastboot ;-) :-) .... Reset-Pin als I/O konfiguriert, und fertig is'. Grüße, The SphereX
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.