The MCHP_CN block provides an interface to the Change Notification (CN) peripheral, which detects pin state changes and measures transition timing. While primarily used for GPIO interrupts (buttons, switches), CN can also serve as a simple encoder interface or pulse counter.
When to use:
When NOT to use:
| Family | CN Type | CN Pins | Notes |
|---|---|---|---|
| dsPIC30F | Type 0 | CN0-CN15 | Dedicated CN peripheral |
| dsPIC33F | Type 0 | CN0-CN23 | Dedicated CN peripheral |
| dsPIC33E | Type 1 | All GPIO pins | All ports have CN capability |
| dsPIC33C | Type 1 | All GPIO pins | All ports have CN capability |
| dsPIC33A | Type 1 + SCCP | All GPIO pins | All ports; timing timer width selectable (16-bit or 32-bit SCCP) |
| PIC32MK | Type 2 | Port-based | One interrupt per port |
| PIC24F | Type 0/1 | Varies | Family dependent |
| Parameter | Description |
|---|---|
| CN Channels (dsPIC30F/33F) | Vector of CN channel numbers, e.g., [0 1 2] for CN0, CN1, CN2 |
| CN Port (dsPIC33E/C, PIC32MK) | Port pin list, e.g., A0 A1 B5 for PA0, PA1, PB5 |
| Mode Value | Measurement | Output Ports |
|---|---|---|
| 0 | Change detect only | Change detected flag only |
| 1 | Measure time UP (rising edge to falling edge) | T_Up (pulse width high) |
| 2 | Measure time DOWN (falling edge to rising edge) | T_Down (pulse width low) |
| 3 | Measure UP & DOWN | T_Up, T_Down |
| 4 | Period on rising edge | P_Rising (time between rising edges) |
| 8 | Period on falling edge | P_Falling (time between falling edges) |
| 5 | UP + Period on rising | T_Up, P_Rising |
| 10 | DOWN + Period on falling | T_Down, P_Falling |
| Value | Detection Mode | Output |
|---|---|---|
| 0 | No change detection | - |
| 1 | Rising edge | CNx_Rise (timestamp) |
| 2 | Falling edge | CNx_Fall (timestamp) |
| 3 | Both edges | CNx_Rise&Fall (timestamp) |
| Parameter | Description |
|---|---|
| Output Port Value | Enable current pin state output (boolean per channel) |
| Max Channel | Maximum expected time for measurements (seconds, per channel) |
| Safe Margin | Percentage margin for timer overflow protection (per channel) |
| Interrupt Priority | CN interrupt priority level (1-7) |
Timer Bit Width (TimerBitWidth) | dsPIC33A only โ Selects the width of the SCCP timer used for CN timestamping: 16 bits (default โ covers up to 65 536 counts per timer tick, lower RAM footprint) or 32 bits (uses one full 32-bit SCCP module, max count = 4โฏ294โฏ967โฏ296 โ removes overflow concerns for long pulses, at the cost of one SCCP resource). The output port datatype follows the selection (uint16 for 16-bit, uint32 for 32-bit). On all other families the field is hidden and fixed at 16 bits. |
dsPIC33A 32-bit SCCP mode โ When Timer Bit Width = 32 bits, the block allocates a 32-bit SCCP timer from the device pool. If the timer pool reports no available 32-bit width (e.g. all SCCPs already taken by other peripherals), the callback falls back to 16-bit and emits the warning
MCHP:CN32bit. Check Timer Info block output to audit SCCP usage.
// Enable CN module CNCONbits.ON = 1; // Enable specific CN pins CNEN1bits.CN0IE = 1; // Enable CN0 CNEN1bits.CN1IE = 1; // Enable CN1// Enable pull-ups CNPU1bits.CN0PUE = 1; // Pull-up on CN0// Interrupt configuration IFS1bits.CNIF = 0; // Clear interrupt flag IEC1bits.CNIE = 1; // Enable CN interrupt IPC4bits.CNIP = 5; // Priority level// Read current state state = PORTBbits.RB0; // Read pin state (if CN0 is on RB0)
// All GPIO pins have CN capability// Enable change notification on specific pins// For port A, pin 0 (PA0/RA0): CNENAbits.CNIEA0 = 1; // Enable CN on RA0 CNPUAbits.CNPUA0 = 1; // Pull-up on RA0// Interrupt per port IFS3bits.CNAIF = 0; // Clear Port A CN interrupt IEC3bits.CNAIE = 1; // Enable Port A CN interrupt
// One CN interrupt per port CNENAbits.CNIEA0 = 1; // Enable CN on RA0// Edge select (positive/negative/both) CNNEAbits.CNNEA0 = 0; // 0 = positive edge, 1 = negative edge// Interrupt control IFS3bits.CNAIF = 0; IEC3bits.CNAIE = 1;
The block creates workspace variables for scaling calculations:
| Variable | Description |
|---|---|
CN0max, CN1max, … | Maximum timer count per CN channel |
Output values are in raw timer ticks. To convert to physical time:
Time_Resolution = Max_Channel / CNxmax
Time_seconds = Timer_Ticks ร Time_Resolution
Example: With CN0max = 65535 and Max_Channel = 0.1s:
Time_Resolution = 0.1 / 65535; % โ 1.53 ยตs per tick
Pulse_Width_s = CN0_Up * Time_Resolution;
Period_s = CN0_Per * Time_Resolution;
Frequency_Hz = 1 / Period_s;
// Timer resolution depends on Max_Channel and timer selection// Block automatically chooses best timer to meet requirements// Example: Max_Channel = 1ms, CNxmax = 65535 Time_Resolution = 1e-3 / 65535 = 15.3 ns; // For pulse width measurement accuracy:// ยฑ1 count error = ยฑ15.3 ns// For longer periods, resolution decreases:// Max_Channel = 1s โ Resolution = 15.3 ยตs
Typical CN Interrupt Overhead:
Hardware: 4 push buttons on CN0-CN3 with pull-ups
Configuration:
Hardware: Mechanical rotary encoder on CN0 (A) and CN1 (B)
Configuration:
Configuration:
Configuration:
Cause: Mechanical switch contacts bounce
Solutions:
Cause: CN interrupt rate too high or interrupt latency
Solutions:
Cause: Signal period exceeds Max Channel setting
Solutions:
Last Updated: 2024 | MCHP Blockset for MATLAB/Simulink