Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

pcint change

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
Duval JP

Bascom Member



Joined: 22 Jun 2004
Posts: 1232
Location: France

france.gif
PostPosted: Mon Dec 08, 2025 5:49 pm    Post subject: pcint change Reply with quote

Hello
I would like to use a PCchange interrupt on an ATMEGA1284P.
The goal is to read a light sensor that returns a 1 when it detects a change.

It works when I control it in the main loop.

Code:
Ir_detect Alias Pinc.3                                     ' data in  detecteur présence
Config Ir_detect = Input

do
'--
'--
         if ir_detect=1 then    'gestion de l'alumage ecran
            Flag_detect = 100
            Call Nex_light(100)      'on éclaire l'horloge
         End If
'--
'--
loop
 


but when I go out the loop that doesn't work...

I have very few free pins. I would like to use PC3, but I'm using PC0 and PC1 for the I2C port. Therefore, I can't declare the entire port as an input, only PC3.

I tried the PCINT_CHANGE.BAS example, trying to change the masks:

but it doesn't work.
how must i write the register to have an interrupt which jump to

Code:


isr_pcint19:                                                  'interruption
  Flag_detect = 1
Return
 


thanks for your help
JP

:wink:

(BASCOM-AVR version : 2.0.8.7 )

_________________
pleasure to learn, to teach, to create
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2377

blank.gif
PostPosted: Mon Dec 08, 2025 6:21 pm    Post subject: Re: pcint change Reply with quote

Duval JP wrote:
Code:
isr_pcint19:

You may name the ISRs however you want, but are you aware that there are only 4 PC-interrupts - PCINT0 ... PCINT3 -, each serving one port of 8 pins?
Corresponding for each interrupt are the PCMSK0 ... PCMSK3 registers.
The IO-pin with name PCINT19 (0..7, 8..15, 16..23, 24..31) belongs thus to the 3rd PCINT-vector, which is PCINT2, the mask register is thus PCMSK2 and the bit to set within PCMSK2 from 0..7 is number 3.
Back to top
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 1180

poland.gif
PostPosted: Mon Dec 08, 2025 6:30 pm    Post subject: Reply with quote

This is universal instruction.

Step1 : Look at the uC pinology and read PCINT number for PINB.3



Here it will be PCINT11

Step2 : Look at the DAT file for micro (because it is quick way for get that info) which PCINT MASK will cover that PCINT PIN



Now you know that you need to enable PCINT1 interrupt with PCMSK1 so...

Code:
Pcmsk1 = &B00001000 'pin 3
Enable Pcint1 : On Pcint1 Pcint1_isr
Enable Interrupts


Your PINC.3 belongs to PCMSK2 because it is PCINT19

_________________
Check B-Flash -my MCS bootloader app for Android
Back to top
View user's profile Visit poster's website
Duval JP

Bascom Member



Joined: 22 Jun 2004
Posts: 1232
Location: France

france.gif
PostPosted: Tue Dec 09, 2025 12:32 pm    Post subject: Reply with quote

sorry but no success

my code
Code:

'-----------------------------------------------------------------------------------------------------------------------------
$regfile = "m1284pdef.dat"                                  '  "m1284pdef.dat"                                  ' "m1284def.dat"
$crystal = 16000000                                         '20000000                                         '16000000                                         ' 11052000
$hwstack = 375                                              '375                                              '300
$swstack = 300                                              '200
$framesize = 300                                            '300
Config Submode = New
Debug On                                                    '                             if you debug off you remove all print from USB port

Const Updateeprom = 1                                       ' to keep eeprom var safe

'port for debug--- USB ------------------------------

Config Com1 = 115200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Echo Off
Config Serialin0 = Buffered , Size = 15
Config Serialout0 = Buffered , Size = 15                    'RX from Terminal
Open "COM1:" For Binary As #1
Const Usb = 1

dim  Flag_detect as byte
 Config Pinc.3 = Input

Enable Interrupts                                           'enable global ints
Enable Pcint2
Pcmsk2 = &B00001000
flag_detect=0
Wait 5    ' to wait for terminal


Debug#usb , "start"
On Pcint2 isr_pcint19

 Debug#usb ,"Pin masque A " ; Bin(pcmsk2) ; " " ; Bin(pinC)
Do
! nop

  If flag_detect = 1 Then                                   ' change detected
     Debug#usb , "pinc.3 has changed"                            'in this case it must be pinc.0
      Debug#usb ,"Pin change  B" ; Bin(pcmsk2)
      flag_detect=0
  End If
Loop

isr_pcint19:                                                  'interruption si présence humaine
  Debug#usb ,"Pin change C " ; Bin(pcmsk2) ; " " ; Bin(pinC)
  Flag_detect = 1
Return

End
 


i'm sure of my detector , it changes when I open the black box where it is closed
Crying or Very sad

_________________
pleasure to learn, to teach, to create
Back to top
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 1180

poland.gif
PostPosted: Tue Dec 09, 2025 1:09 pm    Post subject: Reply with quote

It is working like a charm. I add pullup to be shure.

Code:
Config Pinc.3 = Input : Portc.3 = 1                        'pullup  


And for example purpose disable PCINT2 in the ISR routine because without proper debounce whole terminal window will be flooded with debug messages.
So here you have...tested on real Mega1284 on ZL3 AVR


_________________
Check B-Flash -my MCS bootloader app for Android
Back to top
View user's profile Visit poster's website
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2377

blank.gif
PostPosted: Tue Dec 09, 2025 1:52 pm    Post subject: Reply with quote

Try it this way:
Code:
Do
! nop
  If flag_detect = 1 Then                                   ' change detected
     Debug#usb , "pinc.3 has changed"                            'in this case it must be pinc.0
      Debug#usb ,"Pin change  B" ; Bin(pcmsk2)
      flag_detect=0
        PCIFR.PCIF2 = 1   ' clear pending pc-ints
        Enable PCINT2   ' re-enable pcint2
  End If
Loop

isr_pcint19:                                                  'interruption si présence humaine
If PINC.3 = 1 Then   ' pin is high? means we got a rising edge
  Disable PCINT2
    Debug#usb ,"Pin change C " ; Bin(pcmsk2) ; " " ; Bin(pinC)
      Flag_detect = 1
End If
Return

You get easily multiple triggers of the ISR, additionally the ISR is triggered on rising as well as falling flanks, you need to sort out yourself.
Be aware that in case the signal oscillates and then flanks are faster than execution time from interrupt vector table to testing via 'If PINC.3 = 1', getting the correct flank may fail.
In this case it helps to catch the pin-status very early within the ISR with some ASM-code.
Back to top
View user's profile
port

Bascom Member



Joined: 23 Sep 2025
Posts: 12

germany.gif
PostPosted: Tue Dec 09, 2025 5:49 pm    Post subject: Reply with quote

Maybe I didn't understand the core problem.
But the following code worked for me on the physical AVR.



Code:

$regfile = "m1284pdef.dat"
$crystal = 18432000
$hwstack = 64
$swstack = 64
$framesize = 64
$baud = 9600

Config PinC.3 = Input
Config Portb.3 = Output
PortC.3 = 1

Enable PCINT2
Enable Interrupts
PCICR  = &B00000100
Pcmsk2 = &B00001000
Enable PCINT2
On Pcint2 isr_pcint19

Do
' nix
loop

isr_pcint19:

  toggle PortB.3

  Waitms 100
  Bitwait PinC.3 , Set
  Waitms 1
  PCIFR.PCIF2 = 1
  Return

End
Back to top
View user's profile
Duval JP

Bascom Member



Joined: 22 Jun 2004
Posts: 1232
Location: France

france.gif
PostPosted: Tue Dec 09, 2025 6:18 pm    Post subject: Reply with quote

many thank EDC and MWS !

Yes it works now

pull-up or not pull up ?a good question
My device send a 1 ,
if I put a pull up then change will be when it goes down. right?
if I don't the change goes up when I go up. right again ?

for the others bascom-users I forgot the flag register.

13.2.5 PCIFR – Pin Change Interrupt Flag Register
• Bit 3– PCIF3: Pin Change Interrupt Flag 3
When a logic change on any PCINT31:24 pin triggers an interrupt request, PCIF3 becomes set (one). If the I-bit
in SREG and the PCIE3 bit in PCICR are set (one), the MCU will jump to the corresponding Interrupt Vector.
The flag is cleared when the interrupt routine is executed. Alternatively, the flag can be cleared by writing a
logical one to it.
• Bit 2 – PCIF2: Pin Change Interrupt Flag 2
When a logic change on any PCINT23:16 pin triggers an interrupt request, PCIF2 becomes set (one). If the I-bit
in SREG and the PCIE2 bit in PCICR are set (one), the MCU will jump to the corresponding Interrupt Vector.
The flag is cleared when the interrupt routine is executed. Alternatively, the flag can be cleared by writing a
logical one to it.



Me must
- give a good mask
Code:
Pcmsk2 = &B00001000  
here
- choice the good register as said EDC following the dat file
-clear the flag
Code:
      PCIFR.PCIF2 = 1   ' clear pending pc-ints    

- pull up the port
- config the port in input

the final code

Wink
jp
Code:

$regfile = "m1284pdef.dat"                                  '  "m1284pdef.dat"                                  ' "m1284def.dat"
$crystal = 16000000                                         '20000000                                         '16000000                                         ' 11052000
$hwstack = 375                                              '375                                              '300
$swstack = 300                                              '200
$framesize = 300                                            '300
Config Submode = New
Debug On                                                    '                             if you debug off you remove all print from USB port

Const Updateeprom = 1                                       ' to keep eeprom var safe

'port for debug--- USB ------------------------------
Config Com1 = 115200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Echo Off
Config Serialin0 = Buffered , Size = 15
Config Serialout0 = Buffered , Size = 15                    'RX from Terminal
Open "COM1:" For Binary As #1
Const Usb = 1

dim  Flag_detect as byte
 Config Pinc.3 = Input  : Portc.3 = 1                        'pullup

Enable Interrupts                                           'enable global ints
Enable Pcint2
Pcmsk2 = &B00001000
flag_detect=0
Wait 5    ' to wait time to go tot the terminal

Debug#usb , "start"
On Pcint2 isr_pcint19

Do
! nop
  If flag_detect = 1 Then                                   ' change detected
      Debug#usb ,"flag-detect  "; Flag_detect
      flag_detect=0
        PCIFR.PCIF2 = 1   ' clear pending pc-ints
        Enable PCINT2   ' re-enable pcint2
  End If
Loop

isr_pcint19:                                                  'interruption si présence humaine
If PINC.3 = 1 Then   ' pin is high? means we got a rising edge
  Disable PCINT2
      Flag_detect = 1
End If
Return
end

_________________
pleasure to learn, to teach, to create
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2377

blank.gif
PostPosted: Tue Dec 09, 2025 6:45 pm    Post subject: Reply with quote

port wrote:
Maybe I didn't understand the core problem.

Duval JP wrote:
It works when I control it in the main loop.
...
but when I go out the loop that doesn't work...

The TO doesn't want to wait in one place.
Back to top
View user's profile
Duval JP

Bascom Member



Joined: 22 Jun 2004
Posts: 1232
Location: France

france.gif
PostPosted: Tue Dec 09, 2025 7:01 pm    Post subject: Reply with quote

to MWS

Quote:
he TO doesn't want to wait in one place.

Yes i know,

before searching how to make a change interrupt
I checked the port in my main loop


Code:

Ir_detect Alias Pinc.3                                     ' data in  detecteur présence
Config Ir_detect = Input

then
Code:

do
         if ir_detect=1 then    'gestion de l'alumage ecran
            Flag_detect = 100
            Call Nex_light(100)      'on éclaire l'horloge
         End If
loop
 

but how I have to check the light of the screen in an other page(nextion display)
So I need better control, hence the use of the interrupt.

Many thanks for your help
JP

_________________
pleasure to learn, to teach, to create
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2377

blank.gif
PostPosted: Tue Dec 09, 2025 9:31 pm    Post subject: Reply with quote

Duval JP wrote:
Many thanks for your help

You're welcome.
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum