Thread der kleinen µC-Fragen

Programmierung und Hardwaredesign mit Arduino, AVR, PIC und Konsorten.

Moderatoren: MaxZ, ebastler, SeriousD

Benutzeravatar

Thread-Ersteller
nsawilla
Beiträge: 1267
Registriert: Mi 14. Sep 2005, 09:30
Spezialgebiet: Elektronik, AVRs
Schule/Uni/Arbeit: TU Graz Elektrotechnik
Wohnort: Graz
Danksagung erhalten: 1 Mal
Kontaktdaten:

Thread der kleinen µC-Fragen

Beitrag von nsawilla »

So, ich glaube so ein Thread der kleinen Fragen ist auch hier im µC-Unterforum sinnvoll oder? Wenn nicht bitte löschen, dann post ich das im "normalen" TdkF dazu..

Hier die eigentliche Frage:
Ich will einen kleinen Funktionsgenerator mit nem AVR aufbauen, fürs Erste mal einfach Sinus und einstellbare Frequenz..
Ich mach das mit DDS, also ich hab ein Array in dem die entsprechenden Werte für ne Sinuskurve eingspeichert sind, dann lese ich das Array Zelle für Zelle aus und jag das Signal in nen 4-Bit DA-Wandler (ein R2R-Netzwerk)
Wenn ich den Code (diesmal in C gehalten) aufs Minimum reduzier funktioniert das ja noch, dann bekomm ich ne Sinuskurve mit der höchsten Frequenz die der Atmega32 liefern kann..
Ich hab gedacht um ne niedrigere Frequenz zu bekommen müsste ich nur Wartezeiten einfügen, so dass ein Spannungswert ne Zeit lang gehalten wird bevor der nächste drankommt.. Aber das funktioniert nicht!

Hier der wichtigste Teil des Codes:

Code: Alles auswählen

while(1) 
{
y++;
if(y>10000)
{
PORTC=sinus[x];
x++;
if(x==60) 
{
x=0;
}
y=0;
}	
}   
sinus[x] ist einfach das Array bzw der zugehörige Wert, y ist nur zum Verzögern..
Wenn bei y>10000 oder y>10 macht keinen Unterschied, Frequenz bleibt gleich, immer Maximalfrequenz, als würde keine Verzögerung existieren .. Bei y>1000000 aber zb bekomm ich überhaupt kein Signal mehr! Die Ausgänge bleiben einfach alle auf 0V..

Liegt das irgendwie an den Optimierungsoptionen des Compilers? (Programmers Notepad, AVR-GCC, AVR-Dude)
Oder bleiben die Bits in den Ausgangsregistern nicht gesetzt wenn man Wartezeiten einfügt?
Was ist da los?

Bitte um Hilfe! Danke!
mfg
PS: genau dafür hab ich den Kerl in meiner Signatur entworfen :D

EDIT: egal, ich werde es jetzt einfach über Interrupts versuchen
Manch schwieriger Fall endet mit Blitz und Knall.. :mrgreen:

Ich hafte nicht für die inhaltliche Korrektheit meine Beiträge, sowie für Sach- oder Personenschäden.
Benutzeravatar

MalteP
Beiträge: 788
Registriert: Fr 20. Jul 2007, 12:35
Spezialgebiet: Analog, Digital und µC Technik
Wohnort: Uelzen
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Thread der kleinen µC-Fragen

Beitrag von MalteP »

nsawilla hat geschrieben:Liegt das irgendwie an den Optimierungsoptionen des Compilers? (Programmers Notepad, AVR-GCC, AVR-Dude)
könnte... welchen variablentyp hat denn y?
ah und.. gewöhn dir mal GANZ schnell an einzurücken.

hab hier noch code den ich für einen sinus wechselrichter entworfen hab. vllt hilft dir das.

main.h

Code: Alles auswählen

// *********************************************************
// * PWM Sinus Inverter - Headerfile                       *
// *********************************************************
// * Firmware Version : 1.0                                *
// * Compiler         : AVR GCC LINUX                      *
// *********************************************************
// * (c) 2009 by Malte Pöggel <malte@maltepoeggel.de>      *
// *********************************************************
// * Licensed under the beer-ware license:                 *
// *                                                       *
// * "THE BEER-WARE LICENSE"                               *
// * You can do whatever you want with this stuff. If you  *
// * meet the author some day, and you think this stuff is *
// * worth it, you can buy him a beer in return.           *
// *********************************************************

#ifndef MAIN_H
  #define MAIN_H

  #include <avr/io.h>
  #include <avr/interrupt.h>
  #include <util/delay.h>
  #include <avr/wdt.h>
  #include <avr/pgmspace.h>

  #define F_CPU 4096000UL

  prog_uchar sintab[]= { 0, 20, 40, 60, 80, 99, 118, 136, 153, 169, 183, 197, 209, 220, 230, 238, 244, 249, 253, 255, 255, 253, 249, 244, 238, 230, 220, 209, 197, 183, 169, 153, 136, 118, 99, 80, 60, 40, 20, 0 };
 
 #endif
main.c

Code: Alles auswählen

// *********************************************************
// * PWM Sinus Inverter                                    *
// *********************************************************
// * Firmware Version : 1.0                                *
// * Compiler         : AVR GCC LINUX                      *
// *********************************************************
// * (c) 2009 by Malte Pöggel <malte@maltepoeggel.de>      *
// *********************************************************
// * Licensed under the beer-ware license:                 *
// *                                                       *
// * "THE BEER-WARE LICENSE"                               *
// * You can do whatever you want with this stuff. If you  *
// * meet the author some day, and you think this stuff is *
// * worth it, you can buy him a beer in return.           *
// *********************************************************

  #include "main.h"

  volatile uint8_t zaehler;
  volatile uint8_t hwelle;

  ISR(TIMER2_OVF_vect)
   {
   
    zaehler++;
    OCR0A=pgm_read_byte(&sintab[zaehler]);
    
    if(zaehler>=40)
      {
        zaehler = 0;
        if(hwelle==0)
         {        
            PORTB |= (1<<PB0);
            PORTB &= ~(1<<PB1);
            hwelle = 1;
         } else {
            PORTB &= ~(1<<PB0);
            PORTB |= (1<<PB1);
            hwelle = 0;         
         }
      }

    TCNT2 = 254;
   }

 
  int main( void )
   {

    DDRB |= (1<<PB0);
    DDRB |= (1<<PB1);
    DDRD |= (1<<PD6);

    TCCR0A |= (1<<COM0A1) | (1<<WGM00);
    TCCR0B |= (1<<CS00);

    TCCR2B |= (1<<CS20) | (1<<CS21) | (1<<CS22);
    TIMSK2 |= (1<<TOIE2);
    TCNT2 = 254;
    OCR0A = 0;
    hwelle = 0;
    sei();

    for( ; ; ) 
     {
        // do nothing
     }
 
     return 0;
   } 
Bild
Benutzeravatar

Thread-Ersteller
nsawilla
Beiträge: 1267
Registriert: Mi 14. Sep 2005, 09:30
Spezialgebiet: Elektronik, AVRs
Schule/Uni/Arbeit: TU Graz Elektrotechnik
Wohnort: Graz
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Thread der kleinen µC-Fragen

Beitrag von nsawilla »

Y ist ein normaler Integer! X und sinus auch..
Mkay danke! Da muss ich mich mal durcharbeiten, hab bis jetzt immer in Bascom geproggt aber bei diesem Projekt ist mir C lieber weil schneller, steh aber mit C leider noch ein bisschen auf Kriegsfuß ;)

mfg
Manch schwieriger Fall endet mit Blitz und Knall.. :mrgreen:

Ich hafte nicht für die inhaltliche Korrektheit meine Beiträge, sowie für Sach- oder Personenschäden.
Benutzeravatar

MalteP
Beiträge: 788
Registriert: Fr 20. Jul 2007, 12:35
Spezialgebiet: Analog, Digital und µC Technik
Wohnort: Uelzen
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Thread der kleinen µC-Fragen

Beitrag von MalteP »

nsawilla hat geschrieben:Y ist ein normaler Integer!
was verstehst du unter normal
gibts mit und ohne vorzeichen (signed und unsigned) sowie als 8 oder 16 bit typ.
beim avr-gcc würde ich immer explizit beispielsweise uint8_t oder uint16_t schreiben. für 8 bit kannst du auch einen char verwenden.. aber ich find die uintX_t dinger lesen sich einfach schöner.
Bild
Benutzeravatar

Thread-Ersteller
nsawilla
Beiträge: 1267
Registriert: Mi 14. Sep 2005, 09:30
Spezialgebiet: Elektronik, AVRs
Schule/Uni/Arbeit: TU Graz Elektrotechnik
Wohnort: Graz
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Thread der kleinen µC-Fragen

Beitrag von nsawilla »

Ich habs einfach mit "int" definiert..
Hab das ganze jetzt über nen Timer gemacht, jetzt funzt es wie geplant!
Danke trotzdem, weitere Fragen werden wohl oder übel folgen :mrgreen:

mfg
Manch schwieriger Fall endet mit Blitz und Knall.. :mrgreen:

Ich hafte nicht für die inhaltliche Korrektheit meine Beiträge, sowie für Sach- oder Personenschäden.

Lochrasterbastler
Beiträge: 170
Registriert: Di 16. Nov 2010, 16:47
Spezialgebiet: Bits and Bytes :)

Re: Thread der kleinen µC-Fragen

Beitrag von Lochrasterbastler »

*ausgrab*

Ich habe folgendes Problem. Ich nutze Pauls Beispiel der Tastenentprellung. Also Variable wird im Timer wie im Beispiel inkrementiert / dekrementiert. Nun möchte ich, wenn der Taster gedrückt wird eine Variable erhöhen, auf einer 7-Segment-Anzeige darstellen und einen PWM-Wert setzten. Also Code für den Taster in die Hauptschleife wie in Pauls Beispiel. Soweit so gut es funktioniert auch. Nur möchte ich bei gedrückter Taste, einfach weiter inkrementieren. Mein Problem ist jetzt, dass ich zwischen dem inkrementieren eine bestimmte Zeit, für den Anfang mal 500 ms, warten möchte und dann wieder inkrementieren.

Im Prinzip funktioniert das auch, doch sobald ich den Taster länger drücke, also 3x von 0 - 10 durchlaufe, und ihn dann wieder loslasse, wird meine Variable trotzdem noch eine Zeit lang weiter inkrementiert. Ich möchte jedoch sofort aufhören mit inkrementieren sobald mein Taster losgelassen wird. Vielleicht kann mir jemand von euch helfen.

Code: Alles auswählen

// Taster Brightness
if (btn_brightness_counter >= TRESHOLD_PRESS)
{
	// Taster gedrückt
	// [DO SOMETHING]
	Brightness_level++;
	if (Brightness_level >= 10) {Brightness_level = 0;};
	set_pwm_2_value(Brightness_settings[Brightness_level]);
	show_number(Brightness_level);
			
	while (btn_brightness_counter >= TRESHOLD_PRESS)
	{
		// Taster bleibt gedrückt
		if (btn_brightness_counter >= TRESHOLD_HOLD)
		{
			// Taster gehalten
			// [DO SOMETHING]
			
			// warten bis Taster nicht mehr gedrückt
			while (btn_brightness_counter >= TRESHOLD_HOLD)
			{
				Brightness_level++;
				if (Brightness_level >= 10) {Brightness_level = 0;};
				set_pwm_2_value(Brightness_settings[Brightness_level]);
				show_number(Brightness_level);
				_delay_ms(500);
			}
		}
	}
			
	btn_brightness_counter = 0;
	_delay_ms(500);
	show_number(10);
}
Dabei habe ich kein Unterschied festgestellt ob ich _delay_ms(); verwende oder im Timer eine Variable mytimer inkrementiere und statt _delay_ms(); dann mytimer = 0; while (mytimer < 500) {;}; verwende.

Physikant
Beiträge: 503
Registriert: Di 28. Apr 2009, 00:03
Danksagung erhalten: 3 Mal

Re: Thread der kleinen µC-Fragen

Beitrag von Physikant »

Du hättest wirklich Pauls Code auch hinpacken können, dann hättest du auch schneller ne Antwort bekommen.
Das Verhalten ist völlig normal. Um genau zu sein hält es nach dem Halten grob so lange an, wie es gehalten wurde.
Das liegt daran, dass er den counter im ms-Takt inkrementiert bis zu dem dort gegebenen Maximalwert. Paul hat den (was ich schwerlich nachvollziehbar finde) auf ~65000 gesetzt. Wenn da jetzt durch langes halten ein großer Wert erreicht wurde, dauert es genausolange (minus den Schwellwert) bis der Wert wieder runtergezählt ist.
Ergo: mach den Maximalwert kleiner, sagen wir mal auf 2000, und probiers nochmal. Wenn es dann prellt (was ich mir schwer vorstellen kann), dann mach den Wert halt größer.
Ein sehr schnelles und zuverlässiges entprellen findest du übrigens auf µC.net von Peter Danegger. Der hats denke ich so schlank gemacht, wie es nur geht.

Grüße
Nikolas

Lochrasterbastler
Beiträge: 170
Registriert: Di 16. Nov 2010, 16:47
Spezialgebiet: Bits and Bytes :)

Re: Thread der kleinen µC-Fragen

Beitrag von Lochrasterbastler »

Tschuldigung, dachte jeder weiß, dass Pauls Tastenentprellung unter Werkzeugkoffer auf seiner Seite zu finden ist. Wirklich mein Fehler.

Ich habs jetzt einfach so gelöst, dass ich beim warten durch die mytimer-Variante in der Schleife schaue ob der Taster losgelassen wurde und dann den Counter zurücksetzte. So läuft der dann nicht mehr weiter.
Benutzeravatar

ferrum
Beiträge: 712
Registriert: Sa 11. Mai 2013, 15:31
Spezialgebiet: Kaffee
Wohnort: Bayern
Hat sich bedankt: 15 Mal
Danksagung erhalten: 51 Mal
Kontaktdaten:

Re: Thread der kleinen µC-Fragen

Beitrag von ferrum »

Ich weis nicht ob das in diesen thread rein passt aber ich will jetzt mit dem programmieren von ic's anfangen da ich schon c/c++ kann und jetzt damit was anderes als Programme für Computer zu schreiben machen will. Ist als Programmiergerät das hier http://sprut.de/electronic/pic/projekte ... ndex.htm#p geeignet(den ic kann ich mir von einem Freund Brennen lassen).Und welche Ic's sind für den einstieg geeignet?
KAFFEE SCHWARZ

Spitzi
Beiträge: 2349
Registriert: Mo 7. Feb 2011, 23:24
Schule/Uni/Arbeit: Student/Elektrotechnik
Wohnort: Aachen
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Thread der kleinen µC-Fragen

Beitrag von Spitzi »

Dabei handelt es sich um einen PIC Brenner. Es gibt 2 große Familien von Microprozessoren.
Zum einem PIC, zum anderem Atmel. Die Atmel AVRs sind allerdings viel weiter verbreitet, weshalb ich dir diese empfehle.
Da eignet sich zum ausprobieren im speziellen der häufig verwendete Atmega8.
Was man alles braucht ist hier im Forum auch irgendwo aufgelistet.
Bzgl Programmer: Für AVRs gibts viele verschiedene "ISP-Programmer". Ich zb. habe den USBasp, den könnte man auch nachbauen.
Jetzt hab ich aber auch noch ne Frage:
Habe leider mit dem Fusecalc ne Fuse ausgerechnet die für ein Uhrenquarz ist -.-
Startet das Ding jetzt nur wenn ich die 32kHz anlege? (32kHz sind ja noch leicht zu erzeugen :P
Wäre nämlich schon schön wenn der wieder mit mir redet, so ein Atmega 1284p kostet schon ein bisschen mehr^^
Benutzeravatar

durchgebrannt
Wiki-Crew
Beiträge: 740
Registriert: Do 28. Jul 2011, 15:03
Spezialgebiet: ARM(besonders Cortex M4), USB
Wohnort: Schwentinental
Danksagung erhalten: 2 Mal

Re: Thread der kleinen µC-Fragen

Beitrag von durchgebrannt »

Letztenendlich ist es egal, welchen Quarz du anschließt. Der AVR hat keinen Mechanismuss mit dem er nachprüfen kann, ob auch der eingestellte Quarz vorliegt. In sofern solltest du jeden beliebigen Quarz anschließen können. Beim Zurücksetzen der Fuses dann daran denken, den ISP-Takt möglichts weit runter zu stellen.
Gruß Jannis

Spitzi
Beiträge: 2349
Registriert: Mo 7. Feb 2011, 23:24
Schule/Uni/Arbeit: Student/Elektrotechnik
Wohnort: Aachen
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Thread der kleinen µC-Fragen

Beitrag von Spitzi »

Jaha, da ist ja das Problem. Ich wollte ihn vom internem RC auf den externen Stellen. Weder mit den 20MHz aus der Schaltung, noch mit den 8MHz aus dem Programmiersteckbrett klappts.
Ich versuch es heute einfach mal mit 32kHz an XTAL1.
Dieser Modus hat ja auch irgendeinen Sinn und ich denke dass der interne RC Oszillator angeschmissen wird und mit dem Uhrenquarz synchronisiert. Nur wenn da keine 32kHz sind sondern mehr anliegt passiert halt nichts.

Korni
Beiträge: 145
Registriert: Mi 14. Sep 2011, 12:29
Schule/Uni/Arbeit: Electrical Engineering and Management
Hat sich bedankt: 15 Mal
Danksagung erhalten: 7 Mal

Re: Thread der kleinen µC-Fragen

Beitrag von Korni »

Praktisch mit den kleinen Fragen, braucht man nicht für jedes kleine Problem ein neues Thema.

Nun zu meiner Frage:
Ist ein Abblockkondensator am RESET eines Atmel essentiell oder kann man den auch weg lassen. Ich sehe den bei neuen Schaltungen immer öfter, meist ist er aber nicht vorhanden. Den braucht man doch nur zum Programmieren des Controllers, also kann er im normalen betrieb weg Gelassen werden!?
Ich hab den jetzt rausgerupft, da die Platine sonst nicht ins Gehäuse passt.


Grüße
Korni

alpin
Beiträge: 350
Registriert: Di 7. Jul 2009, 17:39
Danksagung erhalten: 1 Mal

Re: Thread der kleinen µC-Fragen

Beitrag von alpin »

Der Kondensator ist im Prinzip nicht notwendig, macht aber in EMV-belasteten Umgebungen Sinn.

Der C ist nicht "nur beim Programmieren wichtig" (eigentlich sogar: nur beim Programmieren unwichtig!), sondern sorgt dafür, dass der Pegel am Reset-Pin im Betrieb konstant auf 5V bleibt. Wenn die Spannung am Reset-Pin über einen hochohmigen Pullup-Widerstand (intern oder extern) gespeist wird, kann es passieren, dass z.B. bei Schaltvorgängen im Umfeld die Spannung am Reset-Pin absackt, was dann den Controller resettet. Diese Gefahr ist deutlich kleiner, wenn ein paar zig bis hundert nF am Pin hängen. Man hört dauernd von Leuten, die Probleme mit undefiniertem Controllerverhalten haben, das kann auch an einem ungepuffertem Reset-Pin liegen.

Wenn du den Controller nicht mehr innerhalb der Schaltung programmieren willst, könntest du den Reset-Pin einfach ohne Pullup an VCC hängen. Aber Achtung, wenn du dann einen Programmer anhängst, kann das böse für den Programmer werden, da der Reset auf GND ziehen "möchte"!

Gruß

Korni
Beiträge: 145
Registriert: Mi 14. Sep 2011, 12:29
Schule/Uni/Arbeit: Electrical Engineering and Management
Hat sich bedankt: 15 Mal
Danksagung erhalten: 7 Mal

Re: Thread der kleinen µC-Fragen

Beitrag von Korni »

Danke für die Hilfe!

Ich musste ihn nur erstmal entfernen, da meine Platine sonst nicht ins Gehäuse passt. Ich werde jetzt einen anderen von unten in das Loch löten und irgendwie irgendwo an Masse löten. Das mit den EMV, naja es ist ein Art-Net Dmx Interface über Ethernet für Lichttechnik. Da können schon spannungsschwankungen auftreten und dann ist es nicht so schön, wenn das Interface resetet und das Licht aus bleibt.

Grüße
Korni
Antworten