Beste forummers,

Ik ben bezig met een programma voor de ATtiny2313 met de pcint pennen, maar ik heb geen idee hoe ik dat in bascom moet doen? Zoeken in de help van bascom heeft nog geen vruchten afgeworpen...

Iemand een idee?

In de ATtiny2313.dat file staat het volgende:

[INTS]
INT0=$001	;External Interrupt0 Vector Address
INT1=$002	;External Interrupt1 Vector Address
ICP1=$003	;Input Capture1 Interrupt Vector Address
OC1A=$004	;Output Compare1 Interrupt Vector Address
OVF1=$005	;Overflow1 Interrupt Vector Address
OVF0=$006	;Overflow0 Interrupt Vector Address
URXC=$007	;UART Receive Complete Interrupt Vector Address
UDRE=$008	;UART Data Register Empty Interrupt Vector Address
UTXC=$009	;UART Transmit Complete Interrupt Vector Address
ACI=$00a	;Analog Comparator Interrupt Vector Address
PCINT=$00B
OC1B=$00C
OC0A=$00D
OC0B=$00E      ; timer 0 compare match B
UCI_START=$00F  ; USI start
UCI_OVFLW=$010  ; USI overflow
EERDY=$011      ; eeprom ready
WDT=$012        ; watch dog timer overflow

Dus ik neem aan dat je PCINT moet hebben, gezien 0x000B het program adress is voor een pin change interrupt.

Als je dan nog even verder zoekt kom je erachter dat je een masker op kan zetten zodat alleen bepaalde pinnen een interrupt geven:

' In case you want PCINT option
' Pcmsk2 = &B0000_0100        'set the mask to ONLY use the pin connected to DOUT
' On Pcint2 Checkints         'label to be called
' Enable Pcint2               'enable this interrupt

En als ik dan bijvoorbeeld 4 PCINT pennen tegelijkertijd wil gebruiken, elk met een aparte subfunctie eraan, is dit ook mogelijk? Of gewoon één interrupt pin die steeds een programma verder schakelt wanneer erop gedrukt wordt.

Als ik dit goed begrijp moet je, wanneer je de PCINT pinnen afzonderlijk wil gebruiken de mask steeds opnieuw instellen. Klopt dit? (zal wel niet:))

Ik heb geen idee, ik heb dit ook maar zo uit de datasheet geplukt. Beetje uitproberen lijkt me.

Op 19 januari 2009 15:35:19 schreef Beroepsprutser:
Als ik dit goed begrijp moet je, wanneer je de PCINT pinnen afzonderlijk wil gebruiken de mask steeds opnieuw instellen. Klopt dit? (zal wel niet:))

De mask stel je in zodat je de 4 pinnen tegelijkertijd kan afvangen. In de interrupt routine bepaal je dan welke van de 4 het interrupt heeft veroorzaakt.

Ahh zo,

Dus ik moet me dat ong zo voorstellen:

On PCINT ga naar Bepaal_Sub

Bepaal_Sub:

Select Case interrupt

case 1
goto prog_1

enz.

En hoe bepaal ik welke Pcint getoggled werd?

Op het moment dat je de interrupt routine in gaat lees je de status van de pinnen uit en zo bepaal je welke het interrupt heeft veroorzaakt. De pinnen moeten dus wel lang genoeg hoog/laag blijven totdat je in de interrupt routine zit. Kan dat niet dan zal je met losse interrupts moeten werken of met een extern geheugen element (flipflop). De meeste AVR's hebben volgens mij niet 4 externe interrupts.

Een normale drukknop/toets houd je normaal gesproken lang genoeg vast

De tiny2313 heeft acht PCINT pinnen, alle portb pinnen zijn tevens PCINT;)

Ik bedoel afzonderlijke interrupts, PCINT is maar één interrupt.

Ahhzo, sorry ik begreep je verkeerd;)

Inderdaad, de tiny2313 heeft maar 2 externe interrupts, INT0 en INT1

Pcint Interrupts kunnen Worden gegenereerd door alle Pcint pinnen , er zijn echter maar 3 interrupt bronnen.
Pin Change Interrupt Pcint2 als Pinnen Pcint23..16 Van niveau veranderen.
Pin Change Interrupt Pcint1 als Pinnen Pcint14..8 Van niveau veranderen.
Pin Change Interrupt Pcint0 als Pinnen Pcint7..0 Van niveau veranderen.

In de Pcmsk2 , Pcmsk1 en Pcmsk0 Registers kunt je aangeven welke pinnen je wilt toestaan Pin Change
Interrupts Te Genereren.


Enable Interrupts
Enable Pcint0
On Pcint0 pin_change                                        'Ga naar pin_change als een van de pinnen uit het masker wijzigd
Pcmsk0 = &B00011001                                         'masker PinB0 & B3 & B4

pin_change:

   
      If Pinb.0 = 0 Then

         ' Jouw actie

      End If


      If Pinb.0 = 1 Then

         ' Jouw actie

      End If

      If Pinb.3 = 0 Then

         ' Jouw actie

      End If


      If Pinb.3 = 1 Then

         ' Jouw actie

      End If

      If Pinb.4 = 0 Then

         ' Jouw actie

      End If


      If Pinb.4 = 1 Then

         ' Jouw actie

      End If

Return

Zover ben ik nu dus, alleen ipv een if..then een select case structuur.

Ik heb nu dit, om het te testen:


$regfile = "attiny2313.dat"
$crystal = 1000000
Config Portb = Input
Config Portb.0 = Output
Enable Interrupts
Enable Pcint
On Pcint Pin_change                                         'Ga naar pin_change als een van de pinnen uit het masker wijzigd
Pcmsk = &B10000000                                          'masker PinB0 & B3 & B4
Set Portb.0
pin_change:


Reset Portb.0
Return

En het werkt niet. Geen idee waarom eigenlijk. Zie ik iets over het hoofd?

Waar is je main loop gebleven? De program counter slaat op hol op deze manier.

Ik zal hem aanpassen, en eens kijken wat ervan komt.

Ik heb alles verwerkt in een rc5-ontvanger, waarvoor het ook uiteindelijk bedoeld was. De bedoeling is dus, dat in de main loop het hoofdprogramma komt, en dat als er een pin change op de rc5 pin komt dat hij de rc5 uitleest en naargelang de code een bepaalde handeling uitvoert. Dit is een testje daarvoor maar wanneer ik op mijn ab op een knop druk, stopt de led op portb.4 met knipperen maar gebeurt verder niks.

Zoals te zien heb ik ook de interrupts gedisabled in de rc5-routine, maar dit hielp niets.


$regfile = "attiny2313.dat"
$crystal = 1000000
$lib "mcsbyte.lbx"


Config Portb = Output
Config Portb.0 = Input

Config Rc5 = Pinb.0
Enable Pcint
On Pcint Pin_change
Pcmsk = &B00000001
Dim Address As Byte , Command As Byte , I As Byte
Enable Interrupts
Set Portb.2
Reset Portb.3

Do
Portb.4 = 1
Waitms 500
Portb.4 = 0
Waitms 500
Loop
Pin_change:

 Disable Interrupts
  Getrc5(address , Command)


If Address = 0 Then

    Toggle Portb.2
    Toggle Portb.3

End If

  Enable Interrupts

Return
End

Wat doe ik fout?

Disable Interrupts
Getrc5(address , Command)

Manual Bascom: http://avrhelp.mcselec.com/index.html

GETRC5
Also the interrupt of TIMER0 is used by this statement.

TIMER0 can be used by your application since the values are preserved by the statement but a delay can occur. The interrupt can not be reused.

Ik zou het zo doen:


Pin_change:

pin_change_flag = 1

Return 

Hoofd lus:


dim pin_change_flag as Byte

if pin_change_flag = 1 then

 Getrc5(address , Command)

 If Address = 0 Then
    Toggle Portb.2
    Toggle Portb.3
 End if

 pin_change_flag = 0

End if

Bedankt, dit werkt perfect!
Dit heb ik nu dus:


$regfile = "attiny2313.dat"
$crystal = 1000000
$lib "mcsbyte.lbx"


Config Portb = Output
Config Portb.0 = Input

Config Rc5 = Pinb.0
Enable Pcint
On Pcint Pin_change
Pcmsk = &B00000001
Dim Address As Byte , Command As Byte , I As Byte
Dim Pin_change_flag As Boolean
Enable Interrupts
Set Portb.2
Reset Portb.3

Do


if pin_change_flag = 1 then

 Getrc5(address , Command)

 If Address = 0 Then
    Toggle Portb.2
    Toggle Portb.3
 End if

 pin_change_flag = 0

End if
Portb.4 = 1
Waitms 500
Portb.4 = 0
Waitms 500
Loop
Pin_change:
pin_change_flag = 1


Return
End

Dit werkt nu helemaal niet, geen enkel teken van leven van de leds:


$regfile = "attiny2313.dat"
$crystal = 1000000
$lib "mcsbyte.lbx"


Config Portb = Output
Config Portb.0 = Input
Config Timer1 = Pwm , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Config Rc5 = Pinb.0

Enable Pcint

On Pcint Pin_change

Pcmsk = &B00000001

Dim Address As Byte , Command As Byte
Dim Pin_change_flag As Boolean
Dim Subvooruit As Boolean

Enable Interrupts
Pin_change_flag = 0
Subvooruit = 0
Reset Portb.2

Do


If Pin_change_flag = 1 Then

 Getrc5(address , Command)

 If Address = 0 Then
    Toggle Subvooruit
    Toggle Portb.2
 End If

 Pin_change_flag = 0

End If
If Subvooruit = 0 Then

'begin eerste programma

Portb.3 = 0
Waitms 500
Portb.3 = 1
Waitms 500

'einde eerste programma

Elseif Subvooruit = 1 Then
'begin tweede programma

Pwm1a = Pwm1a + 1
Waitms 10

'einde tweede programma
End If
Loop

Pin_change:
Pin_change_flag = 1
Return
End

Ik kon me wel voorstellen dat de timer0 dubbel werd gebruikt hier, voor de rc5 en het faden. Dus veranderde ik de timer voor het faden in timer1. Maar nee, het blijft donker...

Niemand?

/EDIT: ik ben er al achter, de timer loopt gewoon door en daardoor blijft de PWM waarde op zijn huidig niveau met als gevolg dat hij niet meer fade en niet knippert. Maar hoe moet ik dit dan gaan aanpakken?

[Bericht gewijzigd door Beroepsprutser op (93%)]