PCINT > Attiny24a > Bascom

Gast #3738752
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
Gast #3739347
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.
Gast #3739983
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. ;-)
Gast #3739991
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?
Gast #3740046
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.
Gast #3740051
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.
Gast #3740108
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.
#3740329
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
Gast #3740638
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.
#3740668
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
Gast #3740740
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.
#3740872
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
Gast #3740887
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?
Gast #3741059
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?
Gast #3742122
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren