On change interrupt using mikromedia for PIC32

mikroC, mikroBasic and mikroPascal PRO for Microchip’s 32-bit PIC MCUs
Post Reply
Author
Message
GWL
Posts: 13
Joined: 04 May 2014 05:25

On change interrupt using mikromedia for PIC32

#1 Post by GWL » 26 Feb 2022 06:50

Hi,
I have the problem of clearing on-change notification interrupts on the mikromedia pic32MX460F512L.
I have a ring counter based on a 18F4550 which triggers 8 on change interrupts on the mikromedia forPIC32 (pic32MX460F512L), being pins B0,B1,B2,B3,B4,B5,F4,F5.
The triggers are through optical isolators and have fast clean rise and fall times. The ring count rate is variable from about 0.1 to 20 seconds.
These interrupts at present drive 8 leds being B14, E8,E9,B6, B7,F3,G12,G13.
The UART in set to 115200.

The results are:
IOC : 1
IOC : 2
IOC : 2
IOC : 3
IOC : 3
IOC : 4
IOC : 4
IOC : 5
IOC : 5
IOC : 6
IOC : 6
IOC : 7
IOC : 7
IOC : 8
int cnt : 14
IOC : 8
int cnt : 1
IOC : 1
and repeat

I am at a loss as to how to clear the interrupt to stop getting 2 interrupts per trigger other than the first trigger.
There is something obvious I have overlooked.
How do I fix this. Extensive web searches have proven fruitless..
The relevant code is as follows:


program onChange;
// processor pic32MX460F512L
// clock 80 MHz
// PLL 2x divide
// PLL 20x multiply
//

const portIn = 1;
portOut = 0;

var
RX1 : sbit at portF.2; RX1_direction : sbit at TRISF2_bit; // pin 47
TX1 : sbit at LATF8_bit; TX1_direction : sbit at TRISF8_bit; // pin 48

Input1 : sbit at portF.5; Input1_direction : sbit at TRISF5_bit; // pin 46 G4.3 CN18
Input2 : sbit at portF.4; Input2_direction : sbit at TRISF4_bit; // pin 45 G4.2 CN17
Input3 : sbit at portB.5; Input3_direction : sbit at TRISB5_bit; // pin 8 G0.3 CN2
Input4 : sbit at portB.4; Input4_direction : sbit at TRISB4_bit; // pin 7 G0.2 CN3
Input5 : sbit at portB.3; Input5_direction : sbit at TRISB3_bit; // pin 6 G0.1 CN4
Input6 : sbit at portB.2; Input6_direction : sbit at TRISB2_bit; // pin 5 G0.0 CN5
Input7 : sbit at portB.1; Input7_direction : sbit at TRISB1_bit; // pin 4 A1 CN6
Input8 : sbit at portB.0; Input8_direction : sbit at TRISB0_bit; // pin 3 A0 CN7

Led1 : sbit at LATB14_bit; Led1_direction : sbit at TRISB14_bit; // pin 9
Led2 : sbit at LATE8_bit; Led2_direction : sbit at TRISE8_bit; // pin 10
Led3 : sbit at LATE9_bit; Led3_direction : sbit at TRISE9_bit; // pin 11
Led4 : sbit at LATB6_bit; Led4_direction : sbit at TRISB6_bit; // pin 16
Led5 : sbit at LATB7_bit; Led5_direction : sbit at TRISB7_bit; // pin 17
Led6 : sbit at LATF3_bit; Led6_direction : sbit at TRISF3_bit; // pin 18
Led7 : sbit at LATG12_bit; Led7_direction : sbit at TRISG12_bit; // pin 19
Led8 : sbit at LATG13_bit; Led8_direction : sbit at TRISG13_bit; // pin 20

s20 : string[20];
s15 : string[15];
s10 : string[10];
s5 : string[5];
s3 : string[3];

stimInput : integer;


procedure init_directions;
begin

RX1_direction := portIn; // pin 47
TX1_direction := portOut; // pin 48

Input1_direction := portIn; // pin 46
Input2_direction := portIn; // pin 45
Input3_direction := portIn; // pin 8
Input4_direction := portIn; // pin 7
Input5_direction := portIn; // pin 6
Input6_direction := portIn; // pin 5
Input7_direction := portIn; // pin 4
Input8_direction := portIn; // pin 3

Led1_direction := portOut; // pin 9
Led2_direction := portOut; // pin 10
Led3_direction := portOut; // pin 11
Led4_direction := portOut; // pin 16
Led5_direction := portOut; // pin 17
Led6_direction := portOut; // pin 18
Led7_direction := portOut; // pin 19
Led8_direction := portOut; // pin 20

end;

// send to uart1 string followed by an integer
procedure serialInt(VAR s:string[20];var i:integer);
begin
inttostr(i,S10);
UART1_Write_Text(s);
UART1_Write_Text(': ');
UART1_Write_Text(s10);
UART1_Write(CR);
UART1_Write(LF);
end;

procedure Uart1_writeLn(var s:string[100]);
begin
UART1_Write_Text(s);
UART1_Write_Text(' ');
UART1_Write(CR);
UART1_Write(LF);
end;

procedure clearChannelLeds;
begin
Led1 :=0 ;
Led2 :=0 ;
Led3 :=0 ;
Led4 :=0 ;
Led5 :=0 ;
Led6 :=0 ;
Led7 :=0 ;
Led8 :=0 ;
end;

procedure setChannelLed(channel:byte);
begin
clearChannelLeds;
case channel of
1 : Led1 :=1 ;
2 : Led2 :=1 ;
3 : Led3 :=1 ;
4 : Led4 :=1 ;
5 : Led5 :=1 ;
6 : Led6 :=1 ;
7 : Led7 :=1 ;
8 : Led8 :=1 ;
end;
end;



procedure initalise_change_notification_Interupts;
begin
disableInterrupts;

MVEC_bit := 1;

// change notification
{ CNCON.15 is use change notice
CNPUEx is pull for pin x
CNENx is enable for pin x
CNIP 0..2 priority
CNIS 0..1 sub priority
CNIF_bit clear the interupt flag
CNIE_bit enable the change notice module
}

CNCON.15 := 1; // turn it on
// CNCON.11 := 1; // use edge detect : not implemented in pic32MX460F512L
CNCON.13 := 0; // cpu idle does not interfer with CN function


// enable CN bits
CNEN18_bit := 1; // RF5
CNEN17_bit := 1; // RF4
CNEN2_bit := 1; // R55
CNEN3_bit := 1; // RB4
CNEN4_bit := 1; // RB3
CNEN5_bit := 1; // RB2
CNEN6_bit := 1; // RB1
CNEN7_bit := 1; // RB0


// CNIP<2:0> (IPC6<20:18>), and Sub-priority bits,CNIS<1:0> (IPC6<17:16>).
CNIP0_bit := 0;
CNIP1_bit := 1; // set to 4
CNIP2_bit := 0;

// CNIS0_bit := ; // do not use a sub priority
// CNIS1_bit := ;

CNIF_bit := 0; // clear cn interrupt flag
CNIE_bit := 1; // Enable the CN Interrupt Enable bit

EnableInterrupts(); // Enable all interrupts
Uart1_writeLn('Change notification interrupt enabled');
end;


// -------- interrupts for Inputs 1 - 8 ----------------------
procedure CN_ISR; iv IVT_CHANGE_NOTICE ; ilevel 4; ics ICS_AUTO; //ICS_OFF;
var s : string[15];
cnt : integer;
begin

CNIE_bit := 0; // turn off interrupt

s := '';
stimInput := 0;


if (portB and %00111111) or (portF and %00110000) then
begin

if portF.5 = 1 then begin stimInput := 1; s := '00000001 '; end; // input1
if portF.4 = 1 then begin stimInput := 2; s := '00000010 '; end; // input2
if portB.5 = 1 then begin stimInput := 3; s := '00000100 '; end; // Input3
if portB.4 = 1 then begin stimInput := 4; s := '00001000 '; end; // Input4

if portB.3 = 1 then begin stimInput := 5; s := '00010000 '; end;
if portB.2 = 1 then begin stimInput := 6; s := '00100000 '; end;
if portB.1 = 1 then begin stimInput := 7; s := '01000000 '; end;
if portB.0 = 1 then begin stimInput := 8; s := '10000000 '; end;

serialInt('IOC ', stimInput); // this writes a string and an integer to the UART


inc(cnt); // count the number in interrupts in the ring of 8

setChannelLed(stimInput); // clears the leds then turns on led number stimInput via a case statement


if stimInput = 8 then // on the 8th external interrupt ie b0 triggered the displayed the number of internal interrupts
begin
serialInt('int cnt ', cnt);
cnt := 0;
end;
end;

CNIF_bit := 0; // clear cn interrupt flag
CNIE_bit := 1; // turn on the interrupt
end;




begin
// ---------------- analog/digital ports --------------------
CHECON := 0x32;
AD1PCFG := 0xFFFF; // Initialize AN pins as digital

CM1CON := 0; // Turn off comparators
CM2CON := 0;

init_directions;
Delay_ms(150);


UART1_Init(115200); // needs to be set before the INT otherwise it hangs
Delay_ms(100);
UART1_WriteLn('uart 1 Connected');

initalise_change_notification_Interupts;

while (TRUE) do
begin
end;

end.

sgssn
Posts: 35
Joined: 13 Sep 2021 16:24

Re: On change interrupt using mikromedia for PIC32

#2 Post by sgssn » 26 Feb 2022 09:19

Hi
i am not familiar to that language and/or PIC32, but what i have noticed are two lines, which seem to be suspicous:

UART1_Write_Text(': ');
UART1_Write_Text(' ');

I would expect, that these functions want to see a string not a single character.
As above
UART1_Write(CR);
UART1_Write(LF);

i had expected to read

UART1_Write(': ');
UART1_Write(' ');

But dont know if thats the problem.

Gerhard

GWL
Posts: 13
Joined: 04 May 2014 05:25

Re: On change interrupt using mikromedia for PIC32

#3 Post by GWL » 01 Mar 2022 15:16

Does any one have an idea why the interrupt is not cleared ?

I have modified the led display routine to:

procedure setChannelLed(channel:byte);
var i : integer;
begin
i := channel;
clearChannelLeds;
case channel of
1 : Led1 :=1 ;
2 : Led2 :=1 ;
3 : Led3 :=1 ;
4 : Led4 :=1 ;
5 : Led5 :=1 ;
6 : Led6 :=1 ;
7 : Led7 :=1 ;
8 : Led8 :=1 ;
end;
delay_ms(100); // new line
clearChannelLeds;
end;

and I keep the ring counter's pulse < 100mS .

Measuring at a LED I get a 100mS pulse followed by a very small delay and another 100mS pulse which indicates that the interrupt flag is not cleared.

Any ideas ? Or do I have to try and write this behavior out in code?

GWL
Posts: 13
Joined: 04 May 2014 05:25

Re: On change interrupt using mikromedia for PIC32

#4 Post by GWL » 02 Apr 2022 00:10

Solution:

Abandoned Interrupt on change and used a 8 input or gate and an edge triggered interrupt.

Post Reply

Return to “PIC32 PRO Compilers”