Forum: Mikrocontroller und Digitale Elektronik PCINT > Attiny24a > Bascom


von frager (Gast)


Lesenswert?

Ich muss mit dem Attiny24a 2 unabhängige Interrupte verwenden.
Da dieser nur einen int0 hat aber 12 PCint's muss ich mich damit 
vergnügen.

Da ich irgendwie wenig im internet finde das mir hilft, habe ich nun 
folgenden schnipsel:

Enable Pcint0
Enable Pcint1
Pcmsk0 = &B00000001
Pcmsk1 = &B00000001
On Pcint0 Golauter
On Pcint1 Goleiser

So wie ich verstehe habe ich zwar 12 PCint pins, aber kann damit nur 2 
Interrupte aktivieren.
Pcint0 der von PORTA.0 bis .7 geht
Pcint1 der von PORTB.0 bis .3 geht

Ich brauche pro Interrupt nur jeweils 1 pin. Also PINA.0 und PINB.0.
Das nachträgliche kontrollieren der PINs wäre zu viel aufwand. Da ich 
bei jeder Flankenänderung eine aktion will.
Brauche ich noch "Enable Interrupts" ?

Danke

von Peter D. (peda)


Lesenswert?

frager schrieb:
> Das nachträgliche kontrollieren der PINs wäre zu viel aufwand.

Warum?
Was ist an einem EXOR so schlimm?

Du kannst aber auch den ICP1 als externen Interrupt benutzen.
Oder den Analog-Komparator mit 1,1V als Schwelle.

von Jerri (Gast)


Lesenswert?

frager schrieb:
> Brauche ich noch "Enable Interrupts" ?

Ja!

von frager (Gast)


Lesenswert?

Aber sonst passt alles?

von Jerri (Gast)


Lesenswert?

frager schrieb:
> Aber sonst passt alles?

Was soll das denn jetzt? Das Programm ist schon mal unvollständig!

Probier es aus und wenn es nicht geht, poste 'ne Fehlerbeschreibung. Bis 
dahin verschwende zumindest ich keine weitere Minute daran, was "alles" 
in dem Projekt nicht passen könnte.

von Oldie (Gast)


Lesenswert?

Da du nur jeweils einen PinChange-Eingang von PCI0 und PCI1
nimmst und freigegeben hast, ist die Sache doch schon fast
eindeutig.

"Enable Interrupts" muss sein, sonst tut sich nix.

Mich würde aber stören, dass EIN Tastendruck schon mindestens (!)
zweimal den jeweiligen Interrupt auslöst: Taste gedrückt UND
Taste losgelassen ändert jeweils den Pegel. (Pin CHANGE!)
Das unvermeidliche Prellen von Tasten kann den Interrupt auch
20 mal auslösen...

Das nachträgliche Kontrollieren der PINs wäre dir zu viel
Aufwand? - Dann lass es sein:
Das Entprellen der Tasten erfordert mehr Aufwand, als nur das
simple Erkennen des auslösenden Pins. ;-)

von frager (Gast)


Lesenswert?

1
$regfile = "attiny24.dat"
2
$crystal = 8000000
3
$hwstack = 40
4
$swstack = 16
5
$framesize = 32
6
7
   $sim
8
9
Config Porta.1 = Output                                     'leiser
10
Config Porta.2 = Output                                     'lauter
11
Config Porta.3 = Output                                     'I/O
12
Config Porta.4 = Output                                     'naechste
13
Config Porta.5 = Output                                     'vorherige
14
Config Porta.6 = Output                                     'mute
15
Config Pina.0 = Input                                       'Drehgeber A in
16
Config Pinb.0 = Input                                       'Drehgeber B in
17
Config Portb.1 = Output                                     'Drehgeber A out
18
Config Portb.2 = Output                                     'Drehgeber B out
19
20
21
Enable Pcint0                                               'PCint0-7
22
Enable Pcint1                                               'PCint8-11
23
Pcmsk0 = &B00000001                                         'PCint0
24
Pcmsk1 = &B00000001                                         'PCint8
25
On Pcint0 Golauter
26
On Pcint1 Goleiser
27
28
29
30
Dreha Alias Portb.1
31
Drehb Alias Portb.2
32
33
34
Enable Interrupts
35
36
Do
37
...
38
Loop
39
40
End
41
42
43
Golauter:
44
Disable Interrupts
45
Toggle Dreha
46
Waitms 10
47
Toggle Drehb
48
Enable Interrupts
49
Return
50
51
Goleiser:
52
Disable Interrupts
53
Toggle Drehb
54
Waitms 10
55
Toggle Dreha
56
Enable Interrupts
57
Return

Folgenden Code habe ich. (Hauptprogramm mal rausgenommen)

Laufen tut der Tiny mit 3.3V @8mhz. Funktioniert aber nicht.
Es geht hier um einen Drehimpulsgeber. Dieser ist an dem Tiny 
angeschlossen. Wird daran gedreht, wird ein interrupt ausgelöst und gibt 
praktisch diesen weiter. Sollte er zumindest.

Wenn ich einen Taster an Pina.0 anschließe (mit Pullup widerstand) 
passiert auch nichts. Ich denke es liegt an den Interrupt?

von spess53 (Gast)


Lesenswert?

Hi

>Es geht hier um einen Drehimpulsgeber. Dieser ist an dem Tiny
>angeschlossen. Wird daran gedreht, wird ein interrupt ausgelöst und gibt
>praktisch diesen weiter. Sollte er zumindest.

Vergiss Intrups.

http://www.mikrocontroller.net/articles/Drehgeber

MfG Spess

von Oldie (Gast)


Lesenswert?

Tut mir leid, von Bascom hab ich NULL Ahnung.

Versuch es erstmal mit einem Minimalprogramm, wo du
nur die Reaktion auf Tasten (nach Masse) an PinA-0 und PinB-0
(mit PullUp) auf irgendwelchen anderen Ausgängen sichtbar machst.

von frager (Gast)


Lesenswert?

Danke für den Tipp, aber ich habe mich in C noch nicht so reingelesen. 
Deswegen, und auch weil ich bisher eigentlich alles mit Bascom 
realisieren konnte, würde ich gerne mit Bascom weiter machen.

Ich versuche das erst mit dem Interrupt. Vorallem denke ich nicht das 
der Controller damit überlastet wird :D.

Wenn ich im simulator den Interrupt aktiviere, funktioniert alles 
perfekt. Ändere ich allerdings den PINA.0 oder PINB.0 dann passiert 
nichts.

von Bastler6 (Gast)


Lesenswert?


von frager (Gast)


Lesenswert?

Oldie schrieb:
> Versuch es erstmal mit einem Minimalprogramm, wo du
> nur die Reaktion auf Tasten (nach Masse) an PinA-0 und PinB-0
> (mit PullUp) auf irgendwelchen anderen Ausgängen sichtbar machst.

Wenn du meinst in Real, das habe ich versucht.

Im Simulator habe ich:
1
$regfile = "attiny24.dat"
2
$crystal = 8000000
3
$hwstack = 40
4
$swstack = 16
5
$framesize = 32
6
7
$sim
8
9
Config Pina.0 = Input
10
Config Pinb.0 = Input
11
Config Portb.1 = Output
12
Config Portb.2 = Output
13
14
Porta.0 = 1
15
Portb.0 = 1
16
17
Enable Pcint0                                               'PCint0-7
18
Enable Pcint1                                               'PCint8-11
19
Pcmsk0 = &B00000001                                         'PCint0
20
Pcmsk1 = &B00000001                                         'PCint8
21
On Pcint0 Golauter
22
On Pcint1 Goleiser
23
24
Enable Interrupts
25
26
Do
27
nop
28
Loop
29
30
Golauter:
31
32
Toggle Portb.1
33
34
35
Return
36
37
Goleiser:
38
Toggle Portb.2
39
40
Return

versucht, funktioniert aber auch nicht.
Ich weiß nicht was ich falsch mache.
Löse ich im simulator den Interrupt so aus, funktioniert alles so wies 
gehört, nur wenn ich eben den pin ändere, funktioniert nichts. Genau so 
auch wenn ichs mit dem richtigen Attiny24 mache.

Bastler6 schrieb:
> Lese dir das mal durch:
>
> http://www.roboternetz.de/community/threads/11849-PCINT-beim-Mega88

Habe mal zum testen den kompletten code aus post 2 kopiert. Im Simulator 
funktioniert dieser auch nicht.

von Norbert S. (norberts)


Lesenswert?

Hi,

ich fürchte den Simulator kannst Du hier vergessen. Ich habe erst 
kürzlich was mit den PinChange Interrupts in Bascom gemacht und bin mir 
sicher, daß das so gehen müsste.
Ist leider nicht so selten, daß im Simulator nicht alles funktioniert, 
vor allem etwas neuere Dinge (wobei "Neu" heisst, war in den allerersten 
AVR vor Tiny und Mega nicht drin, wie z.B. Timer2).
Im Simulator kann man mal banale Dinge ausprobieren, Laufzeiten simpler 
Programmschnipsel testen usw...

Da es in der realen Schaltung auch nicht geht, hast Du da ev. ein 
Hardware-Problem. Schaltet der Drehgeber z.B. nach Plus? Dann passiert 
da natürlich nichts. Ändert sich der Pegel am Pin wirklich? Oszi?

Gruß,
Norbert

von frager (Gast)


Lesenswert?

Norbert S. schrieb:
> Ich habe erst
> kürzlich was mit den PinChange Interrupts in Bascom gemacht und bin mir
> sicher, daß das so gehen müsste.

Oke, also so wie ich das hab müsste das funktionieren? GIMSK z.B. brauch 
ich nicht?
Ich werde dann mal das programm brennen, und dann testen. Per Taster.

Norbert S. schrieb:
> Da es in der realen Schaltung auch nicht geht, hast Du da ev. ein
> Hardware-Problem. Schaltet der Drehgeber z.B. nach Plus? Dann passiert
> da natürlich nichts. Ändert sich der Pegel am Pin wirklich? Oszi?

Ändern tut der sich wirklich. Habe es ja auch versucht mit einem taster.

von Norbert S. (norberts)


Lesenswert?

Hi,

GIMSK macht Bascom mit dem "Enable Pcint0".
Das kannst Du auch im Simulator sehen, das Bit wird gesetzt. Wenn das da 
funktioniert, geht das real sicher. Umgekehrt ist es nicht sicher.

Wie hast Du das mit nem Taster probiert? Schaltplan?

Generell:
Vergiss die Config Pin usw, mach das mit den Registern.
Also DdrX.n = 1 -> Output.
Als Eingang brauchst Du nichts zu machen, den Pullup schaltest Du dann 
mit PortX.n ein.
PinX.n ist immer der tatsächliche Pegel.
"Config PinX.n = Input" macht exakt nichts oder schreibt da 
schlimmstenfalls ne 0 in DdrX.n.
Auch für andere Dinge nutze die "höheren" Funktionen von Bascom nur, 
wenn Du Dir sicher bist, was da abgeht.
Bascom macht es dem User teilweise sehr einfach aber verdaddelt dabei 
auch Zeit.
Für eine Aquariensteuerung mag das egal sein aber bei zeitkritischen 
Dingen kann man das auch in Bascom alles sehr performant per Ints und 
direkt über die Register machen.

Gruß,
Norbert

von frager (Gast)


Lesenswert?

Vielen dank.

Habe eben den Attiny nochmal getestet. Nun funktioniert er. Denke also 
es lag an der Versorgungsspannung im Radio.

Ich verwende aber schon immer "Config PINx.n = Input" das funktionierte 
eigentlich immer.

Muss aber noch den Pullup aktivieren. Hatte das vergessen.

von Norbert S. (norberts)


Lesenswert?

Hi,

"Config PINx.n = Input" ist das Gleiche wie "DdrX.n = 0" und diese 
Register sind nach dem Start alle NULL!
Alles was nicht explizit als Output ("DdrX.n = 1) definiert ist, ist 
immer input.
Das kannst Du Dir also schenken.

Aber selbst meine C-Kollegen schreiben da ne Null rein, ich habs 
aufgegeben...

Ausnahme ist natürlich, wenn das im Programm geändert werden soll.
Am Start macht das aber überhaupt keinen Sinn.

Gruß,
Norbert

von frager (Gast)


Lesenswert?

Achso, ja klingt einleuchtend :D. Danke

Nun ist das so. Ich habe auf der Platine am Radio ja eigentlich einen 
drehgeber. Also folgende Pins: A - GND - B
Beim drehen geht entweder zuerst A oder zuerst B auf low, bzw "liegt in 
der luft".

Mein problem ist nun, das ich das ja per Attiny machen möchte.
Löte ich mir jetzt ein Kabel an A und an B und halte diese abwechselnd 
an A danach an B, tut sich was. Also es können auch sekunden dazwischen 
liegen.

Schließe ich aber nun A und B an den Tiny an, passiert nichts. Egal ob 
ich PORTB also Ausgang setze und dann entweder high oder low anlege, 
oder ob ich ihn als ausgang setzte, also low, und um "in der luft" zu 
liegen als input setze.

Variante A:
Toggle PORTB.1
waitms 10
Toggle PORTB.2

Variante B:
Toggle DDRB.1
waitms
Toggle DDRB.2

Wie realisiere ich das?
Messe ich an GND und z.B. PIN B vom Drehimpulsgeber auf der Platine, 
habe ich 5 Volt. Heißt das jetzt ich hab sicher 5 Volt, oder messe ich 
damit den Pullup nicht mit?

von frager (Gast)


Lesenswert?

So folgenden Code habe ich nun:
1
,8$regfile = "attiny24.dat"
2
$crystal = 8000000
3
$hwstack = 40
4
$swstack = 16
5
$framesize = 32
6
7
8
   $sim
9
10
Config Porta.1 = Output                                     'leiser
11
Config Porta.2 = Output                                     'lauter
12
Config Porta.3 = Output                                     'I/O
13
Config Porta.4 = Output                                     'naechste
14
Config Porta.5 = Output                                     'vorherige
15
Config Porta.6 = Output                                     'mute
16
Config Pina.0 = Input                                       'Drehgeber A in
17
Config Pinb.0 = Input                                       'Drehgeber B in
18
Config Portb.1 = Output                                     'Drehgeber A out
19
Config Portb.2 = Output                                     'Drehgeber B out
20
21
Porta.0 = 1                                                 'pullup
22
Portb.0 = 1                                                 'pullup
23
24
25
Config Adc = Single , Prescaler = Auto , Reference = Internal       'adc einstellungen
26
Start Adc                                                   'adc starten
27
28
Enable Pcint0                                               'PCint0-7
29
Enable Pcint1                                               'PCint8-11
30
Pcmsk0 = &B00000001                                         'PCint0
31
Pcmsk1 = &B00000001                                         'PCint8
32
On Pcint0 Golauter
33
On Pcint1 Goleiser
34
35
36
37
Enable Interrupts
38
39
40
do
41
...
42
loop
43
44
45
46
Golauter:
47
Disable Pcint0
48
Disable Pcint1
49
Toggle Portb.1
50
Wait 1
51
Toggle Portb.2
52
Enable Pcint0
53
Enable Pcint1
54
Return
55
56
Goleiser:
57
Disable Pcint0
58
Disable Pcint1
59
Toggle Portb.2
60
Wait 1
61
Toggle Portb.1
62
Enable Pcint0
63
Enable Pcint1
64
Return

Der Interrupt wird nun auch ausgeführt. Allerdings funktioniert "wait 1" 
nicht
An den Fuses liegts nicht, der ist auch auf 8mhz programmiert, habe ich 
mit einem anderen miniprogramm getestet.

Gelesen habe ich das man Wait 1 in einem Interrupt nicht so verwenden 
sollte, aber was anstelle?

von frager (Gast)


Lesenswert?

Keiner ne idee?

von frager (Gast)


Lesenswert?

",8" am anfang is nur n versehen beim kopieren gewesen

von Norbert S. (norberts)


Lesenswert?

Hi,

das mit dem nicht funktionierendem "Wait 1" ist das $sim.
Wait in einer ISR ist wirklich "Bäh", setze ein Flag und mach das in der 
Hauptschleife.

Gruß,
Norbert

von frager (Gast)


Lesenswert?

Hallo, habe das problem in ein anderes Forum gepostet. Bekam da nach 
paar Minuten auch diese antwort. Hätte ich das mal schon früher gewusst 
:D. Dachte $sim ist lediglich für den internen Simulator gedacht :/.

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.