LED auf Tastendruck

Was passiert denn mit dem High-, Low-Byte in C? Schreibt der Compiler das um?

Ja, inzwischen macht dies der Compiler, so dass du dich nicht mehr darum kümmern musst. LotadaC hat es ja schon erklärt.

Es kann hier und da allerdings vorkommen, dass er bei bestimmten Controllern mal ein Register nicht kennt (nach meiner Erfahrung. TCNT1 zB. gibts ja normalerweise nicht), hier musst du dann die einzelnen 8bit Register behandeln.

Dirk :ciao:
 
Ich glaube ganz am Anfang wurde gefragt, warum ich nicht die neueren Versionen des ATmega8, den ATmega88 benutze. Kann mir jemand den Unterschied der beiden erklären? Die haben den selbern Speicher, wahrscheinlich kann der neuere höher getaktet werden, aber trotzdem sind es ja beide noch 8-bit Mikrocontroller oder irre ich mich da?
 
...neueren Versionen des ATmega8, den ATmega88 benutze. Kann mir jemand den Unterschied der beiden erklären?



ATmega88 im Vergleich zu ATmega8:
Erheblich mehr ext. Interrupts (liegt an PinChangeInterrupt)
20MHz anstelle 16MHz
zwei SPI anstelle 1 SPI (da USART MasterSPI kann)
6 anstelle 3 OutputCompare Pins (PWM)

Ich hoffe, ich habe nichts vergessen :)

Dirk :ciao:
 
Hallo,

Hehe, ok, ich verstehe nur Bahnhof :D Ich glaub ich lese erstmal noch ein bisschen Datenblatt :pcguru:
dann pack ich noch nen ICE dazu :p

Bei den neuen sind wegen der vielen Funktionen manche Register aus dem IO-Bereich in den Memory-Bereich gewandert. Wenn man mit Assembler arbeitet muß man die mit anderen Befehlen bearbeiten. Außerdem kann man nicht mal eben mit einem Befehl ein Bit setzen oder löschen. Beim Mega48,88,168,328 ist zB der UART vom IO in den Memory gewandert. Man verliert also durch die zusätzliche Anzahl an Befehlen evtl wieder den Vorteil der zusätzlichen 4 MHz Taktrate.

Gruß
Dino
 
Für mich hört sich das an, als wäre es viel schwieriger mit dem umzugehen. Ich glaube es dauert noch ein bisschen, bis ich den mega8 oder mega16 wirklich ausreizen kann. Und einfache LED-Dimmer oder Motorsteuerungen werden damit wahrscheinlich super laufen.

Mit dem USART kann man mit entsprechendem Kabel den MC mit dem Computer verbinden oder?
 
Hallo zusammen,
Hallo,
dann pack ich noch nen ICE dazu :p

:D da sieht man den Assembler Freak ;)

Für mich hört sich das an, als wäre es viel schwieriger mit dem umzugehen. Ich glaube es dauert noch ein bisschen, bis ich den mega8 oder mega16 wirklich ausreizen kann. Und einfache LED-Dimmer oder Motorsteuerungen werden damit wahrscheinlich super laufen.

Ich würde mich erst mal ein bisschen herantasten und nicht gleich alle möglichen Features der Mikrocontroller betrachten. Ein grober Überblich über Peripherie-Module ist aber schon mal gut.

Mit dem USART kann man mit entsprechendem Kabel den MC mit dem Computer verbinden oder?
Ja genau.

Bei dem Nano Board ist im Programmer-Controller bereits ein FIFO für den USART integriert, so dass du neben der ISP-Programmierung sogar eine USB-UART-Bridge hast (also ein USB Kabel für ISP Programmierung UND virtuellem COM Port!). Auf Grund der Taktrate ist allerdings die Menge der Baudraten geringer als bei den spezialisierten ICs (die Baudraten von dem Controller muss ja mit der der Bridge zusammenpassen). Wenn die gewünsche Baudrate nicht unterstützt wird (siehe Datenblatt), dann kannst du immer noch direkt an den USART2 Connector eines der folgenden Module/Kabel anschließen. Vorteil wäre hier noch, dass ein Terminalprogramm den COM Port vor Programmierung nicht schließen muss (wir planen noch ein Terminalprogramm in die Bediensoftware zu integrieren, dann wird dies austomatisch bei Programmierung von der Software verwaltet):


Board von Adafruit mit FTDI USB-UART-Bridge:

Converter vom Lillypad mit FTDT USB-UART-Bridge:



Originales Kabel von FTDI mit integrierter USB-UART-Bridge:




Dirk :ciao:
 
Damit ihr up-tp-date seit, das ganze mit Compare:

Ich muss sagen, die variante ist wirklich viel eleganter und auch ein wenig besser einstellbar. Ich kann jetzt durch Clk und Wert in OCR1A die "Blinkzeit" einstellen.

Code:
#include <avr/io.h>
#include <avr/interrupt.h>


//	Globale Variablen

volatile uint8_t i = 0;								//	Zustandszähler: 0 = LED ein; 1 = LED aus

int main(void)
{

	//	Timer/Counter initialisieren

	TIMSK = (1<<OCIE1A);							//	Timer/Counter Interrupt Mask Register: OCIE1A=1 aktiviert Compare-Interrupts
	TCCR1B = (1<<CS12) | (1<<CS10) | (1<<WGM12);				//	Timer/Counter1 Control Register - Vorteiler: Systemtakt |  CTC-Mode (Mode 4)
	OCR1A = 100;									//	Mit TCNT1 zu vergleichender Wert
	

	//	Register initialisieren

	DDRB = 0xFF;
	PORTB = 0xFF;									// Zuerst alle LEDs ausschalten


	sei();											//	Globale Interrupts einschalten;	SREG I-Bit

	//	Hauptprogramm

	while(1)
	{
		if (i==0)									//	Wenn i==0, LED einschalten
		{
			PORTB = 0x00;
		}
		if (i==1)									//	Wenn i==1, LED ausschalten
		{
			PORTB = 0xFF;
		}
	}
}


//	ISR Routine für TIMER1_COMPA_vect

ISR(TIMER1_COMPA_vect)
{
	if (i==0)
	{
		i=1;
	} else
	{
		i=0;
	}
}

EDIT:

Wie soll denn die ein Dimmer mit PWM funktionieren? Werden die LEDs dann direkt am Portausgang oder mit einem Kondensator dazwischen betrieben? Dabei geht es doch darum, das durch einen bestimmten Tastgrad(duty-cycle) im Mittelwert eine bestimmte Gleichspannung bei rauskommt oder? Das gleiche hab ich mit dem jetztigen Code doch aber auch, aber da lässt sich nichts dimmen...
 
zum PWM: genau, entweder es reicht, wenn man das Flackern läßt , oder man legt wirklich einen Tiefpaß dazwischen.
Zum ICE-Bahnhof: Der Mega88 kann eher mehr. Unter Assembler ist einiges zu beachten: Da er jetzt wegen der zusätzlichen Hardware eh nicht mehr mit 64 I/O-Registern auskommt (Zugriff geht bis dahin unter Assembler mit in/out), müßten einige Register darüber angeordnet werden (Zugriff mit LDS/STS (erfordert mehr Takte). Dabei wurden die Alten Register auch etwas aufgeräumt (beim Mega8 verwenden UCSRC und UBRRH dasselbe Register als 7-bit-Register. Dabei entscheidet das MSB des zu schreibenden Bytes, ob man das UBRRH oder das UCSRC meint. Beim lesen wird erst das UBRRH gelesen, liest man im Takt direkt danach (eventuelle Interrupts ausschließen!) nochmal das Register, erscheint jetzt der Wert des UCSRC.
Ist auch gerade nicht einfach...
Aber wie schon gesagt - Du verwendest eine Hochsprache, die sich um derlei Details zu kümmern hat.
Unterschiede zwischen Mega8 und Mega88

Edit: Du mußt Dich entscheiden - entweder Blinken lassen (quasi PWM mit sichtbaren Frequenzen), oder Dimmen (PWM mit Frequenzen, wo das Blinken verwischt - wobei je nach geforderter "Glätte" gefiltert werden muß (Tiefpaß)
Noch ein Wagon an Deinem Zug: Derzeit wird im Compare-Match eine ISR ausgeführt, in der Du ein Flag umsetzt, welches Du im Hauptprogramm abfragst, und dementsprechend alle Pins von PortB setzt.
Das könntest Du genauso bereits in der ISR machen (statt dem Flag). Wenn nur ein Pin reicht, kannst Du diesen auch durch die Hardware selbständig umsetzen lassen, ohne daß dazu das Hauptprogramm überhaupt unterbrochen wird. Such mal nach Compare Output Mode im Datenblatt...
(Hier bietet der 88 zB mehr als der 8 )
 
Okay, das ging jetzt irgendwie etwas schnell :confused: Aber ich denke mein ATmega8 reicht erstmal aus ;)

Das mit der PWM-Steuerung der LEDs würde ich gerne als nächstes angehen. Hier meine Idee:

Ich benutze zur PWM erstmal den Normal-Modus. Bei diesem kann ich sowohl das CompareMatch als auch das Overflow Interrupt benutzen. Somit kann ich beim zählen mit dem Timer einen Pin immer ein und ausschalten. Durch das Variieren von OCR1A kann ich die Pulsweite modulieren.

Wie man den Pin dann verschaltet weißt ich allerdings nicht... Ich hätte einfach in Reihe einen Elko gepackt. Durch den festen Vorwiderstand ist der Strom ja proportional zur Spannung die ich mit der PWM steuere....

EDIT: Allerdings ist ein Kondensator ja ein wechselspannungsmäßiger Kurzschluss... Kann der Vorwiderstand mit dem Elko einen Tiefpass bilden?

EDIT2: Danke für den Tipp, jetzt verstehe ich, wozu der Compare Output überhaupt da ist :p Ich hab mich heute beim durcharbeiten durch das Timer1 Kaptiel an einigen Stellen echt gefragt was das bringt :eek: Aber ich hatte auch nicht verstanden, dass dadurch von der Hardware ein Signal an einen Pin gelegt werden kann :) Den Compare Output Abschnitt werde ich nochmal durchgehen
 
Schau dir mal die Funktion OutputCompare des Timer an. PWM erledigt komplett die Hardware des Mikrocontrollers.

Die Helligkeit der LEDs steuerst du über PWM, Frequenz so hoch, dass das Auge kein Flimmern wahrnimmt, den OC Pin verbindest du direkt mir er LED, auf dem board befindet sich jeweils ein Vorwiderstand.

Dirk :ciao:
 
Lies mal den Edit...
Was meinst Du mit "PWM im Normal Mode"?
Im Normal Mode läuft der Timer einfach durch. An den Überlauf kann ein Interrupt gekoppelt werden. Ebenso an Gleichheit mit den Output-Compare Registern. Außerdem kann automatisch bei jedem Compare Match der korrespondierende Pin gesetzt, gelöscht oder getoggelt werden.
Im FastPWM läuft der Timer auch durch, hier kannst Du aber den Pin stattdessen im CompareMatch setzen/löschen lassen - der Überlauf setzt das jeweils zurück. Folglich legt der Wert im OutputCompareRegister dann den DutyCycle fest.
Im Phasenkorrekten PWM läuft der Timer jetzt nicht mehr durch, sondern hin und her (rauf und runter). Je nachdem, ob TCNT oder das OCR größer ist, ist der Pin dann gesetzt oder gelöscht. Auch daraus ergibt sich ein entsprechender DutyCycle.
Im CTC begrenzt ein Vergleichsregister erstmal nur die Zählreichweite des Timers (NonPWM)
Auch das geht mit PWM - der ist dann frequenzkorrekt
Oder im DualSlope-> phasen und frequenzkorrekt.
Siehe die Tabelle mit den WaveformGenerationModes im Datenblatt...
 
Genau, im Normal-Mode würde ich dann jeweils eine der beiden ISR benutzen, um das Signal am Pin zu schalten.

Ich könnte das auch mit den anderen Modi machen, aber bei denen weiß ich noch nicht, wie ich die restlichen Bits setzen müsste um den entsprechenden Pin als Ausgang zu benutzen.
Daran kann ich mich morgen wagen.

Hier der Code zu meiner Idee:

Code:
#include <avr/io.h>
#include <avr/interrupt.h>


//	Globale Variablen

volatile uint8_t i = 0;								//	Zustandszähler: 0 = LED ein; 1 = LED aus

int main(void)
{

	//	Timer/Counter initialisieren

	TIMSK = (1<<OCIE1A) | (1<<TOIE1);						
	TCCR1B = (1<<CS11);				
	OCR1A = 20000;					
	

	//	Register initialisieren

	DDRB = 0xFF;
	PORTB = 0xFF;									// Zuerst alle LEDs ausschalten


	sei();											//	Globale Interrupts einschalten;	SREG 1-Bit

	//	Hauptprogramm

	while(1)
	{
		if (i==0)									//	Wenn i==0, LED einschalten
		{
			PORTB = 0x00;
		}
		if (i==1)									//	Wenn i==1, LED ausschalten
		{
			PORTB = 0xFF;
		}
	}
}


//	ISR Routine für TIMER1_COMPA_vect

ISR(TIMER1_COMPA_vect)
{
	i=0;
}

ISR(TIMER1_OVF_vect)
{
	i=1;
}
 
...Ich könnte das auch mit den anderen Modi machen, aber bei denen weiß ich noch nicht, wie ich die restlichen Bits setzen müsste um den entsprechenden Pin als Ausgang zu benutzen....
Ähm... über das Datenrichtungsregister vielleicht?
Datenblatt S.96 schrieb:
The COM1A1:0 and COM1B1:0 control the Output Compare Pins (OC1A and OC1B respectively) behavior. If one or both of the COM1A1:0 bits are written to one, the OC1A output overrides the normal port functionality of the I/O pin it is connected to. If one or both of the COM1B1:0 bit are written to one, the OC1B output overrides the normal port functionality of the I/O pin it is connected to. However, note that the Data Direction Register (DDR) bit corresponding to the OC1A or OC1B pin must be set in order to enable the output driver. When the OC1A or OC1B is connected to the pin, the function of the COM1x1:0 bits is dependent of the WGM13:0 bits setting. Table 36 shows the COM1x1:0 bit functionality when the WGM13:0 bits are set to a normal or a CTC mode (non-PWM
Anders gesagt:
Wie Du auf S.60 in Tabelle24 erkennen kannst, wird mit dem Aktivieren des CompareOutputModes (OC1A/B enable) im Controller das Signal PVOE (PortValueOverrideEnable) wirksam, OC1A/B beschreibt dann das jeweilige PVOV (PortValueOverrideValue). Was ist das nun? Hmm... Seite 56, Figure25:
PVOE klemmt quasi das PORT-Register-Bit, welches bisher den logischen Pegel des Beinchens bestimmt hat, vom Beinchen ab, und stattdessen das PVOV Signal (welches von der Timer-Hardware gesteuert wird) dran. Das Datenrichtungsregister bleibt vollständig unter Deiner Kontrolle/wird davon nicht beeinflußt. Man kann das Bein durch den PWM also insbesondere auch zwischen Tristate und Pullup wechseln lassen (wozu auch immer).

Alle Register, die das Verhalten des Timers(1) betreffen, sind ab Seite 95 beschrieben - ich gehe die einfach immer alle durch...
 
Guten morgen,

gestern habe ich leider nicht so viel geschafft, habe dafür aber mein 5V DC Netzteil fertiggebaut ;)

Also irgendwie find ich die PWM Modes relativ kompliziert...

Ich bin gerade dabei, die PWM, Phase Correct 8-,9-,10-bit Modes 1,2 und 3 zu verstehen.

Hier mal mein aktueller Code:

Code:
#include <avr/io.h>
#include <avr/interrupt.h>


int main(void)
{

	//	Timer/Counter initialisieren

	TIMSK = (1<<OCIE1A) | (1<<TOIE1);
	TCCR1A = (1<<WGM10) | (1<<COM1A1);
	TCCR1B = (1<<CS11);
	OCR1A = 150;									
	

	//	Register initialisieren

	DDRB = 0xFF;
	PORTB = 0xFF;									// Zuerst alle LEDs ausschalten


	sei();											//	Globale Interrupts ein

	//	Hauptprogramm

	while(1)
	{
               // ... Code ...
	}
}

Das dimmen funktioniert damit ganz gut, aber ich frage mich, warum das vorher nicht funktioniert hat. Letztendlich waren das ja auch nur Wellenformen, die ich da produziert habe....
 
Okay, den Timer/Counter1 habe ich so ziemlich durch, also verstanden, dass ist jetzt dann immer nur noch im Datenblatt nachgucken oder bei kritischen Stellen im Code nochmals nachschauen, in welcher Zeit welches TEMP Register wie geschrieben/gelesen wird, etc.

Was könnte ich mir als nächstes anschauen? Was ist sinnvoll mit meinem jetzigen Kenntnisstand?
 
hmm... die anderen beiden Timer sind ja sehr ähnlich, nur eben mit weniger Möglichkeiten - außer daß Timer2 asynchron betaktet werden kann, und der entsprechende Takteingang einen Uhrenquarz treiben kann...

Was interessiert Dich denn?
Ich würde vielleicht den ADC vorschlagen - Dein Board hat ja bereits ein Poti von Vcc nach Gnd.
Ziel: Mit dem Poti die Helligkeit der LED einstellen (erstmal mit 8bit-PWM, der ADC ist auch als 8bit verwendbar. Timer0 triggert mit seinem Überlauf-Interrupt die ADC-Conversion, Der ADC stellt mit seinem hab-fertig-Interrupt die Helligkeit um - erstmal)

Gehe mal das entsprechende Kapitel im Datenblatt durch, und überleg Dir was;)

P.S.: Dirk, wie ist das hier mit dem Aref-Pin? mit der Verschaltung des Poti empfiehlt sich ja die interne "Vcc-Referenz", die auch beim Mega8 extern mit ca 100nF zu Blocken ist. In der Anleitung zu Eurem Board finde ich da nicht wirklich was - lediglich beim Mega48/88 (sollten eigentlich Pinkompatibel sein) wird in der Tabelle auf Seite 23 erwähnt, daß Aref auf PC7 liegt. Dort ist dann der externe Abblockkerko anzuschließen?
 
Hey, danke für den Vorschlag, das klingt auf jeden Fall sehr gut :) Dann muss ich um die Helligkeit zu regeln nicht den Wert im Code ändern und das Programm neu auf den MC Flaschen ;) Ist eine doch relativ umständliche Methode und relativ unbrauchbar :eek:

Meinst du DAS Poti?

IMG_0536.jpg

Achso, hab ich das richtig verstanden?

Mit dem Timer0 stell ich die Abtastfrequenz für ADC ein, also konkret z.B. alle 50ms?


Off-Topic:

Also ich weiß ja nicht wie es euch geht, aber ich hasse diese Block-Diagramme im Datenblatt :mad: Warum benutzen die für die digitalen Bauelemente immer diese doofen amerikanischen Zeichen? Warum kann man sich nicht einfach mal an die DIN 60617-12 halten???

Zitat aus Asterix & Obelix: "Die :stupid: die Amis" :p
 
Denk ich mal - ich hab das Board nicht, kannst ja mal schauen, oder der Mittelabgriff (über einen 150R) auf der Stiftleiste landet, und die beiden anderen Pins nach Vcc/Gnd gehen...
@mein Konzept: ja, genau so. Beachte: der ADC arbeitet mit einem Takt, den er aus dem Systemtakt ableitet. Dieser sollte bei voller Auflösung zwischen 50 und 200 kHz liegen. Entsprechend dauert die Conversion also. (Aber 50ms sollten sicher reichen).
Ich weiß jetzt gerade nicht, was Du für die LED als PWM-Frequenz gewählt hattest - ggf kannst Du natürlich dann auch den Überlauf des PWM-Timers zum triggern einer (jeden) ADC-Conversion nutzen.

Wenn das läuft, schaust Du Dir mal den Free-Running-Mode an.

P.S. zum ständigen Flashen: Der Flash ist nur begrenzt oft beschreibbar. Laut letzter Version des Datenblattes (Z) sinds 10K schreib/lösch-Zyklen (Eeprom immerhin 100K.)
 
Hi LotadaC,
P.S.: Dirk, wie ist das hier mit dem Aref-Pin? mit der Verschaltung des Poti empfiehlt sich ja die interne "Vcc-Referenz", die auch beim Mega8 extern mit ca 100nF zu Blocken ist. In der Anleitung zu Eurem Board finde ich da nicht wirklich was - lediglich beim Mega48/88 (sollten eigentlich Pinkompatibel sein) wird in der Tabelle auf Seite 23 erwähnt, daß Aref auf PC7 liegt. Dort ist dann der externe Abblockkerko anzuschließen?

PC7 ist beim ATtiny48/88 dort wo der Aref Pin bei den anderen Mikrocontrollern ist, das ist hier also eine Einschränkung .

An den AREF Pins ist bei DIP40 und DIP28 ein 100nF Kondensator nach GND. Man kann also die interne Regerenzspannung oder VCC als Referenzspannung verwenden. AVCC ist gefiltert durch ein LC-Netzwerk. Bei DIP20 ist kein C nach GND, da hier, wenn ADC überhaupt vorhanden, dieser (bzw. sogar der AREF Pin) Alternativfunktion hat, hier kann man dann 100nF selber an den Portpin anschließen, normalerweise ist das ein IP-Pin.

Wenn ich Zeit habe, kann ich ja später mal ein Beispiel in C hier reinstellen, im Moment wird der ATmega8 verwendet?

Dirk :ciao:
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)