|
|
View previous topic :: View next topic |
Author |
Message |
mvanvliet
Joined: 02 Jun 2009 Posts: 123 Location: The Netherlands
|
Interrupt on pin change PIC16F1825 |
Posted: Fri May 17, 2013 4:40 am |
|
|
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
|
|
Posted: Fri May 17, 2013 4:54 am |
|
|
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
|
|
Posted: Fri May 17, 2013 5:00 am |
|
|
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
|
|
Posted: Fri May 17, 2013 7:00 am |
|
|
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
|
|
Posted: Fri May 17, 2013 7:12 am |
|
|
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
|
|
Posted: Fri May 17, 2013 7:37 am |
|
|
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
|
|
Posted: Wed May 22, 2013 5:55 am |
|
|
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
|
|
Posted: Wed May 22, 2013 6:57 am |
|
|
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
|
|
Posted: Wed May 22, 2013 3:54 pm |
|
|
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.
and Here type is only assigned a pointer to the string. If you do it like that, then the declaration of type can/should be: |
|
|
|
|
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
|