mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATTINY2313 + Uhr


Autor: Rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo erstmal,

ich versuche mit einem attiny2313 eine binäruhr zu bauen, ich benutze 
(da ein uhrenquarz ja leider nicht funktioniert) einen 4MHz quarz....


wie bekomme ich es hin, das er relativ genau nach einer sekunde eine 
bestimmte variable hochzählt... per delay wird es ungenau und schwierig, 
wenn sich der rest des programms ändert.

ich bin allerdings grade zudoof mit dem internen timer oder einem 
interupt zu arbeiten, verstehe das tutorial leider ned....

ich programmiere ihn in c...

könnte mir da jemand helfen???

Autor: KoF (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sinnvoll ist das nur mit Timern machbar, in diesem Fall einen 
16-Bit-Timer. Vorteilhaft, aber kein Muss ist ein Uhrenquarz mit 
4194304Hz (2^22).

Gruss,
Michael

Autor: Paul Baumann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In C kann ich Dir nicht helfen, aber in Bascom:

'By Paul Baumann
$regfile = "2313def.dat"                        'AT90S2313-Deklarationen
$crystal = 4000000                                          'Quarz: 4 
MHz



Dim Umlauf As Byte
Dim X As Bit




On Timer0 Ontimer0

Config Timer0 = Timer , Prescale = 64                 '4Mhz/64 = 62500 
Hz
                                         'Timer auf 6 heißt 250 Schritte
                                         'bis Überlauf
Enable Timer0                            'Timer erzeugt 250 Hz

Enable Interrupts                        'Interrupts global zulassen
Timer0 = 6
Umlauf = 250                             'Umlauf zählt die Interrupts
Config Portd.6 = Output                   'LED an Port D6
Portd.6 = 0


Do
 If Umlauf = 0 Then
    Umlauf = 250
    If X = 0 Then
      Portd.6 = 0
      X = 1
    Else
      Portd.6 = 1
      X = 0
    End If
 End If
Loop

'Interrupt-Routine

Ontimer0:

Timer0 = 6                                'Timer sofort neu laden
Decr Umlauf

Return

' **** END OF PROGRAM

Vielleicht läßt sich das Prinzip auch in C anwenden. Ich hatte Timer1 
schon
mit etwas Anderem beschäftigt, deswegen mußte ich es so machen.

MfG Paul

Autor: Rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
erstmal danke für die hilfe problem ist, das wir nur den internen takt 
zur verfügung haben, hatte ich glaube ich nicht erwähnt dann habe ich ja 
keine xta.. eingänge
 momentan sieht es so aus, was ich bis jetz aus den tutorials entnehmen 
und verstanden konnte, sind noch paar sachen drin die später dazukommen 
zb.  stellen der uhr..



[c]
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//---------------------------------------
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun  definiert"
#define F_CPU 400000UL
#endif
//----- taster prellung

#define TASTERPORT PIND
#define TASTERBIT PIND5

int8_t stunde=0;
int8_t minute=0;
int8_t sekunde=0;
int64_t timmmer=0;

ISR(TIMER0_OVF_vect)
{
    timmmer++;
}

TCCR0 = 0x03;

 /*


if (taster()== 1)
{minute++;}
 if (stunde ==25)
 {stunde=1;}
  if (minute ==60)
 {minute=0; stunde++;
 }



char taster(void)
{



  static unsigned char zustand;
  char rw = 0;

  if(zustand == 0 && !(TASTERPORT & (1<<TASTERBIT))) //Taster wird 
gedrueckt (steigende Flanke)
  {
    zustand = 1;
    rw = 1;
  }
  else if (zustand == 1 && !(TASTERPORT & (1<<TASTERBIT))) //Taster wird 
gehalten
  {
    zustand = 2;
    rw = 0;
  }
  else if (zustand == 2 && (TASTERPORT & (1<<TASTERBIT))) //Taster wird 
losgelassen (fallende Flanke)
  {
    zustand = 3;
    rw = 0;
  }
  else if (zustand == 3 && (TASTERPORT & (1<<TASTERBIT)))  //Taster 
losgelassen
  {
    zustand = 0;
    rw = 0;
  }

  return rw;
}

*/


//-------------------------------------------------
int main (void) {
sei();

  /* Setzt das Richtungsregister des Ports B auf 0xff
       (alle Pins als Ausgang): */
    DDRB = 0xff;
  DDRA = 0xff;
  DDRD = 0xff;
    /* Setzt PortB auf 0x00,  "low": */
    PORTB = 0x00;
  PORTA = 0x00;
  PORTD = 0x00;


   while(1) {

if (sekunde == 60)
{minute++; sekunde = 0;}

  if (minute ==60)
 {minute=0; stunde++;
 }
  if (stunde ==25)
 {stunde=1;}



  PORTD=stunde;
  PORTA=minute;
  PORTB=sekunde;




                  }
   return 0;
}
[c]

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rhamirez wrote:
> erstmal danke für die hilfe problem ist, das wir nur den internen takt
> zur verfügung haben, hatte ich glaube ich nicht erwähnt dann habe ich ja
> keine xta.. eingänge

Dann kannste das mit der Uhr gleich wieder vergessen. Und der ATTiny 
2313 unterstuetzt einen externen Quarz, das tun (fast) alle AVRs.

Michael

Autor: korgy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für den Anfang schon nicht schlecht....... aaaaaaber

Wozu zählst du denn "timmer" hoch ? (irgendwann sollten doch auch mal 
die Sekunden hochgezählt werden)

Was ist das für ein neues C-Schlüsselwort - "[c]" an Anfang und Ende ? 
;-)

Viel Erfolg beim Üben (nicht ironisch gemeint!)

Autor: Rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok mit einen externen quarz werd ich schon bekommen, problem war nur, er 
wollte meinen uhrenquarz nicht (das kann der attiny ned)

wie gesagt es soll relativ genau werden, muss nicht 100% wenn ich die 
uhr pro tag eine minute stellen muss ist das auch kein problem, nur habe 
es mit delay probiert und das ging ganz ganz schlecht

Autor: Rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja üben es ist ein schulprojekt, welches freitag mittag fertig sein 
soll und der einzige lehrer der uns helfen konnte ist krank =(, und das 
projekt kommt auf zeugniss.
 das [c] sollte nur für euch als hilfe sein...

timmmer sollte hochzählen bis ich die sekunde relativ genau setzen kann 
nur irgendwie blicke ich nicht durch das dieser timer wieder resettet 
werden muss oder so, da bräuchte ich ja eure hilfe... wer voin denen 
jetz bis 255 hochzählt etc

Autor: Rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sry wegen der doppelposts, das problem ist, weshalb auch der tiny 
genommen wird das es relativ stromsparend sein soll, momentan ist es 
aber wichtig, das es überhaupt läuft ich verzweifle langsam und sehe 
mein projekt... kritisch

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Rhamirez (Gast)

>ok mit einen externen quarz werd ich schon bekommen, problem war nur, er
>wollte meinen uhrenquarz nicht (das kann der attiny ned)

>wie gesagt es soll relativ genau werden, muss nicht 100% wenn ich die
>uhr pro tag eine minute stellen muss ist das auch kein problem, nur habe
>es mit delay probiert und das ging ganz ganz schlecht

Dan bleib mal ganz unruhig und lies die beiden Artikel. Steht alles 
idiotensicher drin.

AVR - Die genaue Sekunde / RTC
AVR-Tutorial: Uhr

MfG
Falk

Autor: Rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gibt es das mit der uhr auch in c?

Autor: jemand (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> das [c] sollte nur für euch als hilfe sein...

Wenn du beim zweiten einen / genutzt hättest, wär's wirklich ne Hilfe, 
weil dann das Syntaxhighlighting aktiviert würde.

>timmmer sollte hochzählen bis ich die sekunde relativ genau setzen kann

Hä? ...

Der Sourcecode sieht im übrigen auch etwas seltsam aus. Möglicherweise 
wäre es sinnvoll die Klammern entsprechend zu setzen. Derzeit ist die 
Interruptroutine nämlich nur aus timmer++; aufgebaut, der ganze Rest, 
der da wohl dazu gehören sollte, steht leer im Raum.

Ansatz: Timer nutzen, um eine LED zum Blinken zu bringen. (Siehe auch 
hier in der Codesammlung) Timer so einstellen, dass jede Sekunde blinkt. 
Dann modifizieren.

Die hier:
>int8_t stunde=0;
>int8_t minute=0;
>int8_t sekunde=0;
>int64_t timmmer=0;

müssten alle mit 'volatile' deklariert werden, sonst nützt all das 
Hochzählen nix, weil der Compiler nicht weiss, dass sie sich 
zwischenzeitlich(im Interrupt) geändert haben (könnten).


>  if (stunde ==25)
> {stunde=1;}

Soll dann da 24:30 und dergleichen angezeigt werden? ;)

Ansonsten hilft wohl auch ein gut formatierter Code etwas, dann kann man 
ihn wesentlich besser lesen und Fehler schneller erkennen.

Wenn es wirklich nur um die Nutzung des Timers geht, schau dich in der 
Codesammlung um, da gibt's wirklich genügend Beispiele. Oder aber teile 
uns dein konkretes Problem mit. Anfragen wie 'Hä? Wie verwende ich nen 
Timer?' Werden nicht wirklich gerne beantwortet...

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rhamirez wrote:
> naja üben es ist ein schulprojekt, welches freitag mittag fertig sein
> soll und der einzige lehrer der uns helfen konnte ist krank =(, und das
> projekt kommt auf zeugniss.

Da biste dann reichlich frueh dran ;-P
Das ist meine geek-Clock, kannst Dir den Code ja mal "ansehen":
http://coremelt.net/filebrowser.php?mode=coremelt&...

Ach ja, da sind mir im Nachhinein noch einige Verbesserungen 
eingefallen, ich bin aber nicht dazu gekommen bisher. Funktionieren tut 
die Uhr aber ganz gut, die Abweichung ist minimal -- hoffe das aber 
sogar noch etwas besser hinzubekommen. Nach etwa zwei 6-8 Wochen geht 
die Uhr langsam aber sicher eine Minute daneben.

Konkrete Verbesserung: Den Sekundentakt in nen 16-Bit-Timer, immo mache 
ich alles in einem 8-Bit-Timer inklusive dem Multiplexing der Anzeige, 
das wollte ich noch auslagern.

Gruss,
Michael

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Rhamirez (Gast)

>gibt es das mit der uhr auch in c?

Zitat

"ich versuche mit einem attiny2313 eine binäruhr zu bauen, ich benutze"

Als Idee sollte das doch reichen. Jetzt bis DU an der Reihe, das in C 
umzusetzen.

MfG
Falk

Autor: Rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok und entschuldigung, eine anzeige von 24.30 wird es nicht geben, es 
wird eine binäruhr..

wenn man seid 7 uhr vor dem pc sitzt und programmiert wird man etwas 
seltsam...

den interupt bekomme ich ja nicht fertig deshalb fehlt da was

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rhamirez wrote:
> wenn man seid 7 uhr vor dem pc sitzt und programmiert wird man etwas
> seltsam...

Haste auch Fortschritte vorzuweisen? ;) Wie gesacht nochma, schau Dir 
meine Uhr mal an, aber wennst gar zu sehr zulangst waere eine 
Quellen-Erwaehnung angebracht. Und tu mir nen Gefallen und denk drueber 
nach was Du tust, das sollte ja der Sinn eines solchen Projekts sein, 
nicht einfach die Arbeit anderer zu kopieren und abzugeben.

Gruss,
Michael

Autor: Rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok habe das obere verstanden mit der genauen sekunde, naja fast aber was 
bedeutet



int main( void )
{
  LED_DIR = 0xFF;
  while( KEY_INPUT & 1 );    // start with key 0 pressed

  TCCR1B = 1<<WGM12^1<<CS10;    // divide by 1
          // clear on compare
  OCR1A = XTAL / DEBOUNCE - 1;          // Output Compare Register
  TCNT1 = 0;                            // Timmer startet mit 0
  second = 0;
  prescaler = (uchar)DEBOUNCE;          //software teiler

  TIMSK = 1<<OCIE1A;     //bitte erklären               // beim 
Vergleichswertes Compare Match
                                        // Interrupt 
(SIG_OUTPUT_COMPARE1A)
  sei();

  for(;;){ //was ist das??
    if( second == 60 )
      second = 0;
    LED_DIR = second;      // display second (binary)
  }
}


könnte doch einfach second durch meine sekunde ersetzen oder???

und wozu ist das debounce?

Autor: Rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
fertiger code, aber er läuft nicht, warum???? cp-teufel???




//----------includes---------
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//---------------define-----------
#ifndef F_CPU
#define F_CPU 4000000UL
#endif

#ifndef OCR1A
#define OCR1A OCR1
#endif

#ifndef WGM12
#define WGM12 CTC1
#endif
#define XTAL    4000000L

#define DEBOUNCE  256L

#define uchar unsigned char
#define uint unsigned int


//----- variablen
uchar prescaler;
uchar volatile second;

volatile int8_t stunde=0;
volatile int8_t minute=0;
volatile int8_t sekunde=0;

//----interrupt  aus echte sekunde

SIGNAL (SIG_OUTPUT_COMPARE1A)
{

#if XTAL % DEBOUNCE                     // bei rest
  OCR1A = XTAL / DEBOUNCE - 1;    // debounce vergleich  DEBOUNCE - 1 
times
#endif
  if( --prescaler == 0 ){
    prescaler = (uchar)DEBOUNCE;
    sekunde++;  second++;      // exakte sekunde
#if XTAL % DEBOUNCE      //
    OCR1A = XTAL / DEBOUNCE + XTAL % DEBOUNCE - 1; // 
genauigkeitsvergleich
#endif
  }
}



//------------------main------------
int main (void) {
sei();

  // ausgänge setzen
    DDRB = 0xff;
  DDRA = 0xff;
  DDRD = 0xff;

    PORTB = 0x00;
  PORTA = 0x00;
  PORTD = 0x00;


   while(1) {

//aus echte sekunde

   TCCR1B = 1<<WGM12^1<<CS10;    // divide by 1
          // clear on compare
  OCR1A = XTAL / DEBOUNCE - 1;          // Output Compare Register
  TCNT1 = 0;                            // Timmer startet mit 0
  second = 0;
  prescaler = (uchar)DEBOUNCE;          //software teiler

  TIMSK = 1<<OCIE1A;                    // beim Vergleichswertes Compare 
Match
                                        // Interrupt

//eigener teil

 for(;;){

if( second == 60 )
      second = 0;


if (sekunde == 60)
{minute++; sekunde = 0;}

  if (minute ==60)
 {minute=0; stunde++;
 }
  if (stunde ==25)
 {stunde=1;}

  PORTD=stunde;
  PORTA=minute;
  PORTB=sekunde;


}

                  }
   return 0;
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast vergessen die Interrupts mit einem sei() freizugeben.

Edit: Irrtum - Du hast das sei() gleich am Anfang in main(). Hab
     ich nicht gesehen.
     Dort ist aber kein guter Platz dafür.
     sei() ist normalerweise die letzte Aktion, bevor die
     Hauptschleife betreten wird. Denn dann ist alles korrekt
     aufgesetzt und ab dann sind Interrupts auch zugelassen.
     Interrupts vorher freizugeben, schwört nur Ärger herauf


int main()
{
   ..... Alles initialisieren

   // jetzt gilts. Alles ist initialisiert, ab jetzt dürfen
   // Interrupts zuschlagen
   sei();

   while( 1 ) {
     ... Hauptschleife
   }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS: Gewöhn dir eine vernünftige Formatierung und konsistente
    Einrückung an. Auch so kann man Fehler vermeiden



   TCCR1B = 1<<WGM12^1<<CS10;    // divide by 1
          // clear on compare
  OCR1A = XTAL / DEBOUNCE - 1;          // Output Compare Register
  TCNT1 = 0;                            // Timmer startet mit 0
  second = 0;
  prescaler = (uchar)DEBOUNCE;          //software teiler

  TIMSK = 1<<OCIE1A;

Hast du kontrolliert, ob bei deinem Prozessor die Bits auch gleich
heissen bzw. ob sie auch im jeweilgen Register liegen?


  TCCR1B = 1<<WGM12^1<<CS10;    // divide by 1

Das hier soll den CTC Modus einschalten. Der Timer zählt dabei
vor sich hin und wenn der Timerwert den Wert in OCR1A erreicht,
wird ein Interrupt ausgelöst und der Timer auf 0 zurückgesetzt.

Die SChreibweise ist etwas ungewöhnlich. Normalerweise schreibt
man das so

  TCCR1B = ( 1 << WGM12 ) | ( 1 << CS10 );

macht aber in dem Fall keinen Unterschied.
Also: Kontrollier mal im Datenblatt, ob der Tiny13 die Bits
WGM12, CS10 besitzt und ob sie im Register TCCR1B liegen.
Weiters kontrollierst du im Datenblatt, ob alleiniges
Setzen von CS10 einen Vorteiler von 1 einstellt und ob
das Setzen von WGM12 den CTC Modus aktiviert. Alle anderen
Bits die du bei der Registerbeschreibung im Datenblatt finden
wirst sind als 0 anzusehen.

Dieselbe Kontrolle machst du auch hier:
 TIMSK = 1<<OCIE1A;                    // beim Vergleichswertes Compare

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne Zwischenfrage: Was ist das eigentlich fuer eine Schule?

Autor: rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke hatte gedacht, wenn es die register nicht gibt oder so bekome ich 
direkt nen fehler, weil ich ja am anfang im studio einstelle welcher 
controller es ist, klar werde es mit dem datenblatt abgleiche schauen 
viell hilft es ja.


allerdings ist es ja größtenteils aus eine echte sekunde und dieses 
tutorial bezieht sich doch auf nen attiny2313 oder??

es ist eine berufschule, schulischer bildungsgang mit fachabitur

Autor: rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kontrolliert stimmt....


muss sagen habe jetz das eine sekunde tutorial bei mir ausprobiert 
compiliert geht es auch nur im simulator bewirkt es nix

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Tutorial bezieht sich auf die AVR-Architektur.

Autor: rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
// Target: Mega8, 2313

#include <io.h>
#include <interrupt.h>
#include <signal.h>


#ifndef OCR1A
#define OCR1A OCR1  // 2313 support
#endif


sagen mir diese zeilen nicht das es auf dem mega8  und den attiny2313 
läufen müsste?

Autor: rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gibt es sonst eine andere idee, wie es hinbekommt, das die variable nach 
einer bestimmten zeit hochgezählt wird, weil ich verstehe den interrupt 
nicht, und das datenblatt hilft auch nicht weiter

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles der Reihe nach, du hast da oben Debounce Funktionen (zur 
Tastenentprellung) drin die du schonmal gar nicht brauchst.

Vorgehensweise:
* Lies dich ein wie der Timer funktioniert und wie er nach Ablauf einer 
bestimmten Zeit einen Interrupt erzeugt. 
(http://www.mikrocontroller.net/articles/AVR-GCC-Tu...)
* Wenn ein Interrupt erzeugt wird springt der uC in den Interrupt 
Handler (Interrupt Service Routine, ISR).
* In dieser ISR kannst du jetzt diverse Dinge machen.

Was du versuchen solltest:
* Schau, dass du eine LED sekündlich blinken lässt. Schließe eine LED 
(mit Vorwiderstand) an einen freien Pin an, konfiguriere diesen als 
Ausgang und in jeder ISR toggelst du diesen. Dann hast du deinen 
Sekundenrythmus.
* Wenn du das geschafft hast musst du nur noch eine Variable definieren, 
die du nun anstatt die LED zu toggeln hinaufzählst. var++;

Autor: rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich verstehe allerdings in dem tutorial nicht wie ich den interrupt für 
meinen attiny2313 einstelle


habe noch nie mit etwas derartigem gearbeitet, deshalb weißß ich nicht 
wie das mit dem overflow oder so laufen muss

Autor: dede (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
togglen würd ich mit PORTB = !PORTB hinbekommen, mit sei schalte ich 
anscheinend die interrupts an nur vertsehe nicht wie ich am einfachsten 
den interrupt bei dem controller initialisiere, weil im tutorial steht 
das man den immer zurücksetzen muss oder so und das er zählt und nach so 
und soviel takten auslöst

Autor: dede (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
//----------includes---------
#include <avr/io.h>

#include <avr/interrupt.h>

//----interrupt

  TCCR2  = 6;                     // Vorteiler 256 -> ~65ms 
Überlaufperiode
    TIMSK |= (1<<TOIE2);            // Timer Overflow Interrupt 
freischalten

//------------------main------------
int main (void) {





    DDRB = 0xff;
  DDRA = 0xff;
  DDRD = 0xff;

    PORTB = 0x00;
  PORTA = 0x00;
  PORTD = 0x00;

sei();
   while(1) {

ISR( TIMER_OVF_vect ) {
    PORTB  = !PORTB;
}






                  }
   return 0;
}





so in etwa?? bekomme aber nur fehler =(

Autor: dede (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bin der partner von der attiny2313 uhr,

was meinst du mit anbieten???

Autor: dede (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
falscher thread

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also die includes sind soweit korrekt.

Dann hast du Code der IRGENDWO steht, der sollte wohl in die main rein.

Dafür gehört die ISR aus der while Schleife und aus der main raus ... 
Die Struktur sollte dann in etwas so aussehen
#include ...

ISR( TIMER_OVF_vect ) {
    PORTB  = !PORTB;
}


int main(void) 
{
  // Hier die Initialisierungen der Register, z.B.
  TIMSK |= ...


  sei();
  while (true) { }
}



Autor: dede (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok das wurde in die maiun geschoben

 TCCR2  = 6;                     // Vorteiler 256 -> ~65ms 
Überlaufperiode
    TIMSK |= (1<<TOIE2);            // Timer Overflow Interrupt 
freischalten


allerdings kennt er die drei begriffe nicht, wie definiere ich die?

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nunja, ein bischen mit dem Datasheet musst du dich schon beschäftigen.

Dann würdest du draufkommen wie die Register wirklich heissen - das 
steht übrigens so ca. auf Seite 108 (die Seiten davor und danach sind 
auch interessant)

TIMSK sollte jedoch eigentlich passen, TOIE2 ist wahrscheinlich jedoch 
falsch.

Autor: dede (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jungs ihr seid göttlich...


habe es jetz soweit das kein error mehr kommt, allerdings sagt er mir

../test.c:7: warning: 'TIMER_OVF_vect' appears to be a misspelled signal 
handler


//----interrupt
ISR( TIMER_OVF_vect ) {
    PORTB  = !PORTB;
}


//------------------main------------
int main (void) {

    TCCR1A  = 6;                     // Vorteiler 256 -> ~65ms 
Überlaufperiode
    TIMSK |= (1<<TOIE0);            // Timer Overflow Interrupt 
freischalten



    DDRB = 0xff;
  DDRA = 0xff;
  DDRD = 0xff;

    PORTB = 0x00;
  PORTA = 0x00;
  PORTD = 0x00;

sei();
   while(1) {







                  }
   return 0;
}

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht doch gleich mal besser aus ...

Wahrscheinlich sollte das TIMER_OVF_vect ein TIMER1_OVF_vect sein.

Beachte auch dass es 2 wichtige Register für den Timer 1 gibt: TCCR1A 
und TCCR1B

Beschreibe mal in Worten welche Bits in diesen beiden Registern du 
setzen willst und vor allem: Warum.

Autor: dede (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich möchte, das er bei einem overflow im timer, einen interupt auslöst, 
möglichst so das man den timer counter so einstellt, das es nach einer 
sekunde passiert oder in einem abstand das man eine sekunde berechnen 
kann

ich sehe nur tabellen =(

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ dede (Gast)

>ich möchte, das er bei einem overflow im timer, einen interupt auslöst,
>möglichst so das man den timer counter so einstellt, das es nach einer
>sekunde passiert oder in einem abstand das man eine sekunde berechnen
>kann

Das ist schon dreimal erklärt worden.

AVR - Die genaue Sekunde / RTC

MfG
Falk

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soweit waren wir schonmal ;)

Du hast jetzt zwei Register in denen du Einstellungen vornehmen kannst, 
TCCR1A und TCCR1B.
Auf Seite 108 ist TCCR1A beschrieben.
Du musst nun der Tabelle entnehmen welche Bits du setzen willst.
Bei TCCR1A helfe ich dir:
Wir wollen (vorerst mal) eine "normal Port Operation" was den OC Pin 
anbelangt. Außerdem wollen wir "Timer / Counter Operation" auf "Normal".

Das Register auf Seite 108 hat die folgenden Bits:
COM1A1
COM1A0
COM1B1
COM1B0
--
--
WGM11
WGM10
(unten = niedrigwertestes Bit)

Wir wollen sämtliche Bits auf 0 setzen (wegen den oben definierten 
Bedingungen), die korrekte Zeile lautet also
TCCR1A = 0x00; // Hex Darstellung ist etwas lesefreundlicher

So, jetzt bist du dran.
Schau dir an welche Bits das Register TCCR1B hat und suche in den 
Tabellen nach dem Richtigen Modus

Autor: rhamirez (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
habe jetz m,ich etwas reingearbeitet, der größte problem den ich hatte 
war, das ich dachte er simuliert es in echtzeit, naja...

habe im anhang jetzt mein program habt ihr noch verbesserungsvorschläge 
oder eine idee wie ich das besser mache weil portD gibt die stunden aus 
und dort muss auch noch der schalter dran

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  rhamirez (Gast)

Und was soll das?

>if(foo>= 0xBF)
>{
>_delay_ms(150);
> foo = PORTD;

>if(foo>= 0xBF)
>stunde++;
>else minute++;
>_delay_ms(150);

>}

MfG
Falk

Autor: rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das sollte eine softwäreseitige entprellung eines schalters sein, der an 
pind6
angeschaltet wird.

habe das problem, das ich gleichzeitig an portd (0-5) die stunden 
ausgeben möchte und am verbleibenen port (pind6)  einen schalter machen 
soll, außerdem sollte es unterscheiden, ob man lange den taster drückt, 
um stunden zu stelen oder nur antippt um die minuten zu stellen, oder 
habt ihr eine bessere idee wie sich das lösen lässt?

MfG Rhamirez

Autor: rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
foo=0xbf müsste man umändern in 0x40, weil müsste doch auf 40h stehen 
wenn an pind6 ein high signal ist oder?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ rhamirez (Gast)

>das sollte eine softwäreseitige entprellung eines schalters sein, der an
>pind6
>angeschaltet wird.

Wäre es da nicht sinnvoll, das auch im Timerinterrupt zu machen?

Entprellung

Dort gibts die Creme de la creme, incl. langer und kurzer 
Tastendruckerkennung.

MfG
Falk

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum hab ich das Gefühl dass du dir das (ohne zu verstehen was es tut) 
herauskopiert hast?

Autor: rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das problem ist, das es die creme dela creme nicht verstehe, wie das 
dann ist wenn ich den port gleichzetig als ausgang nutze

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  rhamirez (Gast)

>das problem ist, das es die creme dela creme nicht verstehe, wie das
>dann ist wenn ich den port gleichzetig als ausgang nutze

AVR-Tutorial: IO-Grundlagen

MfG
Falk

Autor: rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
soweit habe ich es ja verstanden, und wenn ich DDRD auf0xbf setze dann 
sind doch die pins 0-5 ausgänge und der pin 6 eingang oder?

nun stehe ich hier und dann eine abfrage mache ob PIND6 ==1 ist oder?

würde das denn so gehen???

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rhamirez wrote:
> soweit habe ich es ja verstanden, und wenn ich DDRD auf0xbf setze dann
> sind doch die pins 0-5 ausgänge und der pin 6 eingang oder?
>
> nun stehe ich hier und dann eine abfrage mache ob PIND6 ==1 ist oder?
>
> würde das denn so gehen???

Abgesehen davon, dass du mit deiner Syntax so nicht weit kommen
würdest: ja so in etwa würde das funktionieren (wenn wir mal
das Problem der prellenden Taster ignorieren und deine Taster
höchstwahrscheinlich low-aktiv angeschlossen sind)

Die Frage ist aber: wozu?
Die Entprellroutinen sind creme de la creme. Den ISR Anteil
in deine bisherige SIGNAL Routine mit aufnehmen, so dass
der einzige Interrupt beides erledigt, die restlichen
Funktionen mit in das Projekt einkopieren und die Tastenfunktionen
benutzen. Ist fast so einfach wie einem Baby den Schnuller klauen -
wenn man weiss was man tut!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ rhamirez (Gast)

>soweit habe ich es ja verstanden, und wenn ich DDRD auf0xbf setze dann
>sind doch die pins 0-5 ausgänge und der pin 6 eingang oder?

>nun stehe ich hier und dann eine abfrage mache ob PIND6 ==1 ist oder?

>würde das denn so gehen???

Nicht ganz.

Schau dir das nochmal in C an.

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...
Bitmanipulation

MfG
Falk

Autor: rhamirez (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
verstehe ich das richtig das meine abfrage dann bit_is_set (PORTD,64)

64 weil die die wertigkeit ja abgefragt wird oder???

setzt sich das bit dann automatisch sobald am eingang ein highsignal 
ist?
aber die deklaration der ein ausgänge war richtig oder?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ rhamirez (Gast)

>verstehe ich das richtig das meine abfrage dann bit_is_set (PORTD,64)

>64 weil die die wertigkeit ja abgefragt wird oder???

Nein. Das Makro arbeitet mit der Bitnummer, nicht Wertigkeiten.

>setzt sich das bit dann automatisch sobald am eingang ein highsignal
>ist?

IN PIND schon, ja.

>aber die deklaration der ein ausgänge war richtig oder?

Aber sehr unleserlich. Viel besser lesbar als 0xBF ist ~(1<<PD6). Siehe 
Bitmanipulation.

MFG
Falk

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.