Forum: Mikrocontroller und Digitale Elektronik Kommunikationsproblem AVR Studio 6.1 mit ATtiny84A


von Hans F. (dani1632)


Lesenswert?

Hallo!

Ich programmiere den ATtiny84A mit AVRStudio6.1 über SPI Schnittstelle 
mit debugOnWire. Als Programmierdevice verwende ich JTAG ICE mk2, 
welches ich mit dem 6 poligen Adapterstecker mit den entsprechenden 
µC-Pins verbinde.

Zuerst wollte ich nur 4 LEDs (Parallelschaltung je zweier in Serie 
geschalteter LEDs mit 2 Vorwiderständen) blinken lassen, um zu sehen, ob 
die Kommunikation funktioniert. Funktionierte einwandfrei, verwendete 
dazu folgendes Programm:
1
#define F_CPU 8000000
2
#include<avr/io.h>
3
#include<util/delay.h>
4
5
int main(void)
6
{
7
   DDRB = 0b00001000; // PB3 als Ausgang, hier hängen die LEDs
8
9
   while(1)
10
   {
11
      PORTB = 0b00001000; // PB3 auf HIgh
12
      _delay_ms(500);
13
      PORTB = 0b00000000; // PB3 auf Low
14
      _delay_ms(500);
15
   }
16
17
   return 0;
18
}
Das ganze funktionierte. AUch unter Tools-> AVR Prog bekam ich beim 
Lesen eine DeviceID zurück, die Kommunikation funktionierte.

Dann löschte ich das #define F_CPU... weg und wollte das Programm wieder 
auf den µC spielen, danach funktionierte die Kommunikation nicht mehr. 
(kann kein Programm mehr auf den µC laden und auch unter Tolls-AVR-Prog 
bekomme ich keine DeviceID zurück).

Woran kann das liegen? Was hat das mit dem F_CPU auf sich? Die default 
Frequenz ist 8MHZ, muss ich die trotzdem mit #define F_CPU definieren?? 
Wenn ich dieses define weglasse, bekomme ich beim kompilieren eine 
Warning, dass dieses define F_CPU fehlt.

Kann ich mit diesem deifne die Taktfrequenz einstellen oder muss ich das 
über die Fuses machen? Oder ist beides möglich bzw ist das das gleiche? 
Der Attiny84A hat auch die Möglichkeit, intern mit 128kHz zu laufen. Im 
Datenblatt steht, dass ich dafür eine bestimmte Bitkombination in ein 
bestimmtes Register schreiben muss. Das wäre die dritte Möglichkeit?!

Zurück zum Hauptproblem der fehlenden Kommunikation nach der Wegnahme 
von define F_CPU... Hat jemand eine Idee, woran das liegen kann?

Danke, lG

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Daniel F. schrieb:
> Dann löschte ich das #define F_CPU... weg und wollte das Programm wieder
> auf den µC spielen, danach funktionierte die Kommunikation nicht mehr.

Das hat keinen ursächlichen Zusammenhang.

Versuch mal rauszufinden, was du zeitgleich noch alles geändert
haben könntest.  Irgendwas davon hat offenbar dazu geführt, dass dein
Controller nicht mehr ansprechbar ist.

von Sandhase (Gast)


Lesenswert?

Hallo,
ich hatte mal ein ähnliches Problem, bei mir war die Lösung der Einsatz 
eines externen Oszilators, damit war der uC wider ansprechbar, 
komischerweise konnte er nach dem Programmieren mit externem oszi auch 
wider ohne betrieben werden.

Gruss
Sandhase

von Hans F. (dani1632)


Lesenswert?

Hmmm, danke für eure Antworten!

Kommt sowas denn öfter vor? Was dürfte ich z.B. denn nicht verändern?

Ich wüsste nicht, dass ich sonst noch was geändert habe... Warum wird 
denn eine Warning ausgegeben, wenn man dieses #define F_CPU nicht 
benutzt? Die Taktfrequenz müsste eigentlich defaultmäßig eingestellt 
sein oder?

Dieser ATtiny hat auch nur 4 Pins am Port B (PB0-PB3). Macht das was, 
wenn ich das Port B trotzdem mit 8 Bits anspreche (siehe Code im ersten 
Beitrag)?

Muss man beim Start eines µC Programmes sonst noch irgendwas spezielles 
initialisieren (außer die Standardfunktionen, die man im Programm 
benötigt wie PWM, Timer, ADC usw...) ? Oder gibt es für alle Funktionen 
eine default-Einstellung?

Dankesehr, lG

von Dietrich L. (dietrichl)


Lesenswert?

Daniel F. schrieb:
> Kommt sowas denn öfter vor? Was dürfte ich z.B. denn nicht verändern?

die Fuses

> Ich wüsste nicht, dass ich sonst noch was geändert habe...

kann ggf. durch falsche Bedienung passiert sein (Fuses); vielleicht hast 
Du auch den Takt zum Programmieren verstellt (muss < als 1/4 des 
µC-Taktes sein)

> Warum wird
> denn eine Warning ausgegeben, wenn man dieses #define F_CPU nicht
> benutzt? Die Taktfrequenz müsste eigentlich defaultmäßig eingestellt
> sein oder?

Das #define F_CPU wird in Deinem Fall nur zum berechnen der Zeiten für 
delay benutzt. Ohne das #define wird mit dem Defaultwert gearbeitet 
(1MHz?) und die Warnung ausgegeben.

> Dieser ATtiny hat auch nur 4 Pins am Port B (PB0-PB3). Macht das was,
> wenn ich das Port B trotzdem mit 8 Bits anspreche (siehe Code im ersten
> Beitrag)?

Das ist ein 8-Bit-µC; da kann man nicht 4 Bit ansprechen. Und intern hat 
das Port schon 8 Bit, nur das Gehäuse hat nicht genug Pins.

>
> Muss man beim Start eines µC Programmes sonst noch irgendwas spezielles
> initialisieren (außer die Standardfunktionen, die man im Programm
> benötigt wie PWM, Timer, ADC usw...) ? Oder gibt es für alle Funktionen
> eine default-Einstellung?

Die Default-Einstellungen stehen im Datenblatt.

Gruß Dietrich

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dietrich L. schrieb:
> Und intern hat das Port schon 8 Bit, nur das Gehäuse hat nicht genug
> Pins.

Das muss keineswegs so sein.

Ein Fehler, den ich mal gemacht habe, war (auf einem ATmega1281):
1
DDRA = DDRB = DDRC = DDRD = DDRE = DDRF = DDRG = 0xff;

Der Fehler ist gar nicht so offensichtlich, nicht wahr? ;-)

Was passiert?

0xff wird an DDRG zugewiesen.

DDRG wird gelesen, und der Wert an DDRF zugewiesen.

DDRF wird gelesen, und der Wert an DDRE zugewiesen.

…

DDRB wird gelesen, und der Wert an DDRA zugewiesen.

Erstens fällt natürlich sofort auf, dass es unsinnig ist, die 0xFF
jedesmal erst wieder aus einem Port zu lesen, wo sie doch sowieso
noch in einem CPU-Register herumsteht.

Der Fehler aber war: Port G auf dem ATmega1281 implementiert nur
PG0 bis PG4.  Die oberen drei Bits sind nicht implementiert.  Das
Rücklesen von DDRG ergab daher 0x1F (statt der erwarteten 0xFF),
und dieser Wert wurde danach in die weiteren DDRx-Register geschrieben.

So viel zu „intern werden alle 8 Bit implementiert“. ;-)  Nein, das
muss keineswegs der Fall sein, auch wenn der Befehlssatz halt nur
8-bit-weise darauf zugreifen kann.

von Hans F. (dani1632)


Lesenswert?

Hallo, danke für die Infos!

@ Jörg: Hab ich das richtig verstanden, dass man also mit 8 Bit ins 
PortB Register schreiben kann, aber beim Auslesen aufpassen sollte?

@all: Wie kann ich nun die Taktfrequenz auf 128 kHz umstellen? Im 
Datenblatt
http://www.atmel.com/Images/doc8183.pdf
steht auf Seite 127, ich muss die CKSEL Fuses auf 0100 stellen. Ist das 
nun im AVR Stduio vor dem Programmieren unter "Fuses" einzustellen oder 
kann man das SOftwaremäßig machen, indem man ins Register CKSEL den Wert 
0100 schreibt? Oder ist beides möglich? Mich irretiert das Ganze etwas, 
weil ich während des Programmierens das Programm immer mit dem 
Debug-Modus auf den µC spiele, und dabei kann ich keine Fuses 
einstellen?!

Dankesehr, lG

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Daniel F. schrieb:

> @ Jörg: Hab ich das richtig verstanden, dass man also mit 8 Bit ins
> PortB Register schreiben kann, aber beim Auslesen aufpassen sollte?

Du darfst halt nur nicht davon ausgehen, dass die oberen 4 Bit in
irgendeiner Weise schreibbar wären.  Das Datenblatt beschreibt sie
als read/only mit Bitwert 0, und genau das passiert auch, wenn man
sie zurückliest.

> @all: Wie kann ich nun die Taktfrequenz auf 128 kHz umstellen?

Du musst die Fuses umstellen, ja, und das ist ein Programmiervorgang
(also nichts, was man zur Laufzeit machen könnte).

Ist aber eine ganz schlechte Idee: die maximale ISP-Taktfrequenz
ist f_CPU/4, du kannst danach also nur noch mit maximal 32 kHz
programmieren.

Normalerweise ist es sinnvoller, die CPU mit höherem Takt arbeiten
zu lassen und dann zum Energiesparen schlafen zu legen.  Alternativ
kann man den Takt auch zur Laufzeit herunter teilen lassen, das geht
übers Register CLKPR, siehe Handbuch 7.10.2.  Damit kommst du bis
auf etwa 30 kHz herunter.  Der Vorteil ist hier aber, dass beim
Reset (und damit fürs ISP) wieder volle 1 bzw. 8 MHz benutzt werden
(je nach CKDIV8-Fuse) und damit das ISP schnell bedient werden kann.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Jörg Wunsch schrieb:
> Ist aber eine ganz schlechte Idee: die maximale ISP-Taktfrequenz
> ist f_CPU/4, du kannst danach also nur noch mit maximal 32 kHz
> programmieren.

Nunja, das dauert länger, aber es geht. Wenn man ungeduldig ist, kann 
man in einem ersten Programmierschritt, die Fuses wieder zurück auf 8 
MHz Takt stellen und danach das Flashen starten.

> Normalerweise ist es sinnvoller, die CPU mit höherem Takt arbeiten
> zu lassen und dann zum Energiesparen schlafen zu legen.

Meistens ja.

> Alternativ
> kann man den Takt auch zur Laufzeit herunter teilen lassen, das geht
> übers Register CLKPR, siehe Handbuch 7.10.2.  Damit kommst du bis
> auf etwa 30 kHz herunter.  Der Vorteil ist hier aber, dass beim
> Reset (und damit fürs ISP) wieder volle 1 bzw. 8 MHz benutzt werden
> (je nach CKDIV8-Fuse) und damit das ISP schnell bedient werden kann.

Ja, das ist eine geschickte Sache, man kann die Geschwindigkeit zur 
Laufzeit dynamisch anpassen.
Die CKDIV8-Fuse bestimmt allerdings nur den Defaultwert für CLKPR, mehr 
nicht. Man hat also unabhängig von diesem Fusebit alle Teiler-Werte 
zwischen 1 und 256 zur Verfügung. Das heißt, man kann auch trotz 
programmierter CKDIV8-Fuse mit 8 MHz Takt arbeiten.

von Hans F. (dani1632)


Lesenswert?

Hallo, danke für die Antwort!

Ich denke, ich werde den Takt für die ersten Tests mal auf 1MHz 
belassen!

Wenn ich den Takt also nur über die Fuses einstellen kann, dann kann ich 
im Debug-Modus nie den Takt ändern?

lG

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Daniel F. schrieb:
> Wenn ich den Takt also nur über die Fuses einstellen kann, dann kann ich
> im Debug-Modus nie den Takt ändern?

Das war dann wohl ein Missverständnis. Du kannst den Takt direkt aus dem 
Programm heraus ändern. Falls du den internen 8-MHz-Oszillator 
verwendest (Fabrikeinstellung), kannst du den Takt in Faktor-2-Stufen 
zwischen 31,25 kHz und 8 MHz jederzeit beliebig ändern. Das geht über 
das Register CLKPR, wie Jörg Wunsch schon geschrieben hat.

von Hans F. (dani1632)


Lesenswert?

Ok danke, das ist es, was mich immer irritierte, weil ich sonst im 
Debugmodus ja nie etwas ändern kann... Wie kann ich denn den brown out 
detektor aktivieren im debugmodus? Oder muss ich einmal die fuses mit 
aktiviertem BOD programmieren, damit das aktiviert ist? (wenn ich danach 
im debug modus arbeite?

lG

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Daniel F. schrieb:
> Oder muss ich einmal die fuses mit aktiviertem BOD programmieren, damit
> das aktiviert ist?

So ist es, der Brownout-Detektor gehört auch zu den Dingen, die man
nur per Fuse modifizieren kann.

von Hans F. (dani1632)


Lesenswert?

Super, dankesehr :)

von Hans F. (dani1632)


Lesenswert?

Hallo!

Jetzt hab ich dazu noch ein Problem: Es geht wieder um mein 
usprüngliches Problem (erster Beitrag): Ich habe jetzt eine neue 
Schaltung mit neuem µC aufgebaut, nachdem ich dachte, dass der µC kaputt 
sei, weil ich keine DeviceID beim Lesen zurück bekomme.

Nun hab ich mit der neuen Schaltung genau das gleiche Problem: zuerst 
funktioniert alles einwandfrei, dann nach ein paar Programmierungen kann 
ich den µC auf einmal nicht mehr lesen (bekomme keine DeviceID zurück 
bei Tools-AVRProgramming).

Die einzige Fuse, die ich verstellt habe, ist die DWEN (da wird man beim 
ersten Programmieren gefragt, ob man diese aktivieren will, da ich ja 
mit debugOnWire programmiere). Aber selbst damit funktionierte es noch 
eine Weile (einige Programmierungen)...?!

Das komische dabei ist, dass ich den µC trotzdem noch von außen (also 
nicht über Tools -> AVRProg....) programmieren kann (mit den beiden 
grünen Pfeilen (Start with Debugging / Start without Debugging). Das 
Programm wird dabei auf den µC gespielt und er läuft! Also ist der µC 
doch nicht kaputt, wie ich das verstehe... Ich kann auch ganz normal 
debuggen... Kann sich das jemand erklären?

Was ich diesmal zum Schluss (bevor das Problem auftrat) geändert hatte, 
war, dass ich versehentlich den PIN PB3 auf High geschalten habe, das 
ist der Reset-Pin. In meinem ersten Beitrag sind alle PB3 durch PB2 zu 
ersetzen, war nur ein Tippfehler, die LEDs hängen an PB2. Ich habe also 
versehentlich PB3 auf High gesetzt (war im DDRB-Register noch 
defaultmäßig eingestellt, also vermutlich auf Eingang). Wenn ich den nun 
auf High setzte, aktiviere ich den internen Pullup, oder? Kann dieses 
Setzen etwas mit meinem Problem zu tun haben?

Vielen Dank, lG

von Hans F. (dani1632)


Lesenswert?

Hallo!

Falls jemand auf das gleiche Problem stößt, hab jetzt den Fehler 
gefunden:
Wenn man über debugOnWire programmieren will, muss die DWEN fuse gesetzt 
sein. Man wird beim ersten Übertragungsversuch auch darauf aufmerksam 
gemacht, mit einer Bestätigung dieser Medlung wird die Fuse gesetzt. (Es 
muss dann noch einmal die Vcc getoggelt werden, damit ein reset 
ausgelöst wird).

Wenn diese Fuse gesetzt ist, kann man aber nicht mehr über Tools->AVR 
Prog programmieren bzw. die Fuses und die DeviceID auslesen. Man kann 
das Programm also nur mit den beiden Buttons (grüne "Pfeile") "Start 
Debugging" und "Start without Debugging" in den µC spielen. Man kann 
aber irgendwo im Menü (ich glaub es war unter Debug -> Disable 
debugOnWIre oder so ähnlich) diese Fuse wieder disablen und danach 
wieder ganz normal unter Tools-AVR-Prog auf die Fuses zugreifen, die 
DeviceID auslesen und also auch wieder Programmieren.

Ich bin Anfänger, deswegen bin ich etwas verwundert, dass dieses Problem 
keinem bekannt ist (falls das überhaupt ein "Problem" oder durchaus 
sinnvoll ist, wie gesagt, bin Anfänger :) ). Wird dieses debugOnWire so 
selten verwendet?

lG

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Daniel F. schrieb:
> Ich bin Anfänger, deswegen bin ich etwas verwundert, dass dieses Problem
> keinem bekannt ist

Das ist kein „Problem“, sondern so ist halt das Design von debugWIRE:
während debugWIRE aktiv ist, ist /RESET nicht verfügbar.  Da /RESET
aber für den ISP-Algorithmus als “chip select”-Pin fungiert, kann man
in dieser Zeit kein ISP machen.

Der Rückweg ist (leider) ein wenig beschwerlich: man muss innerhalb
des debugWIRE-Modus (für den man daher zwingend ein Debugger-Tool
braucht, also mehr als nur einen ISP-Adapter) mit einer bestimmten
Aktion temporär debugWIRE wieder deaktivieren.  Dieses temporäre
Deaktivieren wirkt bis zum nächsten Power-On; da wird dann die
DWEN-Fuse wieder gelesen um zu bestimmen, ob nun debugWIRE gewünscht
ist oder nicht.  Nachdem man debugWIRE auf diese Weise vorübergehend
deaktiviert hat, kann man dann wieder normal ISP machen und somit auch
die DWEN-Fuse selbst löschen.  (Muss man aber nicht, man kann genauso
gut auch einfach nur per ISP ein neues Image aufspielen, und nach dem
nächsten Power-On ist debugWIRE wieder da.)

Atmel Studio versteckt den kompletten Rückweg meines Wissens hinter
einem einzigen Menüpunkt.

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.