|
|
View previous topic :: View next topic |
Author |
Message |
camleot23
Joined: 16 Aug 2019 Posts: 52
|
dsPIC33EP Input Capture |
Posted: Mon Aug 26, 2019 1:40 am |
|
|
Hello All,
I want to set up a simple input capture program. I use IC1 module which is PIN_B2, after I did my research I was able to write this code:
Code: | #include <./33EP64MC206.h>
#use delay(internal=28MHz)
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES FRC
#FUSES NOOSCIO
#use rs232(baud=9600,parity=N,stop=1,xmit=PIN_G7 ,rcv=PIN_G6)
#use fast_io(b)
#INT_IC1
void inputcapture_interrupt()
{
printf("input captured");
}
int main()
{
setup_oscillator(OSC_INTERNAL,28000000);
setup_capture(PIN_B2, CAPTURE_RE | INTERRUPT_EVERY_CAPTURE);
set_tris_b(0x04);
enable_interrupts(INT_IC1);
enable_interrupts(GLOBAL);
while(1)
{
delay_ms(100);
}
} |
I made PIN_B2 as PULL-DOWN, when I push button PIN_B2 will be high, and I thought when this happened, pic will capture this HIGH and it would enter the interrupt function. But it didn't happen. I don't get a message on my serial terminal. What is my wrong in my code? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Aug 26, 2019 2:30 am |
|
|
You're missing the #pin_select for IC1. |
|
|
camleot23
Joined: 16 Aug 2019 Posts: 52
|
|
Posted: Mon Aug 26, 2019 2:32 am |
|
|
Okay, I solved my problem. The problem is that:
setup_capture(PIN_B2, CAPTURE_RE | INTERRUPT_EVERY_CAPTURE);
writing PIN_B2 here. I use IC1 module and I need to write 1 instead of PIN_B2.
Actually I wrote 1 here at first before PIN_B2 and compiler gave me an error "invalid pin" like this and I changed it to PIN_B2. So, I continued my research on internet and I found this thread:
https://ccsinfo.com/forum/viewtopic.php?p=178309
It solved my problem.
I added this line to the top:
Code: | #PIN_SELECT ic1=PIN_B2 |
Here is my last code that captures a signal and makes an interrupt:
Code: | #include <./33EP64MC206.h>
#use delay(internal=28MHz)
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES FRC
#FUSES NOOSCIO
#use rs232(baud=9600,parity=N,stop=1,xmit=PIN_G7 ,rcv=PIN_G6)
#PIN_SELECT ic1=PIN_B2
#INT_IC1
void inputcapture_interrupt()
{
printf("input captured");
}
void main()
{
setup_oscillator(OSC_INTERNAL,28000000);
setup_capture(1, CAPTURE_RE | INTERRUPT_EVERY_CAPTURE);
enable_interrupts(INT_IC1);
enable_interrupts(GLOBAL);
while(1)
{
delay_ms(100);
}
} |
Last edited by camleot23 on Mon Aug 26, 2019 3:05 am; edited 2 times in total |
|
|
camleot23
Joined: 16 Aug 2019 Posts: 52
|
|
Posted: Mon Aug 26, 2019 2:33 am |
|
|
Thank you PCM Programmer I realized that, thank you so much:) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Mon Aug 26, 2019 2:39 am |
|
|
That was funny, started typing to point out that IC1 is not PIN_B2, and
needs a PIN_SELECT, and saw that PCM 'beat me to it'.
Actually what you have posted as 'fixed' is wrong. The capture needs to be setup as:
setup_capture(1, CAPTURE_RE | INTERRUPT_EVERY_CAPTURE);
The reason this gave an invalid pin when you tried to use it originally was
because the pin for IC1 was not setup....
Also your 'main' declaration is wrong. It should be 'void', not 'int'.
In CCS, there is no 'operating system' for a 'main' routine to return anything
'to', so the main routine should always be 'void' and return nothing... |
|
|
camleot23
Joined: 16 Aug 2019 Posts: 52
|
|
Posted: Mon Aug 26, 2019 3:05 am |
|
|
Yes Ttelmah, you are right I forgot to change PIN_B2 as 1. Now I edited thank you for your reply too And for "main" point, you are also right too I forgot to change it. Thank you.
Note for other users: The code that I shared above (second one) is corrected/edited according to Ttelmah and PCM Programmer. It is working. |
|
|
camleot23
Joined: 16 Aug 2019 Posts: 52
|
|
Posted: Tue Aug 27, 2019 8:59 am |
|
|
I encounter with a problem. When my input stays high, my interrupt is working. Why? I set my config as Rising Edge. What may be the problem?
Actually, It is strange that when I load this code to pic, I'm having the problem:
Code: | #include <./33EP64MC206.h>
#use delay(internal=42MHz)
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES FRC //internal oscillator icin gerekli
#FUSES NOOSCIO
#use i2c(master,I2C1,STREAM=lcd_kanal)
#use rs232(baud=9600,parity=N,stop=1,xmit=PIN_G7 ,rcv=PIN_G6)
#PIN_SELECT ic1=PIN_B2 //Capture pin icin gereklii
#include <./i2C_Flex_LCD_with_BIGNUMBERS.h>
int i=0;
int counter=0;
#INT_IC1
void inputcapture_interrupt()
{
i++;
}
void main()
{
setup_oscillator(OSC_INTERNAL,42000000);
setup_capture(1, CAPTURE_RE);
enable_interrupts(INT_IC1);
enable_interrupts(GLOBAL);
lcd_init();
output_toggle(pin_b5);
delay_ms(100);
output_toggle(pin_b5);
delay_ms(100);
output_toggle(pin_b5);
delay_ms(100);
output_toggle(pin_b5);
delay_ms(100);
lcd_gotoxy(1,1);
lcd_putc("test V0.1");
delay_ms(1000);
lcd_putc("\f");
while(1)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"Yklnn plse %02d",i);
delay_ms(100);
}
}
|
But when I load like this, when my input stays high, it doesn't count. It waits to become low and when it becomes high again, it counts normally. However this time there are pulse losses that I miss to capture If I send pulses too fast.
Code: |
#include <./33EP64MC206.h>
#use delay(internal=42MHz)
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES FRC //internal oscillator icin gerekli
#FUSES NOOSCIO
#use i2c(master,I2C1,STREAM=lcd_kanal)
#use rs232(baud=9600,parity=N,stop=1,xmit=PIN_G7 ,rcv=PIN_G6)
#PIN_SELECT ic1=PIN_B2 //Capture pin icin gereklii
#include <./i2C_Flex_LCD_with_BIGNUMBERS.h>
int i=0;
int counter=0;
#INT_IC1
void inputcapture_interrupt()
{
i++;
lcd_gotoxy(1,1); ///MOVED HERE
printf(lcd_putc,"Yklnn plse %02d",i);//MOVED HERE
}
void main()
{
setup_oscillator(OSC_INTERNAL,42000000);
setup_capture(1, CAPTURE_RE);
enable_interrupts(INT_IC1);
enable_interrupts(GLOBAL);
lcd_init();
output_toggle(pin_b5);
delay_ms(100);
output_toggle(pin_b5);
delay_ms(100);
output_toggle(pin_b5);
delay_ms(100);
output_toggle(pin_b5);
delay_ms(100);
lcd_gotoxy(1,1);
lcd_putc("test V0.1");
delay_ms(1000);
lcd_putc("\f");
while(1)
{
delay_ms(100);
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Tue Aug 27, 2019 12:07 pm |
|
|
You must not have slow things like the print in your ISR.
Your original code is the better starting point except you probably
don't want to actually print unless the count has incfremented.
However the reason it hangs is because you are not reading the
capture buffer. This must be read in the ISR. If it is not read after
four captures the buffer will overflow. It'll also keep interrupting till
it is read. Because the signal is high, the capture gets set, and then
you are stuck. |
|
|
camleot23
Joined: 16 Aug 2019 Posts: 52
|
|
Posted: Tue Aug 27, 2019 11:42 pm |
|
|
Thank you Ttelmah. I understand you but how can I read capture buffer? What is its function? |
|
|
camleot23
Joined: 16 Aug 2019 Posts: 52
|
|
Posted: Tue Aug 27, 2019 11:47 pm |
|
|
I found these in device header file;
_bif unsigned int16 get_capture(unsigned int8 module);
_bif unsigned int16 get_capture(unsigned int8 module, int1 wait);
_bif unsigned int32 get_capture32(unsigned int8 module);
_bif unsigned int32 get_capture32(unsigned int8 module, int1 wait); |
|
|
camleot23
Joined: 16 Aug 2019 Posts: 52
|
|
Posted: Wed Aug 28, 2019 12:53 am |
|
|
Code: | int1 NewCapture = FALSE;
#INT_IC1
void inputcapture_interrupt()
{
if(!NewCapture)
{
FirstCapture = get_capture(1,FALSE); //Read first capture event.
NewCapture = TRUE;
}
else
{
dummy = get_capture(1,TRUE); //The TRUE causes the last capture event to
//be retrieved from the capture FIFO buffer
//and to clear out any previous captures.
//This is used to keep the FIFO buffer from
//overflowing while calculating and
//displaying the time. If an overflow
//occurs it will cause any further Input
//Capture interrupts form occuring.
}
i++;
}
void main()
{
setup_oscillator(OSC_INTERNAL,42000000);
setup_capture(1, CAPTURE_RE |INTERRUPT_EVERY_CAPTURE );
enable_interrupts(INT_IC1);
enable_interrupts(GLOBAL);
lcd_init();
output_toggle(pin_b5);
delay_ms(100);
output_toggle(pin_b5);
delay_ms(100);
output_toggle(pin_b5);
delay_ms(100);
output_toggle(pin_b5);
delay_ms(100);
lcd_gotoxy(1,1);
lcd_putc("test V0.1");
delay_ms(1000);
lcd_putc("\f");
while(1)
{
if(NewCapture)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"Yklnn plse %02d",i);
NewCapture = FALSE;
}
}
}
|
It is reading more pulses than I send. Also, I can generate the pulses with mechanically so I can adjust my pulses' width and can send them too fast or
too slow. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Wed Aug 28, 2019 1:32 am |
|
|
OK.
'reading more pulses than I send'. Are you sure?. If the pulses are from a
mechanical source then I have to say that _bounce_ is the most likely
problem. You need to look at cleaning up the input signal (small capacitor).
The CCP is both reliable, and very fast.
You are making it lose counts, by throwing events away, while waiting
for the slow LCD. Don't do this. Just record the 'i' value, and leave the
capture buffer filling. This should raise the speed supported enormously. |
|
|
camleot23
Joined: 16 Aug 2019 Posts: 52
|
|
Posted: Wed Aug 28, 2019 3:21 am |
|
|
What do you mean by the bounce ? You mean a square wave signal something like this. (Normally It should be straight)
..... .... __
........_|.. |
____|..... |_____ |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Aug 28, 2019 3:39 am |
|
|
Go to Google image search and search for this:
Quote: | switch contact bounce |
You'll see many scope diagrams showing switch bounce. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Wed Aug 28, 2019 4:57 am |
|
|
A very good little summary is at:
<http://rsrelectronics.com/t_bounc.htm>
You can debounce by simply not counting if the change from the last
capture value is less than some figure. However this will slow the maximum
rate that can be captured. |
|
|
|
|
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
|