|
|
View previous topic :: View next topic |
Author |
Message |
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Tue Jun 13, 2023 6:21 am |
|
|
Hello,
Is there a driver for this chip already created for CCS Complier?
I ran this code and it was not reporting anything:
Code: |
#include <16F887.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4M)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK". This function returns TRUE if an
// ACK was found. Otherwise it returns FALSE.
int8 get_ack_status(int8 address)
{
int8 status;
i2c_start();
status = i2c_write(address); // Status = 0 if got an ACK
i2c_stop();
if(status == 0)
return(TRUE);
else
return(FALSE);
}
//=================================
void main()
{
int8 i;
int8 status;
int8 count = 0;
printf("\n\rStart:\n\r");
delay_ms(1000);
// Try all slave addresses from 0x10 to 0xEF.
// See if we get a response from any slaves
// that may be on the i2c bus.
for(i=0x10; i < 0xF0; i+=2)
{
status = get_ack_status(i);
if(status == TRUE)
{
printf("ACK addr: %X\n\r", i);
count++;
delay_ms(2000);
}
}
if(count == 0)
printf("\n\rNothing Found");
else
printf("\n\rNumber of i2c chips found: %u", count);
while(1);
}
|
There are 10K pullups on the SDA and SCL line.
Regards.... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Tue Jun 13, 2023 7:07 am |
|
|
First thing, use the code buttons!...
It should be seen. 10K is rather large. 4.7K is normally recommended.
By default, since you don't specify a clock rate the unit will clock as fast
as possible. With 10K this may not be working. Reduce these.
Change your setup to:
Code: |
#include <16F887.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(INTERNAL=4M)
|
Is your start message being seen?.
How are A0, A1 & A2 connected on the chip?.
How is RESET connected?. It says "Connect to VCC or VDPUM
(1) through a pull-up resistor, if not used". |
|
|
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Tue Jun 13, 2023 9:38 am |
|
|
Hello,
I am using the PIC16F877A Development Kit from CCS. Reset is pulled up to 5V. I have changed the header file to [#include <16F877A.h>]. I also receive an error for no internal Osc.[#include <16F877A.h>
Code: | #fuses NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(INTERNAL=4M)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)] |
I have changed the resistors to 3.1K (that is what I had). I removed the TCA9548A and connected straight to the sensor (with the pullups on SDA and SCL) from the PIC16F877A.
Update:
I do have the program running and nothing is connected to the bus and the program reports 112 Chips found.
Last edited by Blackjackmaster on Tue Jun 13, 2023 10:16 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Tue Jun 13, 2023 10:14 am |
|
|
The 877A, does not have an internal oscillator. The 887 does. Hence that
error.
You won't see the sensor connected via the transceiver, until this is
programmed to enable whichever connection you use. You should though
see an ACK from the transceiver device itself. Where this will be seen
depends on how you have A0, A1 & A2 connected. This is why I asked about
these.
Without the transceiver, you should see an ACK from the sensor.
However you have not told us what chip this is?. It may well not support
the clock rate you are trying to use. A lot of sensors only support 100K.
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FAST=100K)
Some only support slow rates. |
|
|
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Tue Jun 13, 2023 11:39 am |
|
|
Currently I have an ADXL345 Sensor connected straight to the PIC16F877A. I took out the mux because I want to see if this will work with a sensor directly wired to the Micro. The mux has A0,A1,A0 pulled high. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Tue Jun 13, 2023 2:48 pm |
|
|
that's bad news....
adxl spec sheet...
Supply voltage range: 2.0 V to 3.6 V
that 877A PIC is FIVE volts....
POOF ! you've let the magic smoke out !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Wed Jun 14, 2023 12:42 am |
|
|
Ignoring the bang mode, the multiplexer would be on addresses 0xEE, and
0xE1 with the A0, A1 & A2 wired high. It should have been seen there on
your original test.
Now the multiplexer could have solved the level problem.
You'd have needed the multiplexer power by 5v. Then connect the ADXL
to SD0 & SCO,with it powered off 3.3v, and pull up resistors on these
lines to 3.3v.
You'd then program the TCA, with:
Code: |
#define TCAaddr 0xEE //for A0,A1,A2=0b111
const bus_array[8]={1,2,4,8,16,32,64,128};
void select_bus(int number)
{
if (number>7)
return; //trap illegal bus numbers
I2C_start();
I2C_write(TCAaddr);
I2C_write(bus_array[number]); //select specified bus number
I2C_stop(); //I2C bus now routes to BUS number
}
//Then with the ADXL wired as described above, simply call
select_bus(0);
//And the ADXL will now be connected to the I2C bus with level
//translation.
//You then write to the ADXL as normal.
|
The TCA will now route the I2C bus to the SD0/SC0 connections. So
with this done, the ADXL will now appear at it's I2C address on the bus.
There is no great programming involved in the multiplexer. All you have to
do is select it (by writing to it's address), and then send a single byte
with the bit set corresponding to the bus you want to use. The routine
shown handles this. |
|
|
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Thu Jun 15, 2023 7:27 am |
|
|
Hello thank you for the routine. I was able to see 0XEE.
I am not sure where to put this routine.
Code: | #include <16F877A.h>
#fuses NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(crystal=20mHz)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FAST=100000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK". This function returns TRUE if an
// ACK was found. Otherwise it returns FALSE.
#define TCAaddr 0xEE //for A0,A1,A2=0b111
int8 get_ack_status(int8 address)
{
int8 status;
i2c_start();
status = i2c_write(address); // Status = 0 if got an ACK
i2c_stop();
if(status == 0)
return(TRUE);
else
return(FALSE);
}
const bus_array[8]={1,2,4,8,16,32,64,128};
void select_bus(int number);
{
if (number>7)
return; //trap illegal bus numbers
I2C_start();
I2C_write(TCAaddr);
I2C_write(bus_array[number]); //select specified bus number
I2C_stop(); //I2C bus now routes to BUS number
}
//=================================
void main()
{
int8 i;
int8 status;
int8 count = 0;
printf("\n\rStart:\n\r");
delay_ms(1000);
// Try all slave addresses from 0x10 to 0xEF.
// See if we get a response from any slaves
// that may be on the i2c bus.
for(i=0x10; i < 0xF0; i+=2)
{
status= get_ack_status(i);
if(status == TRUE)
{
printf("ACK addr: %X\n\r", i);
count++;
delay_ms(20);
}
}
if(count == 0)
printf("\n\rNothing Found");
else
printf("\n\rNumber of i2c chips found: %u", count);
while(1);
} |
I am getting an "Expecting a Declaration" error. when compiling. I have the ADXL's on Channel 0 and Channel 1 on the TCA9548 and they are not recognized |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Thu Jun 15, 2023 9:16 am |
|
|
First thing:
void select_bus(int number);
There should not be a ';' at the end of this line.
Then in terms of where you use it, _before_ you talk to any bus.
You select the bus you want to use, then do the I2C transactions, and
once the transactions are complete, you then select the next bus and
perform the transactions on this.
It is a function to attach the I2C bus to a specified set of target
connections.
For I2C mode, CS on the ADXL needs to be tied high. Then if SDO is low
the device will be on A6/A7, if this is high then it'll be on 3A/3B.
Understand that at lower voltages the I2C pull up has to drop. The
maximum specified pull up current is normally 3mA. At 5v, this gives
about 1600R min resistor. At 3.3v, just 1100R.
So to see both devices, you'd need to select bus 0, then run the scan
code, then select bus 1, and run the scan code again on this bus.
Are you intending to have a lot more devices?. If not then get rid of
the multiplexer, and just add an I2C level shifter, and set the two
ADXL's to different addresses. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Thu Jun 15, 2023 9:19 am |
|
|
I found two mistakes, after that it compiles ok.
First: const bus_array[8]={1,2,4,8,16,32,64,128};
should be const int8 bus_array[8]={1,2,4,8,16,32,64,128};
and second you have one semicolon extra on the next line in the function. |
|
|
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Thu Jun 15, 2023 11:21 am |
|
|
Thank you for the responses....
I added:
Code: | printf("\n\rBus Array:\n\r %Lu", bus_array);
|
to see the bus array from the chip. I expected to see a 0 for channel 0 and 1 for Channel 1.
This is what I received:
Bus Array:
4112 |
|
|
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Thu Jun 15, 2023 11:32 am |
|
|
I tried this as well....
for (int8 number=0; number<8; number++) {
select_bus(number);
printf ("TCA Port #: %lu",number);
} |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Thu Jun 15, 2023 11:51 am |
|
|
And what was the result?
I'd avoid using the same name for global and local variables or in function declarations(number). Makes it way harder to read and debug. Also if you declare something as int8, why using 16 bit printout (Lu)? What are you trying to print out? In your code you are not even using the function to select channel (void select_bus(int number); ). It is also easier to debug if you declare your variables as int8 or int16 instead of just int. That way you can see at once what kind of variable you are dealing with. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Thu Jun 15, 2023 12:43 pm |
|
|
There is no code to read from the multiplexer here. The value you are
getting for 'BusArray', is just potentially it's address in the ROM. Means
nothing.
All the code does is turns on a switch in the multiplexer to connect the
processor I2C bus to the external I2C bus pair.
You do understand that the external busses need their own pull-ups,
and these have to go to the voltages supported by the external chips?.
You show code selecting the busses, but then don't do any transactions
on the selected bus.
Sequence needs to be:
Select BUS 0
Perform the device scan (but stop it at 0xE0 - you don't want to send
an address byte to the multiplexer -m this will potentially re-program
it....
Select BUS 1
Perform a second device scan - same comment
etc.. |
|
|
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Thu Jun 15, 2023 4:42 pm |
|
|
Hello,
The goal is this:
TCA Port 0#
TCA Port 1#
Found 0X34
TCA Port 2#....
I am trying to figure out how to detect the sensor and what port it is connected to. See the Link...
Is this possible with the configuration I am using? There is existing hardware that was developed and has one set of pullups for 16 chips and has Arduino software on it. I am not a software expert but I am working on converting this to the CCS compiler and PIC16F877A. I did look at the TCA9548A data sheet and it shows pullups for each sensor. The current system works fine but now it is time to make this without the Arduino Bootloader.
There are other issues I have as well. The current addresses are from 96-101. When I scan these sensors I get C0-D? ( I do not have the list with me) and then I have to divide by 2. One is processor treats it like a 7-bit and the other 8-bit. I have not figured out which is which yet.
I understand from the responses some frustration from the two that have responded. Thank you for your support and I apologize for the confusion. |
|
|
|
|
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
|