![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
Two I2C modules |
Posted: Sat Jun 15, 2019 5:45 pm |
|
|
Hi
I found by searching the forum how to assign pins for I2C modules.
Tried to implement for PIC16F1847 according to the data sheet:
Code: | #use STANDARD_IO( B )
#pin_select SCL1OUT = PIN_B4
#pin_select SCL1IN = PIN_B4
#pin_select SDA1OUT = PIN_B1
#pin_select SDA1IN = PIN_B1 |
The compiler returns 4 errors stating that:
Quote: | Invalid Pre-Processor directive Invalid Pin |
According to the data sheet SCL1 is RB4 and SDA1 is RB1
I am missing something?
Best wishes
Joe |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9177 Location: Greensville,Ontario
|
|
Posted: Sat Jun 15, 2019 7:02 pm |
|
|
...in a nutshell...
That PIC does NOT have 'pin selectable' pins, instead you use the APFCON register to select whhich pins the peripheral is assigned to.
Check out chapter 12 of the datasheet for how it works...as well as the 'device header file for the names CCS uses.
True 'pin selectable devices have a configurable 'layer' of silicon between the physical I/O pins and the 'guts' similar to old PAL or GAL devices where you 'burn' the device layout the way you want (within reason).
One day I need to get back into 'playingwith PICs' but as Spring is almost here, I prefer to be outside...
Jay |
|
![](templates/subSilver/images/spacer.gif) |
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sat Jun 15, 2019 9:00 pm |
|
|
Thank you for the answer Jay.
I was doing according to the data sheet in assembler (older controllers).
In the 16F1847.h I found Quote: | // #use i2c() Prototypes: |
But I didn't find the pins.
Anyhow, I wrote the statements below in the .h
Code: | #use i2c(Slave,sda=PIN_B1,scl=PIN_B4,restart_wdt,force_hw,address=0x01)//I2C1 module
#use i2c(Slave,sda=PIN_B2,scl=PIN_B5,restart_wdt,force_hw,address=0x02)//I2C2 module |
It compiles without error and in the .lst have both, hope both will work.
I enabled both interrupts and I have in the .lst the below:
Code: | .................... #INT_SSP2
.................... void SSP2_isr(void)
.................... {
....................
.................... }
....................
0057: BCF 14.0
0058: MOVLP 00
0059: GOTO 036
.................... #INT_SSP
.................... void SSP_isr(void)
.................... {
....................
005A: BCF 11.3
005B: MOVLP 00
005C: GOTO 036
.................... } |
I am writing 2 test programs for master and slave, both 16F1847 and will see it it works
Best wishes
Joe |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19381
|
|
Posted: Sun Jun 16, 2019 1:46 am |
|
|
It's worth perhaps saying, that the really 'safe' way of ensuring the I2C
uses the hardware, is to simply use:
Code: |
#use i2c(Slave,I2C1, restart_wdt,faddress=0x01)//I2C1 module
#use i2c(Slave,I2C2, restart_wdt,address=0x02)//I2C2 module
|
The I2Cx shorthand, says to the compiler to force selection of the hardware
module.
Now the compiler doesn't actually 'know' about APFCON chips (one small
bit that is missed), so selecting like this will always simply result in the
default pins being used (the ones where the APFCON bits are set to '0').
If you want to use the other pins all you do is exactly the same I2C setup,
but you then just set the APFCON bit yourself. So:
Code: |
#BYTE SS1SEL=getenv("BIT:SS1SEL")
//Then in code
SS1SEL=TRUE; //will move SS1 from RB5 to RA5
|
|
|
![](templates/subSilver/images/spacer.gif) |
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sun Jun 16, 2019 6:07 am |
|
|
Thanks Ttelmah
The Slave is clear to me (almost)
By the way, faddress is a typing error I suppose. It gives error when compiling.
I changed to address and it is OK.
I would like to ask how I can implement an interrupt driving Master?
In all my searches didn't find one. Or maybe didn't understand that is interrupt driven.
If I will change to Master will also select hardware I suppose?
Code: | #use i2c(Master, Slow, I2C1, restart_wdt)//I2C1 module
#use i2c(Master, Slow, I2C2, restart_wdt)//I2C2 module |
Best wishes
Joe |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19381
|
|
Posted: Sun Jun 16, 2019 8:09 am |
|
|
I cut and pasted from yours, then removed the 'force_hw'. Managed to miss
the 'f'.... ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sun Jun 16, 2019 11:37 pm |
|
|
Hi
I made the test program for the I2C master, it compiles.
CCS PCM C Compiler, Version 5.062.
PIC16F1847
Below the I2C #use:
Code: | #use i2c(Master,Slow,I2C1,restart_wdt)//I2C1 module, automatically hardware |
The implementation:
Code: | if(I2CstartF==1)
{
i2c_start();//Start condition
i2c_write(slave01addr*2);//(Slave Address * 2) R/W bit low for a write
i2c_write(slave01dataout);//Data to the slave PIC16F1847
i2c_start();//Restart the bus
i2c_write((slave01addr*2)+1);//(Slave Address * 2) R/W bit high for a read
slave01datain = i2c_read();//Read the data from the slave
i2c_stop();
txupdateF=1;
I2CstartF=0;
} |
The LST seems OK.
I copy/paste from Ttelmah posts, small changes, hope with no mistakes.
Please be kind and post your opinion.
Starting the Slave program.
Best wishes
Joe |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|