Hallo noch mal
Ich habe mir beigefügtes Projekt auf einen TTINY461 geladen
geht auch soweit bis ich die Digitalen Eingänge als Port Abfrage.
Wenn ich Pullup Wiederstände anklemme geht es aber nicht mit den
internen
Pullup.
Könnte sich einer mal das Projekt AVR Studio ansehen?
Ist nicht von mir.
Gruß
Dirk H. schrieb:> Wenn ich Pullup Wiederstände anklemme geht es aber nicht mit den> internen
hast du die Doku vom 461 gelesen?
Der hat extra Register für die PullUps.
> Wenn ich Pullup Wiederstände anklemme geht es aber> nicht mit den internen Pullup.> Könnte sich einer mal das Projekt AVR Studio ansehen?> Im projekt sind die Pullup doch aktiviert.
Da könnte man doch mal das Multimeter hervorholen und im "Projekt AVR
Studio" nachmessen, dann sähe man klarer.
Auf jeden Fall fehlen da Klammern. Es muss heissen:
DDRA &= ~((1<<E1) | (1<<E2) | (1<<E3) | (1<<E4));
Hast du eventuell vergessen, den Pin AVCC anzuschließen?
tut mir leid keine Ahnung
hab das projekt nur so übernommen
ob da klammer hinkommen weis ich nicht
ich noch kein c bin dabei zu lernen.
ich kann nur flowcode.
Die Klammern sind trotz konkretem Vorschlag immer noch nicht gesetzt.
So kommt man nicht weiter!
"Ich kann kein C" ist eine Faule Ausrede, denn zwischen den Zeilen
bedeutet es: Ich will auch kein C lernen.
Lerne es und folge den Ratschlägen. Oder lass es bleiben und übergebe
das Projekt an jemanden, der dazu bereit ist.
Ich bin nicht in der Firma
Um das zu Testen.
Darumm wäre es echt Nett wenn ihr mir sagen könntet ob
Bei beiden
PORTA |= ((1<<E1) | (1<<E2) | (1<<E3) | (1<<E4))
Und
DDRA &= ~((1<<E1) | (1<<E2) | (1<<E3) | (1<<E4));
Und bei allen anderen mehrfachzuweisungen die klammern kommen
Das wird wohl schon so sein.
Allerdings frage ich mich zweierlei:
Wie hat das jemals funktioniert, bzw. welchen Compiler hat Christian
Hottum benutzt?
Wenn weitere solcher Merkwürdigkeiten im Programm stecken, wie wollen
Sie diese ohne C-Kenntnisse finden?
Ich bin erst voe zwei Tagen mit
C angefangen in meinem alter micht mehr so einfach.
Im Tutorial steht das manchmal mit und manchmal ohne Doppelklammer.
Was soll man da lehrnen?
Hat nichts mit Faul zu tun.
Wen soll man denn sonst Fragen als hier im Forum?
Ansonsten läuft das Programm.
Und was mir auch nicht ganz klar ist:
S. Landolt schlug vor:
> ... Multimeter hervorholen und ... nachmessen
Dirk Hartmann bestätigte:
> hab noch mal alles durchgesehen ...........
Da hätte Ihnen doch ein Unterschied auffallen müssen z.B. zwischen E1
und E2.
Was ich mich frage :
List das hier auch einer von
Anfang an?
Die Schaltung geht ausser Pullup.
Also kann es nur an der Programmierung liegen.
Da brauch ich nicht messen.
Aber echt super Forum.
Anfänger werden erst mal
runtergemacht.
Und für dumm verkauft.
Dann verbessert erst mal eure Tutorial wo man ja immer nachschauen soll.
Ich habe sehr wohl von Anfang an gelesen, und als erstes fiel mir auf,
dass es mit externen Pullup-Widerständen funktioniert. Durch Nachmessen
hätten Sie den Unterschied z.B. zwischen E1 und E2 festgestellt und
hätten gezielt im Programm danach suchen können, dann wäre auch
aufgefallen, dass vor dem einen '~' steht und vor dem anderen nicht.
Das war's jetzt aber auch von meiner Seite, denn, pardon, Ihr Ton
gefällt mir ganz und gar nicht.
Ist mir aufgefallen
Und?
Noch mal ich kann kein C
Darum habe ich um Hilfe gebeten.
Ich habe die schaltung überprüft
Dann habe ich mich hier gemeldet.
Weil ein Programmfehler vorliegt
Und dann
Faul, Probier doch einfach und
So kommen wir nicht weiter
Einfacher und schneller !!!
Mach da und da Klammern weil....
Und man hat was dazugelernt.
S. Landolt schrieb:>> Wenn ich Pullup Wiederstände anklemme geht es aber>> nicht mit den internen Pullup.>> Könnte sich einer mal das Projekt AVR Studio ansehen?>> Im projekt sind die Pullup doch aktiviert.
Dies Sprüche sind es:
>> Da könnte man doch mal das Multimeter hervorholen und im "Projekt AVR> Studio" nachmessen, dann sähe man klarer.
die den TO zu der Aussage kommen lassen:
Dirk H. schrieb:> List das hier auch einer von> Anfang an?>> Die Schaltung geht ausser Pullup.>> Also kann es nur an der Programmierung liegen.>> Da brauch ich nicht messen.>> Aber echt super Forum.>> Anfänger werden erst mal> runtergemacht.> Und für dumm verkauft.
Damit hat er absolut Recht.
Soll er das Multimeter an die Zeilen im Quelltext halten, um zu messen,
ob die internen Pullups eingeschltet sind, oder wie?
S. Landolt schrieb:> Das war's jetzt aber auch von meiner Seite, denn, pardon, Ihr Ton> gefällt mir ganz und gar nicht.
Und tschüß!
Wegend er Klammern:
1<<4 = Binär: 00010000
(1<<4) | (1<<3) = Binär: 00011000
Ich hoffe, das ist soweit klar. Ansonsten musst du wirklich mal die
Grundlagen von C lernen. Eventuell mit einem besseren Tutorial
(Empfehlung:
http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/029_c_anhang_a_001.htm).
Es gibt auch umfangreichere Bücher.
Bei dem obigen Ausdruck sind die Klammern sogar optional, weil die
Schiebe-Operation vor der Oder-Verknüpfung hat. Ich schreibe die
Klammern aber immer, weil der Code so besser lesbar ist und weil ich
nicht alle Detauls im Kopf habe. Zuviel Klammern schaden nicht, sicher
ist sicher.
Achtung:
(1<<4) + (1<<3) = Binär: 00011000
Das sieht man auch häufig. Ist ebenfalls korrekt, hier darf man die
Klammern aber nicht weglassen!
Nun zur Negation:
~15 (Binär: 00001111) = 240 (Binär: 11110000)
~0 = 255
~255 = 0
Der folgende Ausdruck ist fehlerhaft:
DDRA &= ~(1<<E1) | (1<<E2) | (1<<E3) | (1<<E4);
Absicht war, alle Bits zu löschen, die auf der rechten Seite Benannt
sind.
Aber die Negation bezieht sich nur auf E1! E2 E3 und E4 werden nicht
negiert.
Ich löse den Ausdruck mal Schrittweise auf, dann siehst du, was schief
läuft:
DDRA &= ~(1<<E1) | (1<<E2) | (1<<E3) | (1<<E4);
ergibt
DDRA &= ~(1<<PINA0) | (1<<PINA1) | (1<<PINA2) | (1<<PINA3);
ergibt
DDRA &= ~(1<<0) | (1<<1) | (1<<2) | (1<<3);
ergibt
DDRA &= ~(1) | (2) | (4) | (8);
ergibt
DDRA &= 254 | 2 | 4 | 8;
Hier sollte der Fehler offensichtlich sein. Siehst du ihn?
ergibt
DDRA &= 254; (Binär: 11111110)
Also wird hier nur der Pin PA0 als Eingang konfiguriert, die anderen
bleiben unverändertt.
Mit korrekten Klammern passiert das:
DDRA &= ~((1<<E1) | (1<<E2) | (1<<E3) | (1<<E4));
ergibt
DDRA &= ~((1<<PINA0) | (1<<PINA1) | (1<<PINA2) | (1<<PINA3));
ergibt
DDRA &= ~((1<<0) | (1<<1) | (1<<2) | (1<<3));
ergibt
DDRA &= ~((1) | (2) | (4) | (8));
ergibt
DDRA &= ~(1 | 2 | 4 | 8);
ergibt
DDRA &= ~(15);
ergibt
DDRA &= 240; (Binär: 11110000)
Also werden hier die Pins PA0, PA1, PA2 und PA3 als Eingang
konfiguriert, die anderen bleiben unverändertt.
Dieser Fehler kommt in deinem Quelltext dreimal vor:
PORTA &= ~(1<<A1) | (1<<A2) | (1<<A3) | (1<<A4);
DDRB &= ~(1<<S1) | (1<<S2) | (1<<PINB6);
DDRA &= ~(1<<E1) | (1<<E2) | (1<<E3) | (1<<E4);
Hast du alle drei Stellen korrigiert? Welche Spannung misst du an den
Eingängen, wenn sie High sein sollten?
> Wie hat das jemals funktioniert...
Weil UND mit 0 wieder 0 ergibt, und PORTA, DDRA und DDRB haben als
Reset-Wert eben 0. Liegt der Fehler wohl anderswo.
Dirk H. schrieb:> Wenn ich Pullup Wiederstände anklemme geht es aber nicht mit den> internen Pullup.
Die internen Pullups sind relativ hochohmig. Vielleicht reichen diese
nicht aus und es geht nur deshalb, weil du externe (mit welchem Wert?),
viel niederohmigere angeklemmt hattest.
Wie sieht denn die Beschaltung der Eingänge aus?
Ja ich habe alle stellen
korrigiert.
Keine Veränderung.
Die Beschaltung : siehe in diesem Beitrag.
http://www.elektronik-labor.de/Projekte/TPS11.html
Eingänge schalten 0V auf die Pins
Habe extern dann 10k zugeschaltet
Dirk H. schrieb:> Bei s1 und s2 gehen die pullupsDirk H. schrieb:> Es geht um die E1 - E4
Danke für die Info! Warum kommst Du damit erst jetzt? Ich habe mir
nämlich gestern im Quellcode einen Wolf gesucht, wo denn das Problem mit
PB0 und PB2 (S1 & S2) sein soll und keins gefunden.
Jetzt hängst Du bitte mal den aktuellen Quellcode (.c und .h) mitsamt
Deiner Korrekturen hier an. Betonung liegt auf Anhängen, nicht hier
einfach in den Text kopieren.
Danke.
Und jetzt erklärst Du bitte noch, was da an E1 bis E4 dranhängt. Es kann
nämlich durchaus sein, dass die internen Pullup-Widerstände mit ~80kOhm
zu schwach sind, um den Pegel hochzuziehen.
Kannst Du auch einfach mal selber testen:
- E1-E4 offen lassen, also externes Gerät abziehen
- An E1 einen Pulldown(!) von 1MOhm anschließen
- Spannung an E1 messen.
Wenn Du annähernd 5V misst, sind die Pullups aktiv, aber offenbar nicht
klein genug, um bei Deiner externen Schaltung zu wirken. Wenn Du
annähernd 0V misst, sind die Pullups tatsächlich nicht aktiv.
Dieser Test dann auch klären, warum Du mit einem externen 10kOhm-Pullup
erfolgreich bist.
P.S.
Ich habe den Quelltext gerade nochmal geprüft. DDRA wird lediglich an 2
Stellen gesetzt. Und diese Stellen sehen nun korrekt aus. Ich sehe da
keinen Konfigurationsfehler. Bleibt eigentlich nur noch die externe
Hardware...
PORTA&=~(1<<A1)|(1<<A2)|(1<<A3)|(1<<A4);// alle Ausgänge aus
3
DDRA|=(1<<A1)|(1<<A2)|(1<<A3)|(1<<A4);// als Ausgänge setzen
4
5
.
6
.
7
.
8
9
// Eingänge
10
PORTA|=(1<<E1)|(1<<E2)|(1<<E3)|(1<<E4);// Pull up Widerstände an
11
DDRA&=~(1<<E1)|(1<<E2)|(1<<E3)|(1<<E4);// als Eingänge setzen
einfach nur mal
1
DDRA=0x0F;
2
PORTA=0xF0;
und prüfe dann mal.
Sehr seltsam finde ich auch die Einstellungen
ADMUX=39; // setze den Mux auf ADC 7
und
ADMUX=40; // setze den Mux auf ADC 8
Das wählt nicht ADC7 und ADC8 auf PORTB, sondern eine von mir noch nie
genutzte differentielle Variante auf den Ports A0 ... A2.
Meiner Ansicht nach müssten den beiden ADMUX-Einstellungen entsprechend
des Kommentars die Werte 7 bzw. 8 zugeordnet werden.
Ich vermute mal, dass die AD-Kanalzuweisungen einfach deine Ports von
der normalen Benutzung durch Pulls abhängt.
> E1-E4 = 0V
Wirklich 0V? Das kann ja nur sein, wenn die entweder
a) Die Eingänge quasi nach GND kurzgeschlossen sind
oder
b) Die Pull-Up's nicht funktionieren.
Welche Spannung misst du an den Eingängen, wenn deine zusätzlichen
externen Pull-Ups vorhanden sind, und welchen Widerstandwert haben die?
So
Die E1 und E2 sind offen und werden nur mit einer Drahtbrücke nach
0V aktiviert.
Verhalten sich wie die Taster S1 und S2
1M 0V nach E1 = 0V
allein wenn ich die Eingänge berühre schalten E1-E4
DDRA = 0x0F;
PORTA = 0xF0;
hatte ich auch probiert ohne Erfolg
Patiene habe ich überprüft keine Fehler
ADC einstellungen bin ich leider überfragt.
Dirk H. schrieb:> ADC einstellungen bin ich leider überfragt.
dann schreibe mal in den Funktionen ADC1() und ADC2() statt
ADMUX=39; // setze den Mux auf ADC 7
und
ADMUX=40; // setze den Mux auf ADC 8
neu
ADMUX = 7;
und
ADMUX = 8;
> DDRA = 0x0F;> PORTA = 0xF0;
Das ist genau falsch rum. Damit stellst du die Anschlüsse PA0 bis PA3
auf Ausgang mit Low Pegel. Probiere:
> DDRA = 0xF0;> PORTA = 0x0F;
Und du bist ganz sicher, daß AVCC richtig angeschlossen ist? Könne die
LED's leuchten?
Hallo,
formal gesehen ist die TPS_UP.h eine TPS_UP.c, da in ihr realer Code
steht und keine reinen Definitionen, Prototypen und verweise auf externe
Variable.
Als logischen Fehler sehe ich das Schreiben in TPS_UP.h von
1
// Ausgänge
2
#define A1 PINA4
3
#define A2 PINA5
4
#define A3 PINA6
5
#define A4 PINA7
Und würde eher PORTXn oder durchgängig PXn schreiben.
Wie schon geschrieben, kann man aus
1
ADMUX=39;// setze den Mux auf ADC 7
nicht direkt die gesetzten, bzw. gelöschten Register ablesen.
1
ADMUX – ADC Multiplexer Selection Register
2
REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0
3
0 0 1 0 0 1 1 1 // ADC7
4
0 0 1 0 1 0 0 0 // ADC8
Besser lesbar wird dies durch die Definition zweier ADC Bitmasken:
in ADC1() und ADC21() ist überflüssig.
Je nach Ausgangsimpendanz deiner Spannungsquelle ist ein delay von 1µs
eine mögliche Lösung für das Umschalten und Umladen des Eingangs.
In AUSF() ist eine Abfolge von sehr vielen IF ohne eine ELSE.
Ich hatte den Code als Switch-Case-Anweisung über den Parameter kom
mit inline Procedure aufrufen codiert. Das ist sehr gut lesbar,
überprüfbat und schnell änderbar.
Stilistisch sehr schön ist
1
while(!0);
Die AVR µC Taktfrequenz im Quellcode festzulegen kann eine Fehlerquelle
sein.
1
// CPU Frequenz
2
#define F_CPU 8000000UL
Das wurde schon erschöpfend diskutiert.
Besser legt man dies im zugehörigen Makefile global ab.
HildeK schrieb:> Dirk H. schrieb:>> ADC einstellungen bin ich leider überfragt.>> dann schreibe mal in den Funktionen ADC1() und ADC2() statt> ADMUX=39; // setze den Mux auf ADC 7> und> ADMUX=40; // setze den Mux auf ADC 8>> neu> ADMUX = 7;> und> ADMUX = 8;
Ist nicht richtig, da er nur 8Bit über ADCH zurückgibt.
Ich hatte vor einiger Zeit für den PIC16F876 das gleiche
Programm in Flowcode geschrieben wobei es keine Probleme gab.
Es kann ja nur etwas mit dem PORT A sein weil bei Port B gehen die
Pullups ja ordentlich.
Ich habe auch mal einen neuen 461 Ausprobiert geht auch nicht.
> Es kann ja nur etwas mit dem PORT A sein
Sieht so aus, aber
> Ich habe auch mal einen neuen 461 Ausprobiert geht auch nicht.
Mit Sicherheit können wir ausschließen, dass der ATtiny461 an Port A
keine Pull-Ups hat. Aber vielleicht ein Serienfehler? Hast du beide
Chips am selben Tag gekauft?
Was ist hiermit?:
>> DDRA = 0x0F;>> PORTA = 0xF0;>Das ist genau falsch rum. Damit stellst du die Anschlüsse PA0 bis PA3>auf Ausgang mit Low Pegel. Probiere:>> DDRA = 0xF0;>> PORTA = 0x0F;>Und du bist ganz sicher, daß AVCC richtig angeschlossen ist?>Können die LED's leuchten?
Ich kann kein C, aber beim Drüberschauen fällt mir auf, dass in allen
drei Unterprogrammen PROG, TEST und AUSF an diversen Stellen die
Pullup-Widerstände für E1..4, also PORTA0..3, deaktiviert werden, z.B.
"PORTA = dat * 16 & 0xF0" o.ä.
Vielleicht kann jemand aus der Runde mehr dazu sagen.
Das wirds sein.
Die Profis erwarten allerdings keinen Code in einem *.h-File und haben
deshalb dort nicht nach dem Fehler gesucht.
Code in einem *.h gehört sich einfach nicht.
Wenn man mit Make oder der IDE auf Kriegsfuß steht, dann meinetwegen in
ein *.inc.
Dirk H. schrieb:> Was soll ich ändern
Schreibe überall, wo PORTA modifiziert wird mit Maske 0xF0:
Alt:
PORTA = irgendwas & 0xF0;
Neu:
PORTA = (irgendwas & 0xF0) | 0x0F;
Bespiel:
Alt:
PORTA = dat * 16 & 0xF0;
Neu:
PORTA = (dat * 16 & 0xF0) | 0x0F;
Die Maske 0xF0 könnte man sogar weglassen, also:
PORTA = (dat * 16) | 0x0F;
Das ist zwar nicht besonders schön gelöst, aber dieses mit Fehlern
gespickte Programm hat es sowieso nicht anders verdient.
Hallo Dirk,
bitte veröffentliche zum Abschluss noch das geänderte Programm.
Was macht dein Standartprogramm, dass man neu in das EEprom schreiben
kann ?
1
if(kom==15)// 15: EEProm neu schreiben
2
{
3
:
4
}
Zu Timer1, wenn ich das richtig lesen, wird der Timer1 im 10Bit Modus
"Phase & Frequency Correct PWM OCR1C" betrieben.
Dabei ist das 10Bit Register OCR1C = 0x000
OCR1A und OCR1B werden nur mit 8Bit Werte beschrieben.
Ist das so gewollt ?
Hallo
Ich werde das projekt nachher
einstellen.
Das Projekt ist eine Tasten programmierbare Steuerung
Nachzulesen mit Varianten hier
http://www.elektronik-labor.de/Lernpakete/TPS/TPS0.html
Eigentlicht recht interessant
Gruss
Willst du den Quelltext im Ernst so veröffentlichen?
Mach das besser nicht - vor allem, wenn du irgendwo als Programmierer
eingestellt werden möchtest.
Der Code ist sehr hässlich und würde ein schlechtes Licht auf dich
werfen.
Zum Glück bin ich u.a. Programmierer
Aber im Bereich der SPS.
K.O. ich lass das mit dem Code der ja nicht von mir ist.
kann mann ja auch auf der Seite runterladen.
was mich noch interresieren würde wie Ihr das Programm umsetzen würdet.
Gruß