26F064 EEPROM an ATMEGA328

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • 26F064 EEPROM an ATMEGA328

      Hallo,
      seit einer Woche versuche ich nun schon, einen SPI EEPROM zu verwenden.
      Das Programm soll einfach 5 Zeichen in dem EEPROM speichern und wieder auslesen. Zum Test lasse ich die ID des EEPROMs auslesen.
      Als Ergebnis erhalte ich die ID einwandfrei, aber da, wo die gespeicherten Daten erscheinen sollen, bekomme ich nur $FF zurück. Keine Ahnung, ob es beim Speichern oder Zurücklesen nicht funktioniert.Die Signale kann ich mit dem Oszilloskop sehen und da das Auslesen der ID funktioniert, gehe ich davon aus, daß alle Anschlüsse funktionieren.
      Hier das Testprogramm:

      BASCOM-Quellcode

      1. $regfile = "m328pdef.dat"
      2. $crystal = 16000000 ' oder enstprechende Taktfrequenz
      3. $loadersize = &H800
      4. $hwstack = 60
      5. $swstack = 60
      6. $framesize = 80
      7. $baud = 1200
      8. Dim B As Byte
      9. B = 2
      10. Config Portb.3 = Output
      11. Config Portb.2 = Output
      12. Config Portb.5 = Output
      13. Config Pinb.4 = Input
      14. Dim A(10) As Byte
      15. Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 0
      16. Spiinit
      17. $asm
      18. cbi portb,2 'Chip Select auf Low
      19. nop
      20. ldi r16,&H06 'write enable
      21. Out Spdr , R16 'Kommando senden
      22. Wait2:
      23. sbis spsr,spif 'Warten bis alles gesendet
      24. rjmp wait2
      25. sbi portb,2 'CS wieder high
      26. nop
      27. nop
      28. cbi portb,2 'Chip Select auf Low
      29. ldi r16,2 '2=schreiben
      30. Out Spdr , R16 'Kommando senden
      31. Wait3:
      32. sbis spsr,spif 'Warten bis alles gesendet
      33. rjmp wait3
      34. ldi r17,0 'Adresse highbyte
      35. Out Spdr , R17 'Kommando senden
      36. Wait11:
      37. sbis spsr,spif 'Warten bis alles gesendet
      38. rjmp wait11
      39. ldi r18,5 'Adresse midbyte
      40. Out Spdr , R18 'Kommando senden
      41. Wait12:
      42. sbis spsr,spif 'Warten bis alles gesendet
      43. rjmp wait12
      44. ldi r19,0 'Adreese lowbyte
      45. Out Spdr , R19 'Kommando senden
      46. Wait13:
      47. sbis spsr,spif 'Warten bis alles gesendet
      48. rjmp wait13
      49. ldi r16,&h61 '61=b
      50. Out Spdr , R16 'senden
      51. Wait14:
      52. sbis spsr,spif 'Warten bis alles gesendet
      53. rjmp wait14
      54. ldi r16,&h62 '62=c
      55. Out Spdr , R16 'senden
      56. Wait15:
      57. sbis spsr,spif 'Warten bis alles gesendet
      58. rjmp wait15
      59. ldi r16,&h63 '63=d
      60. Out Spdr , R16 'senden
      61. Wait16:
      62. sbis spsr,spif 'Warten bis alles gesendet
      63. rjmp wait16
      64. ldi r16,&h64 '64=e
      65. Out Spdr , R16 'senden
      66. Wait17:
      67. sbis spsr,spif 'Warten bis alles gesendet
      68. rjmp wait17
      69. ldi r16,&h65 '65=f
      70. Out Spdr , R16 'senden
      71. Wait18:
      72. sbis spsr,spif 'Warten bis alles gesendet
      73. rjmp wait18
      74. nop
      75. nop
      76. sbi portb,2
      77. $end Asm
      78. Do
      79. $asm
      80. cbi portb,2 'Chip Select auf Low
      81. ldi r20,&h9f 'ID lesen -Kommando
      82. Out Spdr , R20 'Kommando senden
      83. Wait26:
      84. sbis spsr,spif 'Warten bis alles gesendet
      85. rjmp wait26
      86. ldi r20,0
      87. Out Spdr , R20 'Dummy senden damit Takt ausgegeben wird
      88. Wait29:
      89. sbis spsr,spif 'Warten bis alles gesendet
      90. rjmp wait29
      91. in r16,spdr
      92. rcall serout
      93. Out Spdr , R20
      94. Wait6:
      95. sbis spsr,spif 'Warten bis alles gesendet
      96. rjmp wait6
      97. in r16,spdr
      98. rcall serout
      99. Out Spdr , R20
      100. Wait7:
      101. sbis spsr,spif 'Warten bis alles gesendet
      102. rjmp wait7
      103. in r16,spdr
      104. rcall serout
      105. sbi portb,2 'Chip Select auf High
      106. $end Asm
      107. $asm
      108. cbi portb,2 'Chip Select auf Low
      109. ldi r20,&h03 '03 = READ
      110. Out Spdr , R20 'Kommando senden
      111. Wait30:
      112. sbis spsr,spif 'Warten bis alles gesendet
      113. rjmp wait30
      114. ldi r20,0 'Adresse High
      115. Out Spdr , R20 'Byte senden
      116. Wait31:
      117. sbis spsr,spif 'Warten bis alles gesendet
      118. rjmp wait31
      119. ldi r20,5 'Adresse mid
      120. Out Spdr , R20 'Byte senden
      121. Wait32:
      122. sbis spsr,spif 'Warten bis alles gesendet
      123. rjmp wait32
      124. ldi r20,0 'Adresse Low
      125. Out Spdr , R20 'Byte senden
      126. Wait33:
      127. sbis spsr,spif 'Warten bis alles gesendet
      128. rjmp wait33
      129. ldi r20,0
      130. Out Spdr , R20 'Dummy senden
      131. Wait34:
      132. sbis spsr,spif 'Warten bis alles gesendet
      133. rjmp wait34
      134. in r16,spdr 'Wert einlesen
      135. rcall serout 'An UART senden
      136. Out Spdr , R20
      137. Wait35:
      138. sbis spsr,spif 'Warten bis alles gesendet
      139. rjmp wait35
      140. in r16,spdr
      141. rcall serout
      142. Out Spdr , R20
      143. Wait36:
      144. sbis spsr,spif 'Warten bis alles gesendet
      145. rjmp wait36
      146. in r16,spdr
      147. rcall serout
      148. Out Spdr , R20
      149. Wait37:
      150. sbis spsr,spif 'Warten bis alles gesendet
      151. rjmp wait37
      152. in r16,spdr
      153. rcall serout
      154. Out Spdr , R20
      155. Wait38:
      156. sbis spsr,spif 'Warten bis alles gesendet
      157. rjmp wait38
      158. in r16,spdr
      159. rcall serout
      160. Out Spdr , R20
      161. Wait39:
      162. sbis spsr,spif 'Warten bis alles gesendet
      163. rjmp wait39
      164. in r16,spdr
      165. rcall serout
      166. sbi portb,2 'Chip Select auf High
      167. ldi r16,&h70 '$70 nur für Test an UART senden
      168. rcall serout
      169. jmp readend
      170. $end asm
      171. $asm
      172. Serout:
      173. sbis ucsr0a,udre0
      174. rjmp serout
      175. Out Udr , R16
      176. ret
      177. Readend:
      178. $end Asm
      179. Wait 2
      180. Loop
      181. End
      Alles anzeigen
      Ich hoffe, daß mir hier jemand helfen kann.
      Danke schon mal.
      MFG
      Torsten Müller
    • Die Anwendung benötigt ein sehr genaues Timing. Während der Prozessor die Daten über SPI in SPDR reintaktet müssen noch ein paar andere Befehle ausgeführt werden.
      Bei SPIIN muß ich warten, bis alles reingetaktet wurde und an eine Variable übergeben wurde, daß dauert zu lange.
      Deshalb muß ich das in Assembler machen.
    • elcomportal schrieb:

      Die Anwendung benötigt ein sehr genaues Timing. Während der Prozessor die Daten über SPI in SPDR reintaktet müssen noch ein paar andere Befehle ausgeführt werden.
      Bei SPIIN muß ich warten, bis alles reingetaktet wurde und an eine Variable übergeben wurde, daß dauert zu lange.
      Deshalb muß ich das in Assembler machen.
      Sind solche eeprom nicht eher langsam? Bist du vielleicht mit deinem Assembler zu schnell? Probier doch mal die bascom-Befehle zum Testen. Wenn es mit denen geht, kannst du immer noch mit Assembler optimieren, entweder beim Lesen oder Schreiben, oder beides.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Habe jetzt mal folgendes Testprogramm geschrieben, aber es gibt das selbe Ergebnis. Alles was ich auslese ist $FF

      Quellcode

      1. Reset Portb.2
      2. A(1) = &H06
      3. Spiout A(1) , 1
      4. Set Portb.2
      5. Reset Portb.2
      6. A(1) = &HC7
      7. Spiout A(1) , 1
      8. Set Portb.2
      9. Wait 1
      10. Reset Portb.2
      11. A(1) = &H06
      12. Spiout A(1) , 1
      13. Set Portb.2
      14. Reset Portb.2
      15. A(1) = &H02
      16. Spiout A(1) , 1
      17. A(1) = &H00
      18. Spiout A(1) , 1
      19. A(1) = &H00
      20. Spiout A(1) , 1
      21. A(1) = &H00
      22. Spiout A(1) , 1
      23. A(1) = "a"
      24. Spiout A(1) , 1
      25. A(1) = "b"
      26. Spiout A(1) , 1
      27. A(1) = "c"
      28. Spiout A(1) , 1
      29. A(1) = "d"
      30. Spiout A(1) , 1
      31. A(1) = "e"
      32. Spiout A(1) , 1
      33. A(1) = "f"
      34. Spiout A(1) , 1
      35. Set Portb.2
      Alles anzeigen
    • elcomportal schrieb:

      Die Anwendung benötigt ein sehr genaues Timing. Während der Prozessor die Daten über SPI in SPDR reintaktet müssen noch ein paar andere Befehle ausgeführt werden.
      Bei SPIIN muß ich warten, bis alles reingetaktet wurde und an eine Variable übergeben wurde, daß dauert zu lange.
      Deshalb muß ich das in Assembler machen.
      Die SPI-Hardware kümmert sich um das Takten, du musst nur noch ein Register füllen bzw. abholen.
    • elcomportal schrieb:

      Habe jetzt mal folgendes Testprogramm geschrieben, aber es gibt das selbe Ergebnis. Alles was ich auslese ist $FF
      Hallo,

      ist Eeprom neu oder gelöscht sind alle Zellen typischerweise 0xFFh.
      Somit nehme ich an er wird nicht beschrieben.
      Kann durch folgenden Bedingungen beeinflusst werden:
      Der Betriebsart (SPI-Mode)/ der Bus-Geschwindigkeit/ der Anwenderschaltung, z.B. der Größe der Pull-Up- Widerstände/Last und der Impedanz der Bus-Leitungen usw.

      Im Code stellst du mit Config Spi den Mode auf 0 soweit okay aber im ASM scheint es so zu sein das CPHA 1 ist wenn Daten übernommen werden sollen.
      Versuch einfach malPolarity = High eventuell auch Phase = 1.
      Wie schon geschrieben wurde. In voll Bacomcode setzt du kein lesen ab. SPI ist doch unidirektional somit kannst du lesen und schreiben fast von jedem Ort(im Code) starten(wenn gewünscht).

      Config SPI ist in Assembler geschrieben und nimmt dir sehr, sehr viel „Denkarbeit“ ab.
      Kann auch kein Zeitvorteil mit deiner ASM – Einbindung erkennen auch nicht wenn mehrere Teilnehmer am Bus sein sollten.
      Der kritische Faktor ist oft der Start- Endzeitpunk.
      Mit jeder Taktperiode wird ein Bit übertragen. Beim üblichen Bytetransfer sind also acht Taktperioden für eine vollständige Übertragung nötig. Es können auch mehrere Worte hintereinander übertragen werden, wobei in der Spezifikation nicht festgelegt ist, ob zwischen jedem Wort das SS-Signal kurz wieder auf High gezogen werden muss. Eine Übertragung ist beendet, wenn das Slave-Select- Signal endgültig auf High gesetzt wird. Dies Signal mit Waite ($asm) für Synchronisierung zu nutzen ist für AVR er negativ.

      Hoffe nicht mit Grundlagen genervt zu haben. a_78_5e922510
      Gruß
    • Vielen Dank erstmal an Alle für Eure Antworten.
      Jetzt funktioniert es. Das Problem war, daß alle Bits im BPR Register im Flash noch gesetzt waren. Somit war der Chip noch write protected.
      Also habe ich einmalig folgendes ausgeführt:

      Quellcode

      1. Reset Portb.2
      2. A(1) = &H06 'Write Enable
      3. Spiout A(1) , 1
      4. Set Portb.2
      5. Waitms 10
      6. Reset Portb.2
      7. A(1) = &H98 'RESET all bits of BPR register
      8. Spiout A(1) , 1
      9. Set Portb.2

      Danach funktioniert mein Assembler-Code einwandfrei:

      Quellcode

      1. $regfile = "m328pdef.dat"
      2. $crystal = 16000000 ' oder enstprechende Taktfrequenz
      3. $loadersize = &H800
      4. $hwstack = 60
      5. $swstack = 60
      6. $framesize = 80
      7. $baud = 1200
      8. Dim B As Byte
      9. B = 2
      10. Config Portb.3 = Output
      11. Config Portb.2 = Output
      12. Config Portb.5 = Output
      13. Config Pinb.4 = Input
      14. Dim A(10) As Byte
      15. Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 0
      16. Spiinit
      17. $asm
      18. cbi portb,2 'Chip Select auf Low
      19. nop
      20. ldi r16,&H06 'write enable
      21. Out Spdr , R16 'Kommando senden
      22. Wait2:
      23. sbis spsr,spif 'Warten bis alles gesendet
      24. rjmp wait2
      25. sbi portb,2 'CS wieder high
      26. nop
      27. nop
      28. cbi portb,2 'Chip Select auf Low
      29. ldi r16,2 '2=schreiben
      30. Out Spdr , R16 'Kommando senden
      31. Wait3:
      32. sbis spsr,spif 'Warten bis alles gesendet
      33. rjmp wait3
      34. ldi r17,0 'Adresse highbyte
      35. Out Spdr , R17 'Kommando senden
      36. Wait11:
      37. sbis spsr,spif 'Warten bis alles gesendet
      38. rjmp wait11
      39. ldi r18,0 'Adresse midbyte
      40. Out Spdr , R18 'Kommando senden
      41. Wait12:
      42. sbis spsr,spif 'Warten bis alles gesendet
      43. rjmp wait12
      44. ldi r19,0 'Adreese lowbyte
      45. Out Spdr , R19 'Kommando senden
      46. Wait13:
      47. sbis spsr,spif 'Warten bis alles gesendet
      48. rjmp wait13
      49. ldi r16,&h61 '61=b
      50. Out Spdr , R16 'senden
      51. Wait14:
      52. sbis spsr,spif 'Warten bis alles gesendet
      53. rjmp wait14
      54. ldi r16,&h62 '62=c
      55. Out Spdr , R16 'senden
      56. Wait15:
      57. sbis spsr,spif 'Warten bis alles gesendet
      58. rjmp wait15
      59. ldi r16,&h63 '63=d
      60. Out Spdr , R16 'senden
      61. Wait16:
      62. sbis spsr,spif 'Warten bis alles gesendet
      63. rjmp wait16
      64. ldi r16,&h64 '64=e
      65. Out Spdr , R16 'senden
      66. Wait17:
      67. sbis spsr,spif 'Warten bis alles gesendet
      68. rjmp wait17
      69. ldi r16,&h65 '65=f
      70. Out Spdr , R16 'senden
      71. Wait18:
      72. sbis spsr,spif 'Warten bis alles gesendet
      73. rjmp wait18
      74. nop
      75. nop
      76. sbi portb,2
      77. cbi portb,2 'Chip Select auf Low
      78. ldi r20,&h03 '03 = READ
      79. Out Spdr , R20 'Kommando senden
      80. Wait30:
      81. sbis spsr,spif 'Warten bis alles gesendet
      82. rjmp wait30
      83. ldi r20,0 'Adresse High
      84. Out Spdr , R20 'Byte senden
      85. Wait31:
      86. sbis spsr,spif 'Warten bis alles gesendet
      87. rjmp wait31
      88. ldi r20,0 'Adresse mid
      89. Out Spdr , R20 'Byte senden
      90. Wait32:
      91. sbis spsr,spif 'Warten bis alles gesendet
      92. rjmp wait32
      93. ldi r20,0 'Adresse Low
      94. Out Spdr , R20 'Byte senden
      95. Wait33:
      96. sbis spsr,spif 'Warten bis alles gesendet
      97. rjmp wait33
      98. ldi r20,0
      99. Out Spdr , R20 'Dummy senden
      100. Wait34:
      101. sbis spsr,spif 'Warten bis alles gesendet
      102. rjmp wait34
      103. in r16,spdr 'Wert einlesen
      104. rcall serout 'An UART senden
      105. Out Spdr , R20
      106. Wait35:
      107. sbis spsr,spif 'Warten bis alles gesendet
      108. rjmp wait35
      109. in r16,spdr
      110. rcall serout
      111. Out Spdr , R20
      112. Wait36:
      113. sbis spsr,spif 'Warten bis alles gesendet
      114. rjmp wait36
      115. in r16,spdr
      116. rcall serout
      117. Out Spdr , R20
      118. Wait37:
      119. sbis spsr,spif 'Warten bis alles gesendet
      120. rjmp wait37
      121. in r16,spdr
      122. rcall serout
      123. Out Spdr , R20
      124. Wait38:
      125. sbis spsr,spif 'Warten bis alles gesendet
      126. rjmp wait38
      127. in r16,spdr
      128. rcall serout
      129. Out Spdr , R20
      130. Wait39:
      131. sbis spsr,spif 'Warten bis alles gesendet
      132. rjmp wait39
      133. in r16,spdr
      134. rcall serout
      135. sbi portb,2 'Chip Select auf High
      136. ldi r16,&h70 '$70 nur für Test an UART senden
      137. rcall serout
      138. jmp readend
      139. $end Asm
      140. $asm
      141. Serout:
      142. sbis ucsr0a,udre0
      143. rjmp serout
      144. Out Udr , R16
      145. ret
      146. Readend:
      147. $end Asm
      148. Wait 2
      149. Loop
      150. End
      Alles anzeigen
      Es werden 5 Bytes in den Flash geschrieben, dann werden die 5 Bytes wieder gelesen und über UART ausgegeben.