View previous topic :: View next topic |
Author |
Message |
respected
Joined: 16 May 2006 Posts: 95
|
Changeable PIN name |
Posted: Thu Nov 23, 2017 6:28 am |
|
|
Hi;
i want to write driver code. But something is wrong.
output_bit(pin, shift_right(&data,1,0));
This line has problem. Other lines are good. There is no problem.
When i change pin as below, it is OK.
Where is problem?
output_bit(PIN_A0, shift_right(&data,1,0));
Code: | void onewire_reset(int16 pin)
{
output_low(pin);
delay_us( 500 );
output_float(pin);
delay_us( 500 );
output_float(pin);
}
void onewire_write(int data,int16 pin)
{
int count;
for (count=0; count<8; ++count)
{
output_low(pin);
delay_us( 2 );
output_bit(pin, shift_right(&data,1,0));
delay_us( 60 );
output_float(pin);
delay_us( 2 );
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Thu Nov 23, 2017 7:25 am |
|
|
The code will compile as posted. Nothing wrong from that point of view. But it hasn't got a hope of working. The problem is _time_. Onewire is a timing critical bus. Using a variable as a pin name, massively slows down the I/O function. A bit set or clear on a pre-defined pin, is a single assembly instruction. One using a variable for the on/off immediately takes about four instruction times. The shift adds a few more, but using a variable for a pin name, takes it up to using several dozen instructions. It has to actually calculate the bit offset needed, and extract the register address for every single operation.
Being too generic here just destroys the possibility of getting the timings to work.
Have a look at this thread where the basics of changing the functions to support more than one pin were discussed:
<http://www.ccsinfo.com/forum/viewtopic.php?t=36953&highlight=onewire+variable+pin>
It is actually possible to code it in a different way, by extracting the register and bit number just once at the start of the loop. Only worth doing this though if you needed to access a lot of pins. The version shown in the thread above is much simpler. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Thu Nov 23, 2017 7:26 am |
|
|
How does the compiler KNOW which pin to operate on for these lines?
Quote: | Code: |
output_low(pin);
.
.
.
output_float(pin);
.
|
|
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Thu Nov 23, 2017 7:50 am |
|
|
'pin' is a variable he is passing to the function. This will work, but the time involved is far too long to be used for OneWire.... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Thu Nov 23, 2017 8:07 am |
|
|
As others have said Dallas One wire protocol is very 'time sensitive' !
The easy way, the 'cheat', the way I did it was to just copy the 'one wire' driver 4x ,renaming variables as required to control the 4 pcs of DS18B20s temperature devices for a greenhouse controller project.
While 'one wire' does allow 'daisy chaining' of multiple devcies on one bus,since the sensors were 'all over' the greenhouse , it was far simpler to have a 2pole connector for each and dedicate a pin per device.
Code space is not an issue, PICS have tons of memory these days.
Jay |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1911
|
|
Posted: Thu Nov 23, 2017 8:34 am |
|
|
temtronic wrote: | Code space is not an issue, PICS have tons of memory these days. |
You'll be lamenting your PIC's lack of resources if you write an NMEA 2000 compliant CAN driver. |
|
|
respected
Joined: 16 May 2006 Posts: 95
|
|
Posted: Thu Nov 23, 2017 8:35 am |
|
|
I don't want to use this. But I think the only way to do this
Code: | #define ONE_WIRE_PIN1 PIN_A0
#define ONE_WIRE_PIN2 PIN_E1
#define ONE_WIRE_PIN3 PIN_A5
#define ONE_WIRE_PIN4 PIN_B1
/////////////// 11111111111111111111111111111////////////////////////
void onewire_reset1()
{
output_low(ONE_WIRE_PIN1);
delay_us( 500 );
output_float(ONE_WIRE_PIN1);
delay_us( 500 );
output_float(ONE_WIRE_PIN1);
}
void onewire_reset2()
{
output_low(ONE_WIRE_PIN2);
delay_us( 500 );
output_float(ONE_WIRE_PIN2);
delay_us( 500 );
output_float(ONE_WIRE_PIN2);
}
.
.
.
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Thu Nov 23, 2017 8:43 am |
|
|
Yes, that's what I did several years ago. As I said it's a clean, simple and it works. It's also very easy to use 'find/replace' to make copies of the driver.
I used 'OW' for 'one wire' as I'm a terrible typist. |
|
|
|