|
|
View previous topic :: View next topic |
Author |
Message |
hamid9543
Joined: 31 Jan 2013 Posts: 63
|
Measure pulse width with dsPIC |
Posted: Sat Feb 01, 2020 1:29 pm |
|
|
Hi
I want to measure pulse width (between 0 and 800 us) for 16 signal.
I used below method but pulse width is not correct.
I wrote code for 4 signals and then stop because result is not ok!
For example pulse width for 1st signal=35993 !!!
Can you help me to solve problem ?
Code: |
void main()
{
// setup_pll();
set_ticks(0);
while(true)
{
for (int i=0;i<=4;i++) {done[i]=0;}
set_ticks(0);
while (done[0]==0 || done[1]==0 || done[2]==0 || done[3]==0 || done[4]==0)
{
// tssp0
if(TSSP0==0 && Pre_Edge[0]==1 ) {start_time[0]=get_ticks();Pre_Edge[0]=0;} // Start time
else if(TSSP0==1 && Pre_Edge[0]==0 )
{
end_time[0]=get_ticks();
if(end_time[0]>start_time[0]) pulsewidth[0]=end_time[0]-start_time[0];
else pulsewidth[0]=65535-(start_time[0]-end_time[0]);
// if(pulsewidth[0]>800) pulsewidth[0]=0;
done[0]=1;}
// tssp1
if(TSSP1==0 && Pre_Edge[1]==1 ) {start_time[1]=get_ticks();Pre_Edge[1]=0;} // Start time
else if(TSSP1==1 && Pre_Edge[1]==0 )
{
end_time[1]=get_ticks();
if(end_time[1]>start_time[1]) pulsewidth[1]=end_time[1]-start_time[1];
else pulsewidth[1]=65535-(start_time[1]-end_time[1]);
done[1]=1;}
// tssp2
if(TSSP2==0 && Pre_Edge[2]==1 ) {start_time[2]=get_ticks();Pre_Edge[2]=0;} // Start time
else if(TSSP2==1 && Pre_Edge[2]==0 )
{
end_time[2]=get_ticks();
if(end_time[2]>start_time[1]) pulsewidth[2]=end_time[22]-start_time[1];
else pulsewidth[2]=65535-(start_time[2]-end_time[2]);
done[2]=1;}
// tssp3
if(TSSP3==0 && Pre_Edge[3]==1 ) {start_time[3]=get_ticks();Pre_Edge[3]=0;} // Start time
else if(TSSP3==1 && Pre_Edge[3]==0 )
{
end_time[3]=get_ticks();
if(end_time[3]>start_time[3]) pulsewidth[3]=end_time[3]-start_time[3];
else pulsewidth[3]=65535-(start_time[3]-end_time[3]);
done[3]=1;}
// tssp4
if(TSSP4==0 && Pre_Edge[4]==1 ) {start_time[4]=get_ticks();Pre_Edge[4]=0;} // Start time
else if(TSSP4==1 && Pre_Edge[4]==0 )
{
end_time[4]=get_ticks();
if(end_time[4]>start_time[4]) pulsewidth[4]=end_time[4]-start_time[4];
else pulsewidth[4]=65535-(start_time[4]-end_time[4]);
done[4]=1;}
}
printf("p0=%lu , p1=%lu ,p2=%lu , p3=%lu, p4=%lu , \r\n",pulsewidth[0],pulsewidth[1],pulsewidth[2],pulsewidth[3],pulsewidth[4]);
set_ticks(0);
}
}
|
Code: |
#Include<33ep128gp506.h>
#include <math.h>
#include<ConfigureClock.h>
/#pin_select
#pin_select U1TX=PIN_a4
#pin_select U1RX=PIN_c7 //no rx//just a useless pin
#use rs232(UART1,baud=9600)
#use i2c(SLAVE,I2C1,address=0xA2,stream=I2C_PORT1)
#use timer(timer=1,tick=4us,bits=16,isr)
//#use rs232(baud=38400,parity=N,xmit=PIN_a4,rcv=pin_c7,bits=8,stream=blt)
#define TSSP0 input(pin_b1)
#define TSSP1 input(pin_e15)
#define TSSP2 input(pin_a8)
#define TSSP3 input(pin_b7)
#define TSSP4 input(pin_b10)
unsigned int16 Pulsewidth[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},start_time[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned int16done[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, end_time[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19589
|
|
Posted: Sat Feb 01, 2020 2:01 pm |
|
|
Use the input capture peripherals.
You don't tell us which PIC, but most DsPIC's support separate input
capture on almost all pins.
The peripheral will record the value from the selected clock at the
moment the 'event' occurs. You can program it to just capture on rising
edges, falling edges or both. The values are buffered recording up to
four edge times each.
Far faster, and more accurate than your polling approach can ever be. |
|
|
hamid9543
Joined: 31 Jan 2013 Posts: 63
|
|
Posted: Sat Feb 01, 2020 9:33 pm |
|
|
Mcu: dsPIC33EP128GP506 and I need to measure 16 pulse width signals but
dsPIC33EP128GP506 only has 4 input capture. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19589
|
|
Posted: Sun Feb 02, 2020 1:09 am |
|
|
OK.
In fact the input capture is still the better way to go.
Now the reason your existing code has problems is it is not actually
detecting the 'edge' of the signal. You have to sit while the signal is low,
then read when it _changes_ to high, to read the rising edge. This is not
happening with what you are doing on the first edge, so it can actually
start counting at the wrong place in the signal....
However the key is that the input capture can be dynamically moved from
pin to pin, using PPS, so much simpler to setup the input capture from
a suitable clock, attach it to the first pin, take a reading, then attach to
the second, take a reading, etc. etc.. Now if you use two input capture
units, set one to capture the rising edge, and one the falling, then you
have two counts for the two edges. If you wait for one on the rising edge
detector, and then one on the falling detector, you then have the values
you need. |
|
|
hamid9543
Joined: 31 Jan 2013 Posts: 63
|
|
Posted: Sun Feb 02, 2020 4:43 am |
|
|
i write code in other form
pulse width=600 us
measure with micro controller is = 10677!!
tick time is 1.06 us then pulse width measure with micro=11317 us !!
Code: |
while(true)
{
if (TSSP0==0) {if(Pre_Edge[0]==1) edgeLH0++;}
if (edgeLH0==2){start_time[0]=get_ticks();Pre_Edge[0]=0;edgeLH0=0;led2_high;} // Start time
if(TSSP0==1){if(Pre_Edge[0]==0) edgeHL0++;}
if (edgeHL0==2)
{
end_time[0]=get_ticks();led2_high;
if(end_time[0]>start_time[0]) pulsewidth[0]=end_time[0]-start_time[0];
else pulsewidth[0]=65535-(start_time[0]-end_time[0]);
done[0]=1;edgeHL0=0; }
if(done[0]==1) {printf("p0=%lu ,p1=%lu ,p2=%lu \r\n",pulsewidth[0],start_time[0],end_time[0]); done[0]=0;set_ticks(0);}//set_ticks(0);}
else printf("doing..\r\n");
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19589
|
|
Posted: Sun Feb 02, 2020 4:59 am |
|
|
The way you have to do this (pseudo code), is:
Code: |
while(signal_is_high)
;
while (signal_is_low)
;
record_ticks
while(signal_is_high)
;
record_ticks;
|
You must do the double test at the start, or if the pulse is in a 'low' when
you start, you will record the starting edge at the wrong point.
Also (honestly), I don't trust the #use timer setup. Setup the timer to
simply free-run directly from the processor clock. Much more likely to
give accurate results. |
|
|
|
|
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
|