|
|
View previous topic :: View next topic |
Author |
Message |
Mazza365 Guest
|
I2C and PORTB outpts.... how to change output_XXXX()?? |
Posted: Fri Apr 07, 2006 11:25 am |
|
|
Using a 16F88 with the I2C as a slave, I have found that using the CCS built in functions for outputting on other PORTB pins (output_high() and output_low()) they use the BSF/BCF instructions when modifying the TRISB register. Because these are Read-Modify-Write instructions, it corrupts the status of the I2C pins direction reigster bits when I2C communications are happening. The only way around this is to use the method shown in example 10-1 on page 92 of the current datasheet. (Read TRISB, modify it for the pin being changed to output, sets I2C pins back to outputs, write the new value back using MOVWF). This ensures the I2C direction bits are always left as 1's.
My question is: Is it possible to easily re-define the CCS functions output_high() and output_low() so that they use this method that does not interfere with the I2C direction bits?
Will I have to write my own code and redefine the functions using something like this:
#define output_high( my_output_high(
#define output_low( my_output_low(
Or is there some other way I can get the compiler to compile using different code that does not use BCF and BSF when changing TRISB (thats if CCS have written this different code already)?
Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Apr 07, 2006 11:51 am |
|
|
They already do it for Port C. Look at the generated code for
the test program shown below. They maintain a shadow register
for TRISC that is called "TRIS_C". They do all bit operations on it
and then copy it to the physical TRISC register. This eliminates
the Read-Modify-Write problems that might occur because of the
peripherals that override the TRIS register. You could do something
similar to this.
Code: |
.................... output_high(PIN_C0);
0016: MOVLW FF
0017: MOVWF @TRIS_C // Init the shadow reg to all inputs
0018: BCF @TRIS_C.0 // Clear bit 0 in shadow register
0019: MOVF @TRIS_C,W // Move shadow reg to W
001A: BSF STATUS.5 // Bank 1
001B: MOVWF TRISC // Move W to physical TRISC register
001C: BCF STATUS.5 // Bank 0
001D: BSF PORTC.0 // Set pin C0 to 1
....................
.................... output_low(PIN_C0);
001E: BCF @TRIS_C.0
001F: MOVF @TRIS_C,W
0020: BSF STATUS.5
0021: MOVWF TRISC
0022: BCF STATUS.5
0023: BCF PORTC.0
....................
.................... output_float(PIN_C0);
0024: BSF @TRIS_C.0
0025: MOVF @TRIS_C,W
0026: BSF STATUS.5
0027: MOVWF TRISC |
Code: | #include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//============================
void main()
{
output_high(PIN_C0);
output_low(PIN_C0);
output_float(PIN_C0);
while(1);
} |
------------
Edited to correct one of the comments in the list file code.
Last edited by PCM programmer on Thu Apr 20, 2006 11:57 am; edited 1 time in total |
|
|
Mazza365 Guest
|
|
Posted: Fri Apr 07, 2006 3:48 pm |
|
|
Great. Thats roughly what I have done now. The way i've written it looks far from pretty and is specific to my application, but it works!
I've also E-Mailed CCS to see if they will add a 'No RMW on TRISB'...now waiting to see what they say.
Thankyou! |
|
|
|
|
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
|