Forum: Mikrocontroller und Digitale Elektronik ATINY 13 Interrupt will nicht


von Peter (Gast)


Lesenswert?

Hallo liebe Community, wie der Betreff schon sagt bin ich am verzweifeln 
bei der Aktivierung des Interrupts an einem TINY13A

Die Anwendung ist recht simpel:
Das Hauptprogramm lässt eine LED mit der Frequenz freq blinken
Wird nun ein Interrupt ausgelöst so wird die Variable freq verändert was 
eine Frequenzänderung des Blinkens nach sich ziehen sollte.

Meine Frage ist es ob ich das Code mäßig richtig gemacht habe?
(Die LED an PortB3 soll lediglich eine Status Led sein ob der Tiny in 
die Interrupt routine kommt)
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
5
#define F_CPU 8000000UL     /* Quarz mit 8 Mhz  */
6
7
volatile uint8_t freq;
8
volatile uint8_t langsamer;
9
volatile uint8_t stat;
10
11
void main (void)
12
{
13
  DDRB = (1 << DDB0) | (0 << DDB1) | (1 << DDB3);
14
  PINB = (1 << DDB1);
15
  
16
  sei();
17
  SREG = (1 << 7);
18
  GIMSK = (1 << INT0);
19
  MCUCR = (0 << ISC00) | (1 << ISC01);
20
  
21
  freq = 100;
22
  langsamer = 1;
23
  stat = 0;
24
  
25
  while(1)
26
  {
27
  
28
    PINB = (1 << PINB0);
29
    sleep (freq);
30
    PINB = (0 << PINB0);
31
    
32
    PINB = (stat << PINB3);
33
  
34
  }
35
}
36
37
void sleep ( uint8_t ms )
38
{
39
    for(; ms > 0; ms--) _delay_ms(1);
40
}
41
42
ISR (INT0_vect)
43
{
44
  if (langsamer == 1)
45
  {
46
    freq = freq - 10;
47
    
48
    if (freq < 10)
49
    {
50
      langsamer = 0;
51
      freq = 10;
52
    }
53
  }
54
  else 
55
  {
56
    freq = freq + 10;
57
    
58
    if (freq > 100)
59
    {
60
      langsamer = 1;
61
      freq = 100;
62
    }
63
  }
64
  
65
  if (stat == 1)
66
  {
67
    stat = 0;
68
  }
69
  else 
70
  {
71
    stat = 1;
72
  }
73
}

von holger (Gast)


Lesenswert?

PINB = (stat << PINB3);

Also ich würde ja PORTB nehmen.
PINB ist das Eingangsregister.

von spess53 (Gast)


Lesenswert?

Hi

>  SREG = (1 << 7);

Rate mal. was sei() macht?


>    PINB = (1 << PINB0);
>    sleep (freq);
>    PINB = (0 << PINB0);

>    PINB = (stat << PINB3);

Das Register zur Ausgabe ist PortB .

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

> an einem TINY13A

Hab extra nochmal nachgesehen. Der Tiny13A ist einer von denen, die mit 
einer Zuweisung ans Pin Register den Port toggeln können.

von Peter (Gast)


Lesenswert?

Ok wo ist denn der Unterschied zwischen
Pin und Port??

mit DDRx wird eingestellt ob es eingang oder ausgang ist
und mit pin als auch mit port kann man jetzt entweder eine spannung 
ausgeben oder den pull up einschalten?

Aber das ändert ja immer noch nichts an dem Problem, dass der Interrupt 
nicht funktionieren will.

@KarlHeinz wie erkennt man das es so einer ist
@spess53 stimmt du hast recht :D

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:
> Ok wo ist denn der Unterschied zwischen
> Pin und Port??
>
> mit DDRx wird eingestellt ob es eingang oder ausgang ist
> und mit pin als auch mit port kann man jetzt entweder eine spannung
> ausgeben oder den pull up einschalten?

aha.
und wozu braucht man dann das PINx Register, wenn es egal ist ob PINx 
oder PORTx.

Ich bin mir noch nicht sicher, ob es da jetzt nicht schon an 'früheren' 
Dingen hapert als am Interrupt. Wenn ich das
1
PINB = (0 << PINB0);
im Code sehe, dann denke ich eigentlich 'ja'. Und auch die anderr 
zitierte Aussage überzeugt mich noch nicht wirklich.

Auch müsstest du eine Warnung bzgl. sleep() bekommen haben.

> @KarlHeinz wie erkennt man das es so einer ist
Das steht im Datenblatt.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Was hängt eigentlich am Pin PB1, dem Int0 Eingang?

von Peter (Gast)


Lesenswert?

Okok also wenn ich das richtig verstanden hab wird Pinx verwendet wenn 
man wissen will ob ein Ausgang High oder Low ist oder ob ein Eingang den 
pull up aktiviert hat.
Und PortX verwendet man wenn man den Zustand des Ausgangs / eingangs 
ändern will.

Ja das war mir auch klar dass es im Datenblatt stehen sollte. Aber unter 
welchem Punkt immerhin hat das Datenblatt ein paar Seiten.…

An dem Interruptionen hängt ein Taster nach Ground geschlossen.

Habt ihr irgend welche Tipps für Lektüre oder wie kann man mehr über das 
Thema lernen, weil anscheinend helfen die Tutorial im Internet nicht so 
sehr weil die meisten schon auf einigem Wissen aufbauen.

Mfg Peter

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Peter schrieb:
> Habt ihr irgend welche Tipps für Lektüre oder wie kann man mehr über das
> Thema lernen, weil anscheinend helfen die Tutorial im Internet nicht so
> sehr weil die meisten schon auf einigem Wissen aufbauen.

Das AVR Tutorial hier hast du dir schon angesehen? Das fängt fast bei 
Pontius und Pilatus an und sollte die meisten Fragen klären.
http://www.mikrocontroller.net/articles/AVR-Tutorial
Peter schrieb:
1
 PINB = (1 << PINB0);
2
// irgendwelcher Code
3
 PINB = (0 << PINB0);
Du musst dir darüber klarwerden, das du damit den gesamten Port (oder 
in dem Fall das gesamte PIN Register) beschreibst. Du handelst dir damit 
Seiteneffekte auf andere Pins ein, die du sicher nicht möchtest.
Wenn du ausschliesslich PB0 high setzen willst ist
1
PORTB |= (1<<PINB0);  // verODERn mit PB0
der Weg dazu. Wenn du ihn low machen willst, schreibst du
1
PORTB &= ~(1<<PINB0);  // UNDieren mit der Komplementärmaske von PB0
Das nennt sich Bitoperation und wird im AVR Tutorial alles erklärt.

von Peter (Gast)


Lesenswert?

Ne das Tutorial hatte ich noch nicht gelesen danke!
Und das mit den Bitoperationen ist auch sehr hilfreich danke!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.