View previous topic :: View next topic |
Author |
Message |
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Wed Jun 21, 2023 1:06 pm |
|
|
Thank you for all the help with this.
I change it in the code and I started to get the results for Port 0. I will test the rest later on today.
Code: | void main(){
output_float(PIN_B0);
output_float(PIN_B1);
for(Channel = 0; Channel < 8; Channel++)
{ // loop through channels
select_bus(Channel);
printf("\n\rTCA Port #%d\n\r",Channel);
Device_Count = 0;
Get_I2C_Addresses(); //I2C scanner
}
while(1);
}
|
TCA Port #0
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 00
Stat: 01
ACK addr: C0
Stat: 01
ACK addr: C2
Stat: 01
ACK addr: C4
Stat: 01
ACK addr: C6
Stat: 01
ACK addr: C8
Stat: 01
ACK addr: CA
Stat: 01
ACK addr: CC
Stat: 01
ACK addr: CE
Stat: 01
ACK addr: D0
Stat: 01
ACK addr: D2
Stat: 01
ACK addr: D4
Stat: 01
ACK addr: D6
Stat: 01
ACK addr: D8
Stat: 01
ACK addr: DA
Stat: 01
ACK addr: DC
Stat: 00
Stat: 01
ACK addr: E0
Stat: 00
Stat: 00
Stat: 00
Found: 16 |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Wed Jun 21, 2023 2:51 pm |
|
|
The printf for the bus is actually correct. Depends what you want to see, channel or bus. Channel selection was not, it was ok only for the first bus :-). I'd also go below the mux address with scanning, for the reasons mention earlier. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Thu Jun 22, 2023 12:21 am |
|
|
It wasn't 'only right for bus 0'. Using the array, when he tried to access
zero, it'd actually have selected bus 1.
bus_array[0] = 1
then in the routine
bus_array[1] = 2
which is the value to select bus 1..... |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Thu Jun 22, 2023 12:56 am |
|
|
True. It would hit the <7 limit in select_bus on the third pass. I wonder where it went after that :-) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Thu Jun 22, 2023 1:45 am |
|
|
Some evil dimension... |
|
|
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Mon Jun 26, 2023 2:16 pm |
|
|
Hello,
The addresses I am receiving is 2X the value the what the data sheet says I should receive. I understand this to have bit shift to get the correct value to divide by 2.
[code]void Get_I2C_Addresses(void){
// 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(I2C_Address = 0x10; I2C_Address < 0xF0; I2C_Address+=2) // original
for(I2C_Address = 0x00; I2C_Address < 0xE8; I2C_Address+=2; I2C_Address << 1) // trimmed down to avoid scanning mux address, just in case.
I am getting an error to close paren and Expecting ;.
I do not see why.
Any suggestions? |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 303
|
|
Posted: Mon Jun 26, 2023 3:18 pm |
|
|
You are giving for(;;) an additional parameter it does not support.
I2C address can be represented in 7-bit or 8-bit format. 8-bit format is the 7 bit address with the read/write bit at bit 0. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Tue Jun 27, 2023 4:32 am |
|
|
If he had read my reply in this thread on June 16th, I describe exactly the
difference between 7bit an 8bit addresses. The scanner returns the 8bit
format which is what has to be used by a PIC.
The data sheet actually gives both formats. |
|
|
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Tue Jun 27, 2023 6:49 am |
|
|
Hello,
My question is not the difference between 7-bit and 8-bit. I did see the post on June 16.
Code: | void Get_I2C_Addresses(void){
// 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(I2C_Address = 0x10; I2C_Address < 0xF0; I2C_Address+=2) // original
for(I2C_Address = 0x00; I2C_Address < 0xE8; I2C_Address+=2, [b]I2C_Address << 1[/b]) // trimmed down to avoid scanning mux address, just in case
I have added the IC2_Address << 1 and the results are the same. Is the syntax correct? Here is the data.
ACK addr: C0
Stat: 01
ACK addr: C2
Stat: 01
ACK addr: C4
Stat: 01
ACK addr: C6
Stat: 01
ACK addr: C8
Stat: 01
ACK addr: CA
Stat: 01
ACK addr: CC
Stat: 01
ACK addr: CE
Stat: 01
ACK addr: D0
Stat: 01
ACK addr: D2
Stat: 01
ACK addr: D4
Stat: 01
ACK addr: D6
Stat: 01
ACK addr: D8
Stat: 01
ACK addr: DA
Stat: 01
ACK addr: DC
Stat: 00
Stat: 01
ACK addr: E0
Stat: 00
Stat: 00
Stat: 00
Found: 17
{
status = get_ack_status(I2C_Address);
printf("Stat: %X\n\r", status);
if(status == TRUE)
{
printf("ACK addr: %X\n\r", I2C_Address);
Device_Count++;
delay_ms(100);
}
}
if(Device_Count == 0){
printf("Nothing Found\n\r");
delay_cycles(1);
}
else{
printf("Found: %u\n\r", Device_Count);
delay_cycles(1);
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Tue Jun 27, 2023 6:56 am |
|
|
Jay has already answered why this fails. You are adding a fourth operator
to the for line, which is does not support.
This also doesn't do what you want. It'd mean that the address being sent to
the scanner test would be double the value.
Just limit it by lowering the max count. So:
Code: |
for(I2C_Address = 0x00; I2C_Address < 0xE0; I2C_Address+=2) // trimmed down to avoid scanning mux address, just in case
|
The point about 7bit versus 8bit addresses, is the:
Quote: |
The addresses I am receiving is 2X the value the what the data sheet says I should receive
|
This scanner code returns the 8bit address.
The 8bit address is what the PIC needs, hence the scanner returns this. |
|
|
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Thu Jun 29, 2023 7:29 am |
|
|
Hello,
What is the best way to ignore the R/W bit? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Thu Jun 29, 2023 7:51 am |
|
|
maybe take the 8 bit address, right shift 1 bit, then save as 'actual I2C address' ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Thu Jun 29, 2023 9:31 am |
|
|
and, since (on an integer), the compiler is efficient, and understands the
equivalence between rotation and division, just:
printf("Stat: %X\n\r", status/2); |
|
|
Blackjackmaster
Joined: 14 May 2023 Posts: 30
|
TCA9548A |
Posted: Wed Jul 12, 2023 9:31 am |
|
|
Hello,
I have 3 of the channels used on the TCA9548A and have set up arrays for each channel:
Code: | int8 Array1[16]={}; //Array from Port 0
int8 Array2[16]={}; //Array from Port 1
int8 Array3[16]={}; //Array from Port 2 |
There
After the scan is completed I would like to put each address in the corresponding array for future use.
Code: | #include <16F877A.h>
#device ADC=16
#device ICD=TRUE
//#fuses HS
#FUSES NOWDT //No Watch Dog Timer
//#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOPUT //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(crystal=20mHz)
#use rs232(baud=9600,parity=N,UART1,bits=8,stream=RS232,errors)
#use i2c(Master, slow,i2c1,force_hw)
unsigned int8 I2C_Address;
unsigned int8 status;
unsigned int8 Device_Count = 0;
int8 Channel;
int8 Array0[16]={}; //Array from Port 0
int8 Array1[16]={}; //Array from Port 1
int8 Array2[16]={}; //Array from Port 2
#define TCAaddr 0xE0
const int8 bus_array[8]={1,2,4,8,16,32,64,128};
void select_bus(int bus)
{
if (bus > 7 )
return; //trap illegal bus numbers
I2C_start();
I2C_write(TCAaddr);
I2C_write(bus_array[bus]); //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.
int8 get_ack_status(int8 address)
{
int8 ack;
i2c_start();
delay_us(20);
ack = i2c_write(address); // Status = 0 if got an ACK
i2c_stop();
delay_us(20);
if(ack == 0)
return(TRUE);
else
return(FALSE);
}
void Get_I2C_Addresses(void){
// 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(I2C_Address = 0x10; I2C_Address < 0xF0; I2C_Address+=2) // original
for(I2C_Address = 0x00; I2C_Address < 0xE8; I2C_Address+=2) // trimmed down to avoid scanning mux address, just in case
{
status = get_ack_status(I2C_Address);
printf("Stat: %X\n\r", status);
if(status == TRUE)
{
printf("ACK addr: %X\n\r", I2C_Address);
Device_Count++;
delay_ms(100);
}
}
if(Device_Count == 0){
printf("Nothing Found\n\r");
delay_cycles(1);
}
else{
printf("Found: %u\n\r", Device_Count);
delay_cycles(1);
}
}
//=================================
void main(){
output_float(PIN_B0);
output_float(PIN_B1);
for(Channel = 0; Channel < 8; Channel++)
{ // loop through channels
select_bus(Channel);
printf("\n\rTCA Port #%d\n\r",Channel);
Device_Count = 0;
Get_I2C_Addresses(); //I2C scanner
}
if (Device_Count > 0){
select_bus(0) = Array0[I2C_Address];
printf("\n\rAddresses Port 0 #%d\n\r",I2C_Address);
select_bus(1) = Array1[I2C_Address];
select_bus(2) = Array2[I2C_Address];
}
while(1);
} |
The response I receive is:
Addresses Port 0 #-24
I expected to see:
Stat: 01
ACK addr: C0
Stat: 01
ACK addr: C2
Stat: 01
ACK addr: C4
Stat: 01
ACK addr: C6
Stat: 01
ACK addr: C8
Stat: 01
ACK addr: CA
Stat: 01
ACK addr: CC
Stat: 01
ACK addr: CE
Stat: 01
ACK addr: D0
Stat: 01
ACK addr: D2
Stat: 01
ACK addr: D4
Stat: 01
ACK addr: D6
Stat: 01
ACK addr: D8
Stat: 01
ACK addr: DA
Stat: 01
ACK addr: DC
Any suggestions? |
|
|
|