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 CCS Technical Support

Interrupt on pin change PIC16F1825

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



Joined: 02 Jun 2009
Posts: 123
Location: The Netherlands

View user's profile Send private message

Interrupt on pin change PIC16F1825
PostPosted: Fri May 17, 2013 4:40 am     Reply with quote

I've made a program which must react on a positive pin change. When that happened it must add a value to a variable, but it adds two times the value to the variable. Is this a bug or is something not ok in my software?

Compiler version: 4.132

Code:

#include <16F1825.H>

#Fuses INTRC_IO,WDT_SW
#Fuses PUT,NOMCLR,PROTECT,CPD                                                   //CODEPROTECT EN DATAPROTECT AANGEZET
#Fuses BROWNOUT,NOCLKOUT,NOIESO
#Fuses NOFCMEN,NOWRT,PLL_SW
#Fuses NOSTVREN,NODEBUG,NOLVP
#Device ADC=8
#use delay(clock=8000000)                                                       //Fuses and delay are set, so int osc is set at 8Mhz.


#byte IOCAP = getenv("SFR:IOCAP")
#byte IOCAN = getenv("SFR:IOCAN")
#byte IOCAF = getenv("SFR:IOCAF")

#bit IOCAF2 = 0x393.2                                                           //Flag of interrupt on pin change RA2
#bit IOCAF3 = 0x393.3                                                           //Flag of interrupt on pin change RA3
#bit IOCAF4 = 0x393.4                                                           //Flag of interrupt on pin change RA4
#bit IOCAF5 = 0x393.5                                                           //Flag of interrupt on pin change RA5
#bit T1GSEL  = 285.3                                                            // dec adress  11D Hex

float Aantalkoek = 2;
float Totaalkoekin_kort = 0;
float Totaalkoekuit_kort = 0;


void main()
{
setup_oscillator(OSC_8MHZ|OSC_PLL_OFF);
setup_dac(DAC_OFF);
setup_vref(VREF_OFF);
setup_adc_ports(sAN2|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_16);                                                    // Built-in A/D setup function TAD is 2µSec                                                 
setup_WDT(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);                                      // 32,8 ms tot overflow (0.125us*4*256*256)
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);                                         //
setup_timer_2(T2_DIV_BY_1, 63, 1);                                              // Setup for  Hz 
setup_ccp1(CCP_OFF);                                                            // Configure CCP1
setup_ccp2(CCP_OFF);

T1GSEL = 0;                                                                     // T1_GATE_A4 instructie doet het niet vandaar handmatig.

IOCAP = 48;                                                                     // RA4 en RA5 positieve flank
IOCAN = 8;                                                                      // RA3 negatieve flank
IOCAF = 0;

while(1)
{

If(IOCAF4 == 1)                                            //Aantal koek in
{
Totaalkoekin_kort = Totaalkoekin_kort + 6;

delay_ms(10);

IOCAF4 = 0;                                                                      //Maak flag 0
}


If(IOCAF5 == 1)                                //Aantal pakken uit
{
Totaalkoekuit_kort = (Totaalkoekuit_kort + Aantalkoek);

output_toggle(control);

delay_ms(10);

IOCAF5 = 0;                                                                     //Maak flag 0
}

}


Has anyone a idea what is wrong?
temtronic



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

View user's profile Send private message

PostPosted: Fri May 17, 2013 4:54 am     Reply with quote

What is the input device? A mechanical switch, photocell,another PIC?
If mechanical, like a pushbutton, you have to deal with 'debounce'.All switch contacts will 'bounce'( make multiple contacts) giving several signals not just one.
Options to minimze include hardware like capacitors, resistors to 'clean up' the signal while in software you can add small delays( <50ms+-),oneshots,etc.
How you 'clean up' the signal is up to you.I use a combination of both.With hardware R-C filters for minor noise, window comparators for 'noisey' environments. Software delay filters based on seeing a 'scope picture of actual switch bounce.

I didn't check your code as I always start with hardware! You must have a good 'clean' signal before checking sw issues.



hth
jay
mvanvliet



Joined: 02 Jun 2009
Posts: 123
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri May 17, 2013 5:00 am     Reply with quote

I've tried different inputs, at first the input pin is filtered with a 4k7Ohm/120nF herewith there isn't any bouncing seen on the oscilloscope. And there is a delay of 10ms in the "if(IOCAFX == 1) function and I've also tried a microcontroller output, which isn't bouncing at all. All solutions doesn't solve the problem.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Fri May 17, 2013 7:00 am     Reply with quote

Quote:

adds two times the value to the variable.


how do you know this is true ??

there is no reporting visible in the code to say what is going on.

or is there "debuggery" going on here that you do not show??

or is this an ISIS simulation ??
mvanvliet



Joined: 02 Jun 2009
Posts: 123
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri May 17, 2013 7:12 am     Reply with quote

I put the variable through RS232 to my pc so I can see the value of the variable. I also have an toggle_pin function in the if function which changes 2 times with one pulse so the function is executed two times.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Fri May 17, 2013 7:37 am     Reply with quote

you do realize that there are TWO "int on change" INTS --
generated for each SINGLE press and release combo of the input pins --
even if these are clean, perfectly debounced buttons - right ??

ALSO - since you are NOT using #fastio , it is possible the compiler is being TRIS confused by your INT register state change code, which seem very
non- standard , and "non CCS" to me

you would do better to simply sense the state of the RA pins and add your own timer() based debounce management IMHO

lastly the omitted RS232 code may have an impact on this -
but since you are not showing ALL your code , how can i tell??

are you hiding MORE code yet in addition to your RS232 reporting??
all code has associated execution time you know- the where and when is everything ........
mvanvliet



Joined: 02 Jun 2009
Posts: 123
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed May 22, 2013 5:55 am     Reply with quote

This is all the code:

Code:

#include <16F1825.H>

#Fuses INTRC_IO,WDT_SW
#Fuses PUT,NOMCLR,PROTECT,CPD                                                   //CODEPROTECT EN DATAPROTECT AANGEZET
#Fuses BROWNOUT,NOCLKOUT,NOIESO
#Fuses NOFCMEN,NOWRT,PLL_SW
#Fuses NOSTVREN,NODEBUG,NOLVP
#Device ADC=8
#use delay(clock=8000000)                                                       //Fuses and delay are set, so int osc is set at 8Mhz.
 
#use rs232(baud=9600, xmit=PIN_C5, stream=COM_B)                         //Normal RS232
#use rs232(baud=9600, uart2, stream=COM_A)
//#use fast_io(C)

#define ACP_DATA        PIN_A0         //AN0 ICP_data / TX
#define ICP_CLOCK       PIN_A1           //AN1 ICP_clk  / RX   
//#define MODE            PIN_A2         //AN2 5V spanning       ADC
#define MCLR            PIN_A3         //    MCLR actief
//#define PULS_IN       PIN_A4         //AN3 Charger on
//#define PULS_OUT      PIN_A5         //    Debug
#define SCK             PIN_C0         //AN4 Uitgang voor uitlezen uitgangsspanning en uitgangsstroom
#define SDI             PIN_C1         //AN5 Battery voltage    ADC
#define SDO             PIN_C2         //AN6 Battery on         
#define CONTROL         PIN_C3         //AN7 Battery current 2,5V +/- current
//#define          PIN_C4         //    Control Pin
//#define TX            PIN_C5         //    PWM OUTPUT

#bit TXCKSEL = 285.2                                                            // TX poortje 
#bit T1GSEL  = 285.3                                                            // dec adress  11D Hex
#bit TMR0IF  =  11.2                                                            // TMR0 counter overflow
#bit TMR1IF  =  17.0                                                            // TMR1 counter overflow

#byte IOCAP = getenv("SFR:IOCAP")
#byte IOCAN = getenv("SFR:IOCAN")
#byte IOCAF = getenv("SFR:IOCAF")

#bit IOCAF2 = 0x393.2                                                           //Flag of interrupt on pin change RA2
#bit IOCAF3 = 0x393.3                                                           //Flag of interrupt on pin change RA3
#bit IOCAF4 = 0x393.4                                                           //Flag of interrupt on pin change RA4
#bit IOCAF5 = 0x393.5                                                           //Flag of interrupt on pin change RA5
#bit TO = getenv("BIT:TO")

#include <string.h>

int1  RS232_send = 0;
int1  Minuut_teller_rond = 0;
int1  Half_uur_teller_rond = 0;
int1  Puls_in_read = 0;
int1  Puls_uit_read = 0;

int   mode = 0;
int   MS100 = 0;
int   checksum = 0;
int   i = 0;
int   minuut_teller_usb = 0;
int   minuut_teller_array = 0;
int   minuut_teller_array_kopie = 0;
int   teller = 0;
int   teller_stop = 0;
int   Aantalkoek_USB = 0;

int16 Verlies_array[52];   //51*5/256 zou goed zijn
int16 minute = 0;
int16 size = 0;
int16 Verlies_ber = 0;

float Totaal = 0;
float Aantalkoek = 0;
float Totaalkoekin_kort = 0;
float Totaalkoekuit_kort = 0;
float Verlies_kort = 0;
float Verlies_half_uur = 0;
float Verlies_uur = 0;

char  pretype[] = "<L1><PA><FA><MA><WC><FA>";
char  color[5];
char  color2[5];
char  sVerlies_kort[10];
char  sVerlies_half_uur[10];
char  sVerlies_uur[10];
char  type[10];
char  totaltype[51];

char sData[20];
float sKoekin[20];
float sKoekuit[20];
 

//////////////////////////////// MAIN LOOP /////////////////////////////////////
/*
<ID00>   = ID
<L1>     = Line
<PA>     = Page
<FE>     = Scroll left
<MA>     = display time
<WC>     = speed
<FE>     = Scroll left

*/

float half_uur()
{
      Totaal = 0;
     
      if(minuut_teller_array >= 25)
      {
      Teller_stop = minuut_teller_array - 25;
     
      for(teller = teller_stop; teller <= minuut_teller_array; teller++)
         {       
         Totaal = Totaal + verlies_array[teller];                               //calculate the total of the numbers in the array
         
         }
      }
      else
      {
      Teller_stop = 51 -(25 - minuut_teller_array);
     
      for(teller = 0; teller <= minuut_teller_array; teller++)
         {       
         Totaal = Totaal + verlies_array[teller];                               //calculate the total of the numbers in the array
         }
         
      for(teller = teller_stop; teller <= 51; teller++)
         {       
         Totaal = Totaal + verlies_array[teller];                               //calculate the total of the numbers in the array
         }
      }   
     
      Verlies_half_uur = Totaal/260;
      return Verlies_half_uur;
}




void main()
{
setup_oscillator(OSC_8MHZ|OSC_PLL_OFF);
setup_dac(DAC_OFF);
setup_vref(VREF_OFF);
setup_adc_ports(sAN2|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_16);                                                    // Built-in A/D setup function TAD is 2µSec                                                 
setup_WDT(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);                                      // 32,8 ms tot overflow (0.125us*4*256*256)
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);                                         //
setup_timer_2(T2_DIV_BY_1, 63, 1);                                              // Setup for  Hz 
setup_ccp1(CCP_OFF);                                                            // Configure CCP1
setup_ccp2(CCP_OFF);
//set_tris_c(0x1A);

T1GSEL = 0;                                                                     // T1_GATE_A4 instructie doet het niet vandaar handmatig.
//TXCKSEL = 1;                                                                    // TX poortje selecteren doet het niet vandaar handmatig.

IOCAP = 48;                                                                     // RA4 en RA5 positieve flank
IOCAN = 8;                                                                      // RA3 negatieve flank
IOCAF = 0;


set_adc_channel(2);                                                             //Check modeswitch

delay_ms(5000);

for(teller = 0; teller <= 51; teller++)
{
verlies_array[teller] = 0;                                                //put zeros in array
}

while(1)
{

//output_toggle(control);

//////////////////////////////// 1 sec counter //////////////////////////////////
if    (TMR0IF == 1)
      {                                                                         //33ms counter.
      TMR0IF=0;
      MS100++;
      MINUTE++;
      }

if    (MS100 >= 60)                                                             
      {
      MS100 = 0;
      RS232_send  = 1;
      }
         
/////////Selectie////////
set_adc_channel(2);                                                             //Check modeswitch
delay_us(20);
MODE = read_ADC();

if(MODE < 32) //Zou ideaal 0 zijn
      {
      //1e
      type = "<CJ> 8P";
      Aantalkoek = 4;
      Aantalkoek_USB = 8;
      }
else if(MODE < 96) //zou ideaal 64 zijn
      {
      //2e
      type = "<CJ> 6P";
      Aantalkoek = 3;
      Aantalkoek_USB = 6;
      }
else if(MODE < 143) //zou ideaal 128 zijn
      {
      type = "<CJ> 4P";
      Aantalkoek = 2;
      Aantalkoek_USB = 4;
      }
else if(MODE < 175)     //zou ideaal 159 zijn
      {
      //3e
      type = "<CJ> 3P";
      Aantalkoek = 1.5;
      Aantalkoek_USB = 3;
      }
else if(MODE < 224)  //zou ideaal 191 zijn
      {
      //4e
      type = "<CJ> 2P";
      Aantalkoek = 1;
      Aantalkoek_USB = 2;
      }
else        //zou ideaal 255 zijn
      {
      //5e
      type = "<CJ> 1P";
      Aantalkoek = 0.5;
      Aantalkoek_USB = 1;
      }
     

//Berekening

If(IOCAF4 == 1)                                            //Aantal koek in
{
Totaalkoekin_kort = Totaalkoekin_kort + 6;

delay_ms(10);

IOCAF4 = 0;                                                                      //Maak flag 0
}


If(IOCAF5 == 1)                                //Aantal pakken uit
{
Totaalkoekuit_kort = (Totaalkoekuit_kort + Aantalkoek);

output_toggle(control);

delay_ms(10);

IOCAF5 = 0;                                                                     //Maak flag 0
}


//Reset
If(IOCAF3 == 1)
{
delay_ms(10);
Totaalkoekin_kort = 0;
Totaalkoekuit_kort = 0;
Verlies_kort = 0;

IOCAF3 = 0;
}

if    (MINUTE >= 1764) //1764) //is 1 minuut
      {
         
      Minuut_teller_usb++;
     
      if(minuut_teller_array <= 49)
         {
         Minuut_teller_array++;
         }
      else
         {
         minuut_teller_array = 0;
         minuut_teller_rond = 1;
         }
     
      if(minuut_teller_array >= 26 && Half_uur_teller_rond == 0)
         {
         Half_uur_teller_rond = 1;
         }
     
      MINUTE = 0;
     
      Verlies_ber = Verlies_kort * 10;                                          //convert float to int16 without losing much resolution

      Verlies_array[Minuut_teller_array] = Verlies_ber;                         //put the int16 into an array

      Totaal = 0;

      if(minuut_teller_rond == 0)
      {
         for(teller = 0; teller <= minuut_teller_array; teller++)
         {
         Totaal = Totaal + verlies_array[teller];                               //calculate the total of the numbers in the array
         }
         
         Verlies_uur = (Totaal/minuut_teller_array)/10;
      }
      else
      {
     
         for(teller = 0; teller <= 51; teller++)
         {
         Totaal = Totaal + verlies_array[teller];                               //calculate the total of the numbers in the array
         }
         
         Verlies_uur = Totaal/510;                                              //Totaal / 10 * 52
      }
     
      if(Half_uur_teller_rond == 1)
      {
      half_uur();
      }
      else
         Verlies_half_uur = Verlies_uur;
         
      }     



if(Totaalkoekuit_kort != 0)                                                     //Als er geen koeken uitgekomen zijn dan is verlies 0%
{
//Verlies_kort
Verlies_kort = 100 - (Totaalkoekuit_kort / Totaalkoekin_kort * 100);
}


 
/////////Memory-stick//////
if(minuut_teller_usb >= 30) //nu iedere minuut, straks elk half uur
   {
   TXCKSEL = 1;
     
   sprintf(sData,"%1.0u,", Aantalkoek_USB);
   //sprintf(sKoekin, "%g,", Totaalkoekin_kort);
   //strcat(sData, sKoekin);   
   //sprintf(sKoekuit, "%g,", Totaalkoekuit_kort);
   //strcat(sData, sKoekuit);
   sprintf(sVerlies_uur, "%3.1g%%\r\n", Verlies_uur);
   strcat(sData, sVerlies_uur);     
   
   size = strlen(sData);
   
   // create file and open it
   fprintf(COM_A, "OPW Data.txt\r");
   // write to file
   fprintf(COM_A, "WRF ");
   fputc(0x00, COM_A); // number of bytes of data
   fputc(0x00, COM_A);
   fputc(0x00, COM_A);
   fputc(size, COM_A);
   fputc('\r', COM_A);
   fprintf(COM_A, "%s", sData);
   // close the file
   fprintf(COM_A, "CLF Data.txt\r");
   
   delay_ms(10);
   
   TXCKSEL = 0;
   minuut_teller_usb = 0;
   }
   
/////////RS232/////////////
if(RS232_send == 1)
{

if(Verlies_kort < 10)
   {
   sprintf(sVerlies_kort, " %3.1g%%", Verlies_kort);
   }
else
   sprintf(sVerlies_kort, "%3.1g%%", Verlies_kort);

//Verlies_lang
if(Verlies_half_uur < 10)
   {
   sprintf(sVerlies_half_uur, " %3.1g%%", Verlies_half_uur);
   }
else
   {
   sprintf(sVerlies_half_uur, "%3.1g%%", Verlies_half_uur);
   }
     
if(Verlies_kort <= 3)
      {
      strcopy(color,"<CE>");
      }
else
      {
      strcopy(color,"<CC>");
      }

if(Verlies_half_uur <= 3)
{
strcopy(color2,"<CE>");
}
else
{
strcopy(color2,"<CC>");
}

/////////RS232 String////////////////////
checksum = 0;

fprintf(COM_B, "%3.0g ", totaalkoekin_kort);
fprintf(COM_B, "%3.0g\r\n", totaalkoekuit_kort);


/*
strcpy(totaltype, pretype);                                                     //totaltype now contains a copy of pretype
strcat(totaltype, color2);                                                      //add color to string
strcat(totaltype, sVerlies_half_uur);                                           //add sVerlies_half_uur to string
strcat(totaltype, type);
strcat(totaltype, color);                                                       //it is now the two strings one after the other
strcat(totaltype, sVerlies_kort);                                               //add sVerlies_kort to string


for(i = 0; i <= strlen(totaltype); i++)
   {
   checksum = checksum ^ totaltype[i];
   }

fprintf(COM_B, "<ID00>");
fprintf(COM_B, "%s",totaltype);
fprintf(COM_B, "%02X",checksum);
fprintf(COM_B, "<E>");
*/
RS232_send = 0;
}

}
}


What do you mean with this:

Quote:

you do realize that there are TWO "int on change" INTS --
generated for each SINGLE press and release combo of the input pins --
even if these are clean, perfectly debounced buttons - right ??
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed May 22, 2013 6:57 am     Reply with quote

have your read the DATASHEET?

even though you seem to not have turned ON the actual #int handler -
if you are depending on a poll of the INT pin change, then perhaps you might search for this:

interrupt-on-change

and then consider the flag
IOCIF
and how it works ??
In fact a careful reading of the entire interrupt section of the datasheet
might improve your perspective considerably on your issue
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed May 22, 2013 3:54 pm     Reply with quote

Just a few small things I noted:
Code:
#use rs232(baud=9600, uart2, stream=COM_A)
The PIC16F1825 has only 1 uart so change 'uart2' to 'uart1'. I tested the generated code and it is the same.
It's sloppy that the compiler doesn't create an error on this wrong parameter.

Code:
char  type[10];
and
Code:
type = "<CJ> 8P";
Here type is only assigned a pointer to the string. If you do it like that, then the declaration of type can/should be:
Code:
char *type;
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