PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tiny 2313, tipps und kontrolle gesucht



Ineedhelp
17.03.2008, 12:44
hi

ich bin ziemlich neu in der microcontroller programmierung...
habe vorher aber schon mit c++ gearbeitet

so, ich versuche einen atmel tiny 2313 zu programmieren und habe auch einen code geschrieben, der sich fehlerfrei compilieren lässt

allerdings denke ich, dass der nicht so läuft wie er soll und wollte das ein erfahrener User nochmal drüberschaut, ob die befehle stimmen und er macht was er soll, damit ich den nicht umsonst einlöte(habe es immer daneben geschrieben)

Ausserdem hoffe ich vielleicht ein paar verbesserungsvörschläge und tipps zu bekommen

Danke



#include <avr/io.h>

int main () {

DDRB = 0x00; // B Eingänge
PINB = 0x00; //jeden Eingang benutzen

DDRD = 0xFF; // D Ausgänge
PORTD = 0x11; //Standard: D0,D4 gesetzt

DDRD = 0xFF; // A Ausgänge
PORTD = 0x00;

while(1)
{

if ((!PINB1 & (1<<PINB1)) || ( !PINB2 & (1<<PINB2)) ) // Wenn B1 oder B2 == 0 dann
{
PORTD = 0x00; // Alle B Ports auf 0
}

if ( PINB4 & (1<<PINB4) ) // Wenn B1 == 1 dann
{
PORTD = 0x17; //D0,D1,D2,D4 gesetzt
}

if ( PINB3 & (1<<PINB3) ) // Wenn B1 == 1 dann
{
PORTD = 0x19; //D0,D1,D4 gesetzt
}

if ((!PINB0 & (1<<PINB0)) ) // Wenn B0 == 0 dann
{
PORTD = 0x11; //Standard: D0,D4 gesetzt
}

if((bit_is_set (PORTD,4))) //2LEDs abwechselnd blinken
//Wenn PortD4 gesetzt
{
PORTA &= ~(1 << 4); //PortD4 auf 0 setzen
PORTD |= (1 << 5); //PortD5 auf 1 setzen
}
else
{
PORTA &= ~(1 << 5); //PortD5 auf 0 setzen
PORTD |= (1 << 4); //PortD4 auf 1 setzen
}

}
return 0;
}

Ceos
17.03.2008, 12:53
#include <avr/io.h>

int main () {

DDRB = 0x00; // B Eingänge
PINB = 0x00; //jeden Eingang benutzen PIN ist ein ausgaberegister!!! nie was reinschreiben!

DDRD = 0xFF; // D Ausgänge sieht ok aus
PORTD = 0x11; //Standard: D0,D4 gesetzt das auch

DDRD = 0xFF; // A Ausgänge erm das register für port A ist DDRA
PORTD = 0x00; // dasselbe in grün nicht PORTD sondern PORTA

while(1)
{

if ((!PINB1 & (1<<PINB1)) || ( !PINB2 & (1<<PINB2)) ) // Wenn B1 oder B2 == 0 dann ...
// iwie falsch (!(PINB & (1<<PB1)) || !(PINB & (1<<PB2)))
{
PORTD = 0x00; // Alle B Ports auf 0 PORTB statt PORTD
}

if ( PINB4 & (1<<PINB4) ) // Wenn B1 == 1 dann ... siehe oben
{
PORTD = 0x17; //D0,D1,D2,D4 gesetzt
}

if ( PINB3 & (1<<PINB3) ) // Wenn B1 == 1 dann
{
PORTD = 0x19; //D0,D1,D4 gesetzt
}

if ((!PINB0 & (1<<PINB0)) ) // Wenn B0 == 0 dann
{
PORTD = 0x11; //Standard: D0,D4 gesetzt
}

if((bit_is_set (PORTD,4))) //2LEDs abwechselnd blinken
//Wenn PortD4 gesetzt
{
PORTA &= ~(1 << 4); //PortD4 auf 0 setzen PD4 statt nur 4
PORTD |= (1 << 5); //PortD5 auf 1 setzen
}
else
{
PORTA &= ~(1 << 5); //PortD5 auf 0 setzen PD5 statt nur 5
PORTD |= (1 << 4); //PortD4 auf 1 setzen
}

}
return 0;
}

Ineedhelp
17.03.2008, 13:09
erstmal großes danke für die gute hilfe
=D>

allerdings habe ich nicht alles verstanden

ich habe es mal versucht zu berichtigen...



#include <avr/io.h>

int main () {

DDRB = 0x00; // B Eingänge

DDRD = 0xFF; // D Ausgänge
PORTD = 0x11; //Standard: D0,D4 gesetzt

DDRA = 0xFF; // A Ausgänge
PORTA = 0x00;

while(1)
{

if (!(PINB & (1<<PB1)) || !(PINB & (1<<PB2))) // Wenn B1 oder B2 == 0 dann ...
{
PORTD = 0x00; // Alle D Ports auf 0
}

if ( PINB & (1<<PINB4) ) // Wenn B4 == 1 dann
{
PORTD = 0x17; //D0,D1,D2,D4 gesetzt
}

if ( PINB & (1<<PINB3) ) // Wenn B3 == 1 dann
{
PORTD = 0x19; //D0,D1,D4 gesetzt
}

if (!(PINB & (1<<PINB0)) ) // Wenn B0 == 0 dann
{
PORTD = 0x11; //Standard: D0,D4 gesetzt
}

if((bit_is_set (PORTD,4))) //2LEDs abwechselnd blinken
//Wenn PortD4 gesetzt
{
PORTD &= ~(1 << PD4); //PortD4 auf 0 setzen PD4 statt nur 4
PORTD |= (1 << PD5); //PortD5 auf 1 setzen
}
else
{
PORTD &= ~(1 << PD5); //PortD5 auf 0 setzen PD5 statt nur 5
PORTD |= (1 << PD4); //PortD4 auf 1 setzen
}

}
return 0;
}

Ceos
17.03.2008, 13:15
if ( PINB & (1<<PINB4) ) // Wenn B4 == 1 dann ... PINB4 durch PB4 ersetzen
{
PORTD = 0x17; //D0,D1,D2,D4 gesetzt
}

if ( PINB & (1<<PINB3) ) // Wenn B3 == 1 dann ... siehe oben
{
PORTD = 0x19; //D0,D1,D4 gesetzt
}

if (!(PINB & (1<<PINB0)) ) // Wenn B0 == 0 dann ...
{
PORTD = 0x11; //Standard: D0,D4 gesetzt
}



ansonsten siehts gut aus ... was verstehste denn nicht ?

die pins an sich sind mit P(Port)(Nummer) kodiert ... 1<<Pxn verschiebt eine einzelne 1 an die gewünscht position N im register X .... du musst den errrechneten wert natürlich dem PORTx zuweisen damit es wirkt bei PINx ist es genau andersherum due erzeugst die maske mit 1<<Pxn und als ergebnis bekommst du 0 wenn das bit 0 ist oder irgendwas > 0 wenn das bit gesetzt ist.

Ineedhelp
17.03.2008, 13:25
aha, genau das war die stelle an der ich mir nicht sicher war, dann habe ich das auch verstanden
so, werde meinen ic mal durchmessen und schauen, ob es funktioniert

danke nochmal für deine hilfe

Ceos
17.03.2008, 13:29
ich bin auch nur ein "erfahrener" anfänger ... aus fehlern wird man klug und gewinnt "erfahrung" ^^

Ineedhelp
17.03.2008, 22:32
so ich habe mein programm nochmal ein bisschen verändert
allerdings läuft es nicht richtig

ich möchte, dass ich erst den taster an PBO drücken muss damit die ports von 0 auf 1 gesetzt werden (start taster)

die LED an PD4 läuft allerdings sofort und fast kontinuierlich



#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>

int main () {

uint8_t start=1;

DDRB = 0x00; // B Eingänge

DDRD = 0xFF; // D Ausgänge
PORTD = 0x00; //Standard: D0,D4 gesetzt 0x11

DDRA = 0xFF; // A Ausgänge
PORTA = 0x00;

while(1)
{

if (!(PINB & (1<<PB1)) /*|| !(PINB & (1<<PB2))*/) // Wenn B1 oder B2 == 0 dann ...
{
PORTD = 0x00; // Alle D Ports auf 0
start=1;
}

if ( PINB & (1<<PB4) ) // Wenn B4 == 1 dann
{
PORTD = 0x17; //D0,D1,D2,D4 gesetzt
}

if ( PINB & (1<<PB3) ) // Wenn B3 == 1 dann
{
PORTD = 0x19; //D0,D1,D4 gesetzt
}

if (!(PINB & (1<<PB0)) ) // Wenn B0 == 0 dann
{
PORTD = 0x11; //Standard: D0,D4 gesetzt
start=0;
}

if(start==0)
{

if((bit_is_set (PORTD,4))) //2LEDs abwechselnd blinken //Wenn PortD4 gesetzt
{
PORTD &= ~(1 << PD4); //PortD4 auf 0 setzen PD4 statt nur 4
PORTD |= (1 << PD5); //PortD5 auf 1 setzen
_delay_ms(40);

}
else
{
PORTD &= ~(1 << PD5); //PortD5 auf 0 setzen PD5 statt nur 5
PORTD |= (1 << PD4);
_delay_ms(40);

}

}
}
return 0;
}


2 Frage: ich habe eine eingangsspannung von 4,5 V

müsste ich nciht an allen Ausgängen des ICs 4,5V haben? ich habe allerdings verschiedene ausgangsspannungen von 1 bis 4V...

steveLB
18.03.2008, 09:52
in
if (!(PINB & (1<<PB0)) ) // Wenn B0 == 0 dann
{
PORTD = 0x11; //Standard: D0,D4 gesetzt
start=0;
}
fragst doch ob b0 gleich null ist , muesstest du da nciht fragen ob er gleich 1 ist ? denn nur wenn du b0 drueckst sollen sich die ports aendern, also eher
if (PINB & (1<<PB0) ) // Wenn B0 == 1 dann
{
PORTD = 0x11; //Standard: D0,D4 gesetzt
start=0;

oder irr ich mich ?
gruss

BurningWave
18.03.2008, 20:31
Hallo Ineedhelp,

wenn du erst angefangen hast Microcontroller zu programmieren empfehle ich dir nicht mit so vielen Bitschiebeoperationen zu arbeiten. Da kann man sich nämlich leicht mal vertippen. Stattdessen kann man diese Operationen auch durch Makros ersetzen.
Ich habe mir mal selber, weil ich nicht gerne mit diesen umständlichen Operationen arbeite, eine Haeder-Datei mit allen Makros, die die Bitoperationen ersetzen geschrieben.

Ich habe noch zusätzlich true, false und bool definiert, weil mein AVR-GCC Compiler diese Schlüsselwörter nicht kennt.

mfg _R2D2

Ineedhelp
18.03.2008, 21:24
@_R2D2

Danke für den Tipp und die header, dass kann ich auch wohl machen...


@steveLB

ich bin mir nicht sicher, ich habe einen öffner (taster) auf B0, B1 und B2

das heißt ich habe an den Pins die ganze Zeit Spannung anliegen und erst wenn ich taste, liegt keine Spannung (0) mehr und er soll schalten und das ausführen

ich hatte nur noch 2 schließer und 3 öffner liegen, daher musste ich beides verwenden

fluchtpunkt
18.03.2008, 23:11
wenn du erst angefangen hast Microcontroller zu programmieren empfehle ich dir nicht mit so vielen Bitschiebeoperationen zu arbeiten. Da kann man sich nämlich leicht mal vertippen. Stattdessen kann man diese Operationen auch durch Makros ersetzen.
Und dann empfiehlst du deine Makros die ein erhoehtes Knieschiesspotential enthalten...

steveLB
19.03.2008, 10:34
vieleicht klappt folgendes


#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>

int main () {

uint8_t start=1;

DDRB = 0x00; // B Eingänge

DDRD = 0xFF; // D Ausgänge
PORTD = 0x00; //Standard: D0,D4 gesetzt 0x11

DDRA = 0xFF; // A Ausgänge
PORTA = 0x00;
// pb0 , pb1, pb2 oefner, also geben sie immer ne eins aus

while(1)
{

if (PORTB==0b00000101) /*|| !(PORTB==0b00000011)*/) // Wenn B1 oder B2 == 0 dann ...
{
PORTD = 0x00; // Alle D Ports auf 0
start=1;
}

if ( PORTB==0b00010111 ) // Wenn B4 == 1 dann
// die letxten 3 einser, weil die oefner immer einser liefern solang sie nicht betaetigt sind
{
PORTD = 0x17; //D0,D1,D2,D4 gesetzt
}

if ( PORTB==0b00001111 ) // Wenn B3 == 1 dann
{
PORTD = 0x19; //D0,D1,D4 gesetzt
}

if (PORTB==0b00000110 ) // Wenn B0 == 0 dann
{
PORTD = 0x11; //Standard: D0,D4 gesetzt
start=0;
}

if(start==0)
{

if((bit_is_set (PORTD,4))) //2LEDs abwechselnd blinken //Wenn PortD4 gesetzt
{
PORTD &= ~(1 << PD4); //PortD4 auf 0 setzen PD4 statt nur 4
PORTD |= (1 << PD5); //PortD5 auf 1 setzen
_delay_ms(40);

}
else
{
PORTD &= ~(1 << PD5); //PortD5 auf 0 setzen PD5 statt nur 5
PORTD |= (1 << PD4);
_delay_ms(40);

}

}
}
return 0;
}

gruss

Ineedhelp
19.03.2008, 11:34
danke für den code, werde ihn gleich mal testen
=D>


wollte eigentlich ein bild von der schaltung hochladen, klappt aber nicht

ich melde mich wieder

Hubert.G
19.03.2008, 11:47
Die Schaltung wäre nicht schlecht, ein *.png sollte es sein.
Hast du bei den Tasten entsprechende PullUp oder PullDown Widerstände eingebaut, denn wenn du den Öffner drückst geht die Spannung am Eingang nicht zwangsläufig auf 0V.

Ineedhelp
19.03.2008, 12:10
ich habe jeweils einen 470 ohm widerstand und den taster in reihe auf den pin

Hubert.G
19.03.2008, 13:05
Du musst von allen vier Eingängen noch einen PullDown Widerstand, etwa 10k, nach GND einfügen. Die offenen Eingänge haben sonst kein eindeutiges Potential.
Es wäre besser wenn du die Schaltung so ändern würdest das die Taster von den Eingängen nach GND gehen würden, dann musst du nur noch die internen PullUp aktivieren. PORTB=0xff;
Das Programm entsprechend anpassen.

Ineedhelp
19.03.2008, 17:44
danke für deine antwort

ich habe leider nicht alles verstanden

1. ich habe nur 1,2 K ohm und 22k ohm widerstände, kann ich die auch nehmen?
2. ich habe ja 2 öffner und 2 schliesser, sollen die alle den pull down bekommen?
3. wie kann ich den internen pull up aktivieren und was muss ich dabei genau machen

sry bin noch nicht erfahren

Hubert.G
19.03.2008, 17:57
Du kannst 22k verwenden.
Alle brauchen in deiner Schaltung einen PullDown.
Den internen PullUp aktivierst du inden das du anstelle des PINB = 0x00;von deinem ersten Eintrag PORTB=0xff; schreibst. Das macht aber nur Sinn wenn du die Taster nach GND schaltest.

Ceos
20.03.2008, 11:00
defnier mal bitte die o.G. "keiner Lüfter" und Relais .... der der Tiny hat nur begrenzte stromabgabe, das du dir den nur nicht grillst!!!

Ineedhelp
20.03.2008, 11:13
meine Schaltung läuft jetzt (blink LED usw...)
danke für den tipp mit dem pulldown

so ich habe jetzt ein weiteres Problem

ich schicke ja 4,6 V rein

und mein kleiner Lüfter bekommt davon 3,2V
und meine blinkenden LEDs abwechsend 2,2V

allerdings reicht das dem Lüfter nicht, ich muss den beim start anschupsen udn dann dreht er sich nur ganz langsam

wie schaffe ich das, dass er die 4,6V bekommt?

@Ceos daran habe ich auch schon gedacht
Mein Lüfter ist ein kleiner PC Lüfter (12V, 0,11A)

achja, habe bis jetzt noch kein relais dran, wollte erst das problem mit dem lüfter und der spannung regeln

momentan gehen komplett 88mA durch die Schaltung

du hast geschrieben, das der tiny begrentzt ist, kann ich auch einen anderen microcontroller nehmen um das mit der spannung und dem strom besser zu regeln?

Hubert.G
20.03.2008, 11:19
Alles was mehr als 20mA Strom benötigt muss mit einem Transistor geschalten werden, und der Gesamtstrom darf auch nicht überschritten werden, siehe Datenblatt. Vom µC 1k auf die Basis, Emitter auf GND, Lüfter an den Kollektor nach +12V. Einen NPN-Transistor, für 110mA genügt ein BC547, für etwas mehr Strom ein BC337. Über den Lüfter oder Relais eine Freilaufdiode nicht vergessen.

Ceos
20.03.2008, 11:32
der lüfter hat keine rückkopplungen, ausser wenns n gaaaanz schlechtes fabrikat ist ... nein man kann keinen anderen controller nehmen, du brauchst für jeden stärkeren verbraucher einen transistor, sonst geht dein controller hopps!
freilaufdiode für relais bitte immer mit dem hinweis eine shottky-diode zu verwenden da die schneller sind, den transistor unbedingt einen widerstand zur basis vorsetzen sonst grillst du ihn UND deinen controller ... hab cih noch was vergessen ? bitte korrigieren/ergänzen ^^

Ineedhelp
20.03.2008, 12:42
danke für die antworten

mein wissenzuwachs durch das forum ist echt enorm =D>

also, ich brauche für das relais und für den Lüfter jeweils einen Transistor

dann brauche ich eine Freilaufdiode, damit die selbstinduktion meinen µC nicht angreift

+ widerstand vor die basis des transistors

frage 1: kann ich auch zwei BC 177A Transistoren verwenden?
die habe ich da (was ist überhaupt der unterschied zwischen den ganzen dingern)

frage 2: wenn ich die schaltung wie oben verbessert habe, habe ich dann eine größere spannung an meinem lüfter bzw läuft er dann ein bisschen schneller?

im datenblatt des tinys habe ich max 6mA gefunden, aber das steht das so ganz komisch zwischen ist glaube ich falsch

kann ja auch nciht, baller ja durch meinen schon 88mA

Ceos
20.03.2008, 13:24
zu 1. meist ist es nur der spannungsbereich, steuerverhalten/strom/spannung, PNP/NPN, max-last, verlust, verstärkung ... details überlass ich den anderen

wenn du einen transistor benutzt solltest du eine spannung von 4.5V haben wenn das deine versorgungsspannung ist und die sollte zum drehen ausreichen

Ineedhelp
20.03.2008, 13:34
beispiel Lüfter

Huber meinte: "Vom µC 1k auf die Basis, Emitter auf GND, Lüfter an den Kollektor nach +12V"

Basis an den µC

Emitter auf GND

Aber dann muss doch der Minus Pol vom Lüfter auf den Kollektor, damit die Elektronen zu GND können und der Pluspol vom Lüfter direkt an die 4,6V Spannung

oder nicht?

Dann kommt es nämlich nur zu einem Stromkreis, wenn µC Spannung auf die Basis schickt und dann habe ich auch 4,6 V

achja und wie groß muss der Widerstand vor der basis sein, 470ohm?

Hubert.G
20.03.2008, 14:03
Der BC177A ist ein PNP Transistor, der geht nur bedingt, da musst du alles umdrehen.
Also Emitter an +4,6V, Kollektor an + Lüfter, -Lüfter an GND, Widerstand vor der Basis 1k. Das funktioniert aber nur wenn die Spannung für den Lüfter die gleich ist mit der vom µC.
Das mit dem Lüfter ist richtig.
Der Widerstand vor der Basis ist 1k also 1000 Ohm.
Ob der Lüfter mit den 4,6V läuft, wirst du ja sehen.

Ceos
20.03.2008, 14:11
470 ohm sind bissl wenig aber ausreichend obwohl 4.5V denke das reicht ... ist das n NPN oder n PNP den du da hast ?
mh ... mir wird grad klar das ich vergessen habe wie PNP und NPN noch gleich funktionieren XD

EDIT hubert war schneller

Ineedhelp
20.03.2008, 16:51
so habe den lüfter jetzt mit der transistorschaltung aufgebaut

er bekommt jetzt 4,6V und läuft richtig gut

allerdings läuft er nur wenn der entsprechende port zur ansteuerung 0 und somit die basis 0 ist.

wenn ich anschalte und die basis spannung bekommt geht der lüfter aus


Ist das ein Transistor (BC 177A) der bei Spannung an der Basis sperrt?
anders kann ich mir das nicht erklären

Ceos
20.03.2008, 16:53
also wenn der port 0 ist liegt er auf GND! wenn er auf logisch 1 ist liegt er auf VCC über den internen pullup widerstand!

das prroblem ist ich weis echt nicht mehr wie transistoren pnp und npn unterscheiden, vermutlich erwartet der transistor negative spannung (in deinem fall GND)


ah habs gefunden, klar pnp erwartet steuerspannung über Basis und Emitter PNP bedeutet Emitter bekommt + basis und collector bekommen - also wenn der pin auf logisch 0 ist liegt er auf minus

Hubert.G
20.03.2008, 18:49
Genau das ist der Unterschied, bei einem NPN-Transistor läuft der Lüfter bei logisch 1, bei einem PNP-Transistor bei logisch 0.
Damit ein Transistor leitet, braucht er immer die Spannung die am Kollektor anliegt.

Ineedhelp
20.03.2008, 19:15
ok, habe ich auch mit gerechnet

ich lasse das jetzt so, bis ich andere transistoren habe, ist nicht so wichtig, wann es schaltet, hauptsache volle spannung

danke nochmal an alle die mir geholfen haben

ist ein super forum =D>

Ceos
20.03.2008, 20:08
@hubert laut dem bild was ich hier habe läuft die basisspannung aber übern emitter O_o ?

Hubert.G
20.03.2008, 21:24
Also genau genommen fließt der Basisstrom zum Emitter, damit dieser Strom fließen kann muss sein Potential an der Basis um 0,7V, bei Standardtransistoren, höher sein als am Emitter und zwar höher in Richtung Kollektorpotential.

Ceos
20.03.2008, 21:32
achsooo ja danke das erklärt einiges!