|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 03, 2008 12:59 pm |
|
|
To discover what the compiler is doing, make a little test program which
concentrates only on one thing -- in this case, passing a CCS pin constant
to a function.
Then look at the .LST file to see the ASM code created by the compiler.
Look at the massive amount of code that is required to an turn a CCS pin
constant into a pin i/o operation, when it's passed as a variable.
Because the one wire code depends upon accurate delays, the insertion
of massive hidden delays such as this will ruin the code operation.
Code: | .................... void onewire_write(int16 pin_dq, int data)
.................... {
.................... int count;
....................
.................... for(count=0; count<8; ++count)
00072: CLRF 09
00074: MOVF 09,W
00076: SUBLW 07
00078: BNC 00FE
.................... {
.................... output_low(pin_dq);
0007A: MOVFF 06,0A
0007E: CLRF 0B
00080: MOVLW 0F
00082: MOVWF 0D
00084: MOVLW 89
00086: MOVWF 0C
00088: RCALL 0004
0008A: MOVFF 06,0A
0008E: CLRF 0B
00090: MOVLW 0F
00092: MOVWF 0D
00094: MOVLW 92
00096: MOVWF 0C
00098: RCALL 0004
.................... delay_us( 2 );
0009A: BRA 009C
0009C: BRA 009E
0009E: NOP
// Here's the routine at 0004, that is called by the code above.
00004: MOVF 0A,W
00006: ANDLW 07
00008: MOVWF 00
0000A: RRCF 0A,W
0000C: MOVWF 01
0000E: RRCF 01,F
00010: RRCF 01,F
00012: MOVLW 1F
00014: ANDWF 01,F
00016: MOVF 01,W
00018: ADDWF 0C,W
0001A: MOVWF FE9
0001C: MOVLW 00
0001E: ADDWFC 0D,W
00020: MOVWF FEA
00022: CLRF 01
00024: INCF 01,F
00026: INCF 00,F
00028: BRA 002C
0002A: RLCF 01,F
0002C: DECFSZ 00,F
0002E: BRA 002A
00030: MOVF 0B,F
00032: BZ 003A
00034: MOVF 01,W
00036: IORWF FEF,F
00038: BRA 0040
0003A: COMF 01,F
0003C: MOVF 01,W
0003E: ANDWF FEF,F
00040: RETLW 00
00042: MOVF 0A,W
00044: ANDLW 07
00046: MOVWF 00
00048: RRCF 0A,W
0004A: MOVWF 01
0004C: RRCF 01,F
0004E: RRCF 01,F
00050: MOVLW 1F
00052: ANDWF 01,F
00054: MOVF 01,W
00056: ADDWF 0B,W
00058: MOVWF FE9
0005A: MOVLW 00
0005C: ADDWFC 0C,W
0005E: MOVWF FEA
00060: MOVFF FEF,01
00064: INCF 00,F
00066: BRA 006A
00068: RRCF 01,F
0006A: DECFSZ 00,F
0006C: BRA 0068
0006E: GOTO 00F4 (RETURN)
|
Code: | #include <18F4620.H>
#fuses HS,NOWDT,NOPROTECT, PUT, BROWNOUT, NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
void onewire_write(int16 pin_dq, int data)
{
int count;
for(count=0; count<8; ++count)
{
output_low(pin_dq);
delay_us( 2 );
output_bit(pin_dq, shift_right(&data,1,0));
delay_us( 60 );
output_float(pin_dq);
delay_us( 2 );
}
}
//=========================
void main()
{
onewire_write(PIN_B0, 0x55);
while(1);
} |
|
|
|
jgschmidt
Joined: 03 Dec 2008 Posts: 184 Location: Gresham, OR USA
|
|
Posted: Wed Dec 03, 2008 3:43 pm |
|
|
Thanks for the feedback -I'll try something more efficient. |
|
|
MarcosAmbrose
Joined: 25 Sep 2006 Posts: 38 Location: Adelaide, Australia
|
|
Posted: Wed Dec 03, 2008 3:44 pm |
|
|
Use a switch/case statement in your function.
Code: |
void MyFunction(int16 PinToUse)
{
switch(PinToUse)
{
case PIN_B0:
output_high(PIN_B0);
break;
case PIN_B1:
output_high(PIN_B1);
break;
}
}
|
Quote from CCS compiler help:
Code: |
The pin argument for built in functions like OUTPUT_HIGH need to be known at
compile time so the compiler knows the port and bit to generate the correct code.
If your application needs to use a few different pins not known at compile time consider:
switch(pin_to_use) {
case PIN_B3 : output_high(PIN_B3); break;
case PIN_B4 : output_high(PIN_B4); break;
case PIN_B5 : output_high(PIN_B5); break;
case PIN_A1 : output_high(PIN_A1); break;
}
If you need to use any pin on a port use:
#byte portb = 6
#byte portb_tris = 0x86 // **
portb_tris &= ~(1<<bit_to_use); // **
portb |= (1<<bit_to_use); // bit_to_use is 0-7
If you need to use any pin on any port use:
*(pin_to_use/8|0x80) &= ~(1<<(pin_to_use&7)); // **
*(pin_to_use/8) |= (1<<(pin_to_use&7));
In all cases pin_to_use is the normal PIN_A0... defines.
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 03, 2008 3:50 pm |
|
|
Quote: |
The pin argument for built in functions like OUTPUT_HIGH need to be
known at compile time. |
That's true for version 3. Version 4 allows variable parameters for the
i/o functions. The switch-case method will generate much more compact
code. However, the .LST file should still be checked to verify if the
overhead is sufficiently small to work with the one-wire code's timing
requirements. |
|
|
MarcosAmbrose
Joined: 25 Sep 2006 Posts: 38 Location: Adelaide, Australia
|
|
Posted: Wed Dec 03, 2008 3:57 pm |
|
|
PCM programmer wrote: | That's true for version 3. Version 4 allows variable parameters for the i/o functions. |
Bugga - Now I have a excuse to upgrade my compiler |
|
|
crystal_lattice
Joined: 13 Jun 2006 Posts: 164
|
|
Posted: Thu Dec 04, 2008 2:47 am |
|
|
The sad irony is that Dallas has spent lots of money to produce a device with a unique 64bit serial number and various other functions/features to enable the master to communicate with a single device amongst hundreds of others on the same network and yet people want to use seperate io pins to accomplish the same task...
I understand that there are some exceptions to the rule, but why don't you use the search and match rom functions to communicate with the correct device? It is really not that hard to implement. |
|
|
Ttelmah Guest
|
|
Posted: Thu Dec 04, 2008 4:05 am |
|
|
A quick search here, will find posted code, to give input/output on a variable pin, using V3 compilers.
Best Wishes |
|
|
|
|
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
|