News:

Let's find out together what makes a PIC Tick!

Main Menu

Change Notification Interrupt

Started by RGV250, Jul 09, 2024, 07:56 PM

Previous topic - Next topic

RGV250

Hi,
I have been playing with PIC24 and need an interrupt on PortA.2. After many times looking through the datasheet I notice there is a Change Notification Interrupt which is on all the I/O pins but I cannot for the life of me figure out how to implement it. Has anyone used this function?

Regards,
Bob

trastikata

Quote from: RGV250 on Jul 09, 2024, 07:56 PMHas anyone used this function?

Here's working code for dsPIC33EP128MC504, but it should work for the PIC24 too, just look up the registers because they will probably be different on your device.

Main:
    Clear

    Input PORTA.0           'Input porta.0 
    CNENA.0 = 1             'Enable interupt for porta.0
    IFS1.3 = 0              'Clear CNIF Interrupt flag
    IPC4.14 = 0             'priority for CN interrupts set to 1   
    IPC4.13 = 0             '-     
    IPC4.12 = 1             '-
    IEC1.3 = 1              'Enable CN interrupts using the CNIE
End   
Isr CNInterrupt:
    IFS1.3 = 0              'Clear CNIF Interrupt flag
    TEST_LED = PORTA.0      'read porta.0 to clear the mismatch condition and set up the CN logic
EndIsr   

trastikata

#2
P.s. If there are no external pull-up resistors to the pin or a push/pull device connected to it, then enable the weak internal pull-up resistors.

CN.jpg

diebobo

#3
Device = 24FJ64GA004
Declare Xtal = 32

Config Config1 = JTAGEN_OFF, GCP_OFF, GWRP_OFF, BKBUG_OFF, COE_OFF, ICS_PGx1, FWDTEN_OFF, WINDIS_OFF, FWPSA_PR128, WDTPOST_PS256
Config Config2 = IOL1WAY_OFF, COE_OFF, IESO_OFF, FNOSC_FRCPLL, FCKSM_CSDCMD, OSCIOFNC_ON, POSCMOD_NONE

CLKDIV = 0 ' CPU peripheral clock ratio set to 1:1
OSCCON.Byte1 = %00010000 ' Enable 4 x PLL

Setup:

    Symbol Switch_1             = PORTC.9
    Symbol Switch_2             = PORTC.8

    TRISA      = 65535
    TRISB      = 65535
    TRISC      = 65535

    CNPU2.7    = 1 ' PullUp ZeroCross
    CNPU2.3    = 1 ' PullUp Switch_1
    CNPU2.4    = 1 ' PullUp Switch 2

    CNEN2bits_CN19IE    = 1 ' Switch 1 IOC enable
    CNEN2bits_CN20IE    = 1 ' Switch 2 IOC enable

    IEC1bits_CNIE      = 1 ' interrupt on change ( voor switch 1 en 2 )

    IPC4bits_CNIP2      = 0 ' 4
    IPC4bits_CNIP1      = 0 ' 2
    IPC4bits_CNIP0      = 1 ' 1

Main:

Goto Main 

Isr CNInterrupt

    IFS1bits_CNIF = 0

    If Switch_1 = 0 Then AC_Detect ( True )
    If Switch_2 = 0 Then AC_Detect ( True )

EndIsr


Copy / Paste the relavant parts, no energy more today to comment ..  U Should be able to work it out ;)

RGV250

Thanks for the replies, I have it working now.

The next thing it would be nice to be able to select just rising edge.
I think I can do this by using the external interrupt but this seems to need the pin mapped to this.
I am finding the PPS selection/setting a bit of an issue. Is it just me or are Microchip datasheets just awful. I have looked in the table of contents and index and do not find any mention of PPS or remapping pins etc at all.

Bob

trastikata

Quote from: RGV250 on Jul 10, 2024, 08:37 PMI am finding the PPS selection/setting a bit of an issue. Is it just me or are Microchip datasheets just awful. I have looked in the table of contents and index and do not find any mention of PPS or remapping pins etc at all.

Hello Bob,

they are usually in the I/O Port section, what is the device you are working with?

Ports designated as RPIn can be used to remap inputs only whereas RPn can be input or output.

1. To designate a port pin for peripheral input, look in the table: SELECTABLE INPUT SOURCES
- look which register and  bits in this register are associated with the input (function) name, for example (dsPIC33EP128MC504) External Interrupt 1 is associated with register RPINR0 and bits INT1R[6:0]
- now look in table INPUT PIN SELECTION FOR SELECTABLE INPUT SOURCES - look the value assigned for the pin you want to remap. For example RPI24 (PORTA.8 ) has a value 0011100
- write that value, as explained in the beginning, in register RPINR0 bits INT1R[6:0]

2. Outputs are mapped other way around, thus each RP pin has an associated register where you write a value that will instruct the pin what kind of peripheral it will serve. For example I want RP54 (PORTC.6) to be the SPI2 Clock Output:
- I look in table OUTPUT SELECTION FOR REMAPPABLE PINS and there SCK2 has a value 001001
- Those bits ave to be written in the bits for RP54 that reside in the register which is setting RP54 - these are called register RPOR0, RPOR1 ... In my case this is RPOR5 but in this register you have space for two RP pis, thus look which bits command RP54 pin - that would be bits 5-0 (RP54R[5:0])
- write in those bits the value 001001 from table OUTPUT SELECTION FOR REMAPPABLE PINS to make RP54 pin output for SPI2 Clock Output (SCK2)

Hope this helps. 


RGV250

Thanks, that is a very good explanation, I will study it better tomorrow when I have the datasheet to hand.
Just having a beer after watching England scrape through yet again.

Bob

diebobo

As an addition, this is a few lines to map Uart 1 and Uart 2 to the pins of my choosing. Device 24FJ64GA004

PPS_Output(cOut_Pin_RP11, cOut_Fn_U1TX) ' Map UART1 TX pin to RP35
PPS_Input(cIn_Pin_RP10, cIn_Fn_U1RX) ' Map UART1 RX pin to RPI34

PPS_Output(cOut_Pin_RP20, cOut_Fn_U2TX) ' Map UART1 TX pin to RP35
PPS_Input(cIn_Pin_RP21, cIn_Fn_U2RX) ' Map UART1 RX pin to RPI34