CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

Interrupt Issue

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
matthewmilford



Joined: 09 Feb 2021
Posts: 17

View user's profile Send private message

Interrupt Issue
PostPosted: Wed Feb 24, 2021 1:28 pm     Reply with quote

Hello all. Hopefully someone has ran into this issue before. I am using a triac to switch AC from a pic 18f26k42. This is the simplest code version that I can come up with, however it seems to be skipping signals. I am feeding in a 60 hz square wave. It should be driving an output on every change (up or down) it isn't. What is puzzling me about this is that there seems to be no pattern as to how often the signal coming out of the pic occurs. When it occurs it is always in the correct place on the waveform and will light the bulb, however it is missing the vast majority of the signals. It seems to me that I maybe overflowing a buffer or possibly the pic is going to sleep? Any insight would be appreciated.
Mplab x v5.35
Code:

#include <18f26k42.H>

#include <stdio.h>
#define triac_gate    PIN_A1
#PIN_SELECT INT1=PIN_B0       
#use delay(clock = 4MHz)
int ZC = 0;

//******************************************************************
#INT_EXT            // external interrupt ISR
void EXT_ISR()
{
   //clear_interrupts(INT_EXT);
   ZC = 1;
}
//******************************************************************

void main()
{
  //ext_int_edge(H_TO_L);   //catch only high to low
  output_low(triac_gate);
  output_drive(triac_gate);
 
  clear_interrupt(INT_EXT);          // clear external interrupt flag bit
  enable_interrupts(INT_EXT);        // enable external interrupt
  enable_interrupts(GLOBAL);         // enable global interrupts
  while(TRUE)
  {
        if(ZC == 1)
        {
            ZC = 0;
            delay_ms(4);
            output_high(triac_gate);
            delay_us(5);
            output_low(triac_gate);   
        }
  }
}


Last edited by matthewmilford on Wed Feb 24, 2021 1:42 pm; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 8057
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Feb 24, 2021 1:40 pm     Reply with quote

Ok, what is the hardware that's between the AC signal and the PIC ?

If you're actually feed in AC, you WILL destroy the PIC, sooner or later.....

You NEED a proper 'zero cross detector' circuit...
matthewmilford



Joined: 09 Feb 2021
Posts: 17

View user's profile Send private message

PostPosted: Wed Feb 24, 2021 1:45 pm     Reply with quote

There is an isolator between the ac and the pic. I am not feeding in ac direct, the square wave form is coming off a zero cross detector.

Also I used a scope and the pic is getting in a correct square wave on pin b0.

Just to clarify also.... I have tested the circuit... If I unplug the pic and short across my +5v to the signal line I get a steady full on which is what should be expected with an all on signal.
PCM programmer



Joined: 06 Sep 2003
Posts: 21420

View user's profile Send private message

PostPosted: Wed Feb 24, 2021 2:19 pm     Reply with quote

Your PIC has a ZCD module. Why not use it ?
Look at the setup_zcd() function in the CCS manual.
https://www.ccsinfo.com/downloads/ccs_c_manual.pdf
matthewmilford



Joined: 09 Feb 2021
Posts: 17

View user's profile Send private message

PostPosted: Wed Feb 24, 2021 3:17 pm     Reply with quote

Okay, I will look into that and see if it will work for my application.
matthewmilford



Joined: 09 Feb 2021
Posts: 17

View user's profile Send private message

Update
PostPosted: Wed Feb 24, 2021 3:58 pm     Reply with quote

I have been looking into the ZCD module. I don't think it will work for my application. Primarily due to I do not want to tie my microchip and control circuitry to Ac mains. I am working with an optically isolated 0-5v dc square wave. Any thoughts as to why the original code only fires every 10th or so (inconsistent) cycles.
PCM programmer



Joined: 06 Sep 2003
Posts: 21420

View user's profile Send private message

PostPosted: Wed Feb 24, 2021 5:23 pm     Reply with quote

You've selected INT1 as the interrupt for PIN_B0. Then you setup your
isr for INT_EXT. That's not correct. INT0 is the correct interrupt for
INT_EXT. Fix this line:
Quote:
#PIN_SELECT INT1=PIN_B0
Ttelmah



Joined: 11 Mar 2010
Posts: 17110

View user's profile Send private message

PostPosted: Thu Feb 25, 2021 3:45 am     Reply with quote

This is one where it is easy to get confused. Unfortunately, CCS are still
sticking with the 'old' interrupt names (EXT, EXT1 & EXT2), rather than
the names now used in the data sheet for this chip (INT0 INT1 & INT2).
Makes this mistake very easy to make...
matthewmilford



Joined: 09 Feb 2021
Posts: 17

View user's profile Send private message

Update 2
PostPosted: Thu Feb 25, 2021 10:15 am     Reply with quote

PCM I have corrected that issue. That still does not seem to solve the issue.

To clarify this is the new code with your correction applied.
Code:

#include <18f26k42.H>

#include <stdio.h>
#define triac_gate    PIN_B4   
#PIN_SELECT INT0=PIN_B0
#use delay(clock = 4MHz)
int ZC = 0;
//******************************************************************
#INT_EXT            // external interrupt ISR
void EXT_ISR()
{
   //disable_interrupts(GLOBAL);
   ZC = 1;
   //clear_interrupt(INT_EXT);
   //enable_interrupts(GLOBAL);
   
}
//******************************************************************

void main()
{
  //ext_int_edge(H_TO_L);   //catch only high to low
  output_low(triac_gate);
  output_drive(triac_gate);
  clear_interrupt(INT_EXT);          // clear external interrupt flag bit
  enable_interrupts(INT_EXT);        // enable external interrupt
  enable_interrupts(GLOBAL);         // enable global interrupts
  while(TRUE)
  {
        if(ZC == 1)
        {
            ZC = 0;
            delay_ms(4);
            output_high(triac_gate);
            delay_us(5);
            output_low(triac_gate);   
        }
  }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21420

View user's profile Send private message

PostPosted: Thu Feb 25, 2021 11:35 am     Reply with quote

I was able to make it work with my setup.

I used the Microchip small pin count board with a 16F690 to create a
60 Hz, 0 to 5v, squarewave signal. I jumpered ground, plus the 60
Hz signal over to the main board. Here is the 60Hz program:
Code:
#include <16F690.h>
#fuses INTRC_IO
#use delay(clock=8M)

//======================
void main(void)     
{

while(TRUE)           
  {
   output_toggle(PIN_C0);
   delay_us(8333);
  }

}

For the main board, I don't have your PIC, so I used an 18F46K22.
I then took your latest posted program and commented out two lines near
the top, as shown below. I don't need stdio.h (it clutters up the .LST file)
and 18F46K22 doesn't use #pin_select.

Anyway, it works. I sync'ed on the incoming 60 Hz signal on channel 1.
On channel 2, I can see thin positive pulse slivers occuring on the rising
edges of the ch. 1 signal. As far as I can tell, it's working just fine.
Code:

#include <18F46K22.h>
//#include <stdio.h>
#define triac_gate    PIN_B4   
//#PIN_SELECT INT0=PIN_B0
#use delay(clock = 4MHz)
int ZC = 0;
//*********************************************************
#INT_EXT            // external interrupt ISR
void EXT_ISR()
{
   //disable_interrupts(GLOBAL);
   ZC = 1;
   //clear_interrupt(INT_EXT);
   //enable_interrupts(GLOBAL);
   
}
//*********************************************************
void main()
{
  //ext_int_edge(H_TO_L);   //catch only high to low
  output_low(triac_gate);
  output_drive(triac_gate);
  clear_interrupt(INT_EXT);          // clear external interrupt flag bit
  enable_interrupts(INT_EXT);        // enable external interrupt
  enable_interrupts(GLOBAL);         // enable global interrupts
  while(TRUE)
  {
        if(ZC == 1)
        {
            ZC = 0;
            delay_ms(4);
            output_high(triac_gate);
            delay_us(5);
            output_low(triac_gate);   
        }
  }
}
 
 
 
gaugeguy



Joined: 05 Apr 2011
Posts: 181

View user's profile Send private message

PostPosted: Thu Feb 25, 2021 12:09 pm     Reply with quote

Add a pin toggle before your while(TRUE) loop so you can check to see if the processor is resetting.
Maybe also do the test with the bulb disconnected to see if it is a noise reset.
Make sure you definitely have the WDT disabled so it does not reset the processor.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
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


Powered by phpBB © 2001, 2005 phpBB Group