View previous topic :: View next topic |
Author |
Message |
tesla80
Joined: 23 May 2007 Posts: 81
|
Changing pin in output_float() function |
Posted: Mon Jun 21, 2010 12:44 pm |
|
|
Hello there,
My question is so simple.
I have 8 pins, one of them is selected by a condition and they are used in the same functions. I don't wanna write several functions for every pin.
For example:
Code: | output_high(pinX);
output_float(pinX);
output_low(pinX); |
How to change the address of pinX to set/float/clear another pin?
Can I use an int16 in the output_low function?
Code: | #define PIN_C0 31760
#define PIN_C1 31761
#define PIN_C2 31762
#define PIN_C3 31763
void thefunction(int16 pinX)
{
output_high(pinX);
output_float(pinX);
output_low(pinX);
}
void main
{
thefunction(PIN_C0);
thefunction(PIN_C1);
thefunction(PIN_C2);
thefunction(PIN_C3);
}
|
Will this code above work properly?
Thanks in advance. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19384
|
|
Posted: Mon Jun 21, 2010 12:55 pm |
|
|
What compiler version?.
Old compiler, won't support the use of a variable.
Modern compilers will. This is described in the manual for compilers that accept a variable.
However, the code generated for a variable, will be much larger than for a fixed pin number.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 21, 2010 1:01 pm |
|
|
Download the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Look in the output_float() section:
Quote: |
output_float( )
Syntax: output_float (pin)
Parameters:
Pins are defined in the devices .h file. The actual value is a bit address.
For example, port a (byte 5 ) bit 3 would have a value of 5*8+3 or 43 .
This is defined as follows: #DEFINE PIN_A3 43.
The PIN could also be a variable to identify the pin. The variable must
have a value equal to one of the constants (like PIN_A1) to work
properly. Note that doing I/0 with a variable instead of a constant will
take much longer time.
|
|
|
![](templates/subSilver/images/spacer.gif) |
FFT
Joined: 07 Jul 2010 Posts: 92
|
|
Posted: Sun Jul 11, 2010 3:07 pm |
|
|
Hi,
I have the same problem.
I tried to make a ds18b20 code for 4 sensors which are connected to different pins of PIC. I did not want to write ds1820_read function for every pin.
I just removed the #define DQ PIN_E0 line and add int16 DQ = PIN_E0; line into the ds1820.c file. I change the pin address and call the ds1820_read function:
DQ = PIN_E0;
T1 = ds1820_read();
DQ = PIN_E1;
T2 = ds1820_read();
DQ = PIN_E2;
T3 = ds1820_read();
DQ = PIN_C3;
T4 = ds1820_read();
But I could not see any signal with oscilloscope on the DQ pin.
If I do this for only one sensor using #define DQ PIN_E0 (without int16 DQ), I can see signals and it works.
I use PIC18F4520 and ds1820 library is in this post: http://www.ccsinfo.com/forum/viewtopic.php?p=26593#26593
My compiler version is v4.107
How can we repair that?
Sincerely |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
![](templates/subSilver/images/spacer.gif) |
FFT
Joined: 07 Jul 2010 Posts: 92
|
|
Posted: Sun Jul 11, 2010 4:18 pm |
|
|
Thank you PCM programmer!
I understood it totally, but I really could not see any signal in the oscilloscope's display. The code for output_low(var) is huge but I should see any signal at least, right?
If I write 3 inline functions for output_high, low and float? is this could be solution?
For example:
Code: |
int8 DQ = 0;
#inline
void _output_low(int8 pinnr)
{
switch(pinnr)
{
case 0 : output_low(PIN_E0); break;
case 1 : output_low(PIN_E1); break;
case 2 : output_low(PIN_E2); break;
case 3 : output_low(PIN_C3); break;
}
} |
And I add only "_" to the real commands?
EDIT:
It works!!!!
I wrote 3 inline functions which have cases for every pin.
Code: | #inline
void _output_low(int8 n)
{
switch(n)
{
case 0 : output_low(PIN_E0); break;
case 1 : output_low(PIN_E1); break;
case 2 : output_low(PIN_E2); break;
case 3 : output_low(PIN_D3); break;
}
}
#inline
void _output_float(int8 n)
{
switch(n)
{
case 0 : output_float(PIN_E0); break;
case 1 : output_float(PIN_E1); break;
case 2 : output_float(PIN_E2); break;
case 3 : output_float(PIN_D3); break;
}
}
#inline
int1 _input(int8 n)
{
switch(n)
{
case 0 : return input(PIN_E0);
case 1 : return input(PIN_E1);
case 2 : return input(PIN_E2);
case 3 : return input(PIN_D3);
}
}
//EXAMPLE:
// Returns 0 for one wire device presence, 1 for none
int8 ow_reset(void)
{
int8 presence;
_output_low(DQ);
delay_us(488); // Min. 480uS
_output_float(DQ);
delay_us(72); // Takes 15 to 60uS for devices to respond
presence = _input(DQ);
delay_us(424); // Wait for end of timeslot
return(presence);
} |
I call it as below:
Code: | for(j=0;j<DS1820_COUNT;j++)
{
DQ = j;
T[j] = ds1820_read();
.
.
|
Br
Last edited by FFT on Sun Jul 11, 2010 4:43 pm; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 11, 2010 4:39 pm |
|
|
Look at the ASM code in the .LST file. You now have the added overhead
of the switch statement. You need to look at the existing code and the
ds18b20 data sheet, and study the timing and decide if your proposed
solution will work. |
|
![](templates/subSilver/images/spacer.gif) |
FFT
Joined: 07 Jul 2010 Posts: 92
|
|
Posted: Sun Jul 11, 2010 4:44 pm |
|
|
It works, I edited my last post ;) |
|
![](templates/subSilver/images/spacer.gif) |
|