ciao a tutti, vorrei chiedere un informazione su come impostare i bit in i2c per questo integrato (TDA9886TS), nel senso che sono 3x8 e alcuni sono azzerati e altri hanno 1, come faccio a impostare i parametri?
metto il link del pdf: TDA9886TS/V4 Datasheet(PDF) - NXP Semiconductors
In che senso?
Sceglierei il valore dei vari bit di ciascun registro in funzione di quello che vuoi fare, quando avrai una serie di bit a 0 ed 1 li considererai come un byte e ne scriverai il valore, ad esempio in esadecimale e poi con la libreria Wire scriverai tale valore nel dovuto registro ...
Se, ad esempio, devi impostare il valore 0101 1100 questo corrisponde al valore hex 0x5C che sarà il valore che con la Wire andrai a scrivere.
Guglielmo
e ho fatto cosi, ma rimane fermo, nella tabella il primo bit è nullo, e anche gli ultimi hanno un valore
in altri tda, di solito, nei PLL, nella sezione frequenza, inserivi il valore del numero, con il primo bit a 0, esempio:
valore 2000 (0x7D0), che corrispondeva alla frequenza riempiva 16 bit, è il primo bit doveva essere pari a 0, quindi andava
prima trasmissione 0x07
senza trasmissione 0xD0
e fatto
ma su questo invece, ci sono bit pari a 0 e altri a 1 anche alla fine, quindi come devo trasmetterli?
Non trasmetti i bit, devi comunque costruire un BYTE (o più di uno) composto dai vari bit e poi scrivere i singoli BYTE negli opportuni registri.
I bit dove ci sono 'x', di solito, sono bit ignorati quindi ... lasciali, ad esempio, a 0.
Guglielmo
e gli 0 su msb lo metto? si di solito metto 0 per non perdere ordine
Allora, i bit li DEVI mettere tutti ... se non sono bit usati ('x') mettili a 0 componi il byte, calcola il valore e scrivilo nel registro corretto.
Se invece devi modificare il valore di un bit di un reggistro che è già programmato, leggi il valore del registro, cambi solo quel bit e lo riscivi modificato.
Guglielmo
Quelli sono gli indirizzi di tre regsitri (Definition of the subaddress - second byte after slave address): "SAD for switching mode", "SAD for adjust mode" e "SAD for data mode" ... a seconda in quale devi andare a leggere/scrivere ovviamente DEVI usare il valore indicato.
Per ciascuno poi seguono i possibili bit del contenuto del singolo registro ... tabella 11 per il "SAD for switching mode", tabella 12/13 per il "SAD for adjust mode" e tabella 14 per il "SAD for data mode".
Guglielmo
e come si farebbe?
Ti devi studiare la libreria Wire (con tutti i suoi esempi) e le basi del I2C ... il funzionament è sempre uguale, dopo di che ti devi studiare bene e capire tutte le possibilità che hai nella sezione 9 del datasheet sia per la parte "Read format" che "Write format".
Guglielmo
Come prima cosa, fai girare il programma che segue (su un Arduino AVR ... UNO, MEGA, ecc.):
//
// FILE: MultiSpeedI2CScanner.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.01
// PURPOSE: I2C scanner @different speeds
// DATE: 2013-11-05
// URL:
//
// Released to the public domain
//
#include <Wire.h>
#include <Arduino.h>
#define PRINTALL true
int speed[] = {
10, 50, 100, 200, 400 };
const int speeds = sizeof(speed)/sizeof(speed[0]);
void setup()
{
Serial.begin(115200);
Serial.println("Multispeed - I2C Scanner - V0.1 - \n");
Wire.begin();
I2Cscan();
}
void loop()
{
}
void I2Cscan()
{
// HEADER
Serial.print("ADDR\tADDR\t");
for (uint8_t s = 0; s < speeds; s++)
{
Serial.print("\t");
Serial.print(speed[s]);
}
Serial.println("\t[KHz]");
Serial.println("-----------------------------------------------------------------------");
// TEST
for (uint8_t address = 0; address < 128; address++)
{
bool printLine = PRINTALL;
bool found[speeds];
for (uint8_t s = 0; s < speeds ; s++)
{
TWBR = (F_CPU/speed[s] - 16)/2;
Wire.beginTransmission (address);
found[s] = (Wire.endTransmission () == 0);
printLine |= found[s];
}
if (printLine)
{
Serial.print(address, DEC);
Serial.print("\t0x");
Serial.print(address, HEX);
Serial.print("\t");
for (uint8_t s = 0; s < speeds ; s++)
{
Serial.print("\t");
Serial.print(found[s]? "V":".");
}
Serial.println();
}
}
Serial.println("\ndone...");
}
... ti riporterà l'indirizzo/gli indirizzi fisici del chip attraverso cui comunicare. Riporta il risultato che ti da sul monitor seriale.
Guglielmo
ma qui di mi dici che il chip può avere più indirizzi? io so già indirizzo, ho provato a programmarlo, ma quando lego i registri è sempre allo stesso punto
Hai fatto girare quel programma? Mi riporti i risultati?
Guglielmo
si è un scanner degli indirizzi, mi ha trovato 0x42 il tda e 0x60 che è un altro chip, ma indirizzo lo avevo gia
questo sono i byte che ho messo
#include <Wire.h>
void setup() {
Wire.begin();
trasmissione();
}
void trasmissione()
{
Wire.beginTransmission(0x60);
Wire.write(0x0b);
Wire.write(0x62);
Wire.write(0b11001000);
Wire.write(0b001);
Wire.endTransmission();
Wire.beginTransmission(0x42);
Wire.write(0b00010001);
Wire.write(0b10110000);
Wire.write(0b11000000);
Wire.endTransmission();
}
void loop() {
}
Bene, quindi, se ti sei studiato gli esempi del I2C sai che quello (0x42) è l'indirizzo del chip, gli altri, che trovi all'interno del datasheet, sono gli indirizzi interni dei vari registri, quindi ...
... nella Wire.beginTransmission(indirizzo_del_chip) mentre nelle varie Wire.write() metti l'indirizzo del registro in cui vuoi scrivere o leggere seguito dalla scrittura dei valori o dalla loro lettura.
Guglielmo
quindi Wire.write(0b00010001); che la prima sequenza, devo mettere 0x11?
Certo, in esadeimale il valore binario 0001 0001 è 0x11 (che potresti anche scrivere come numero decimale 17) ... ma cosa indica secondo te quel valore? È l'indirizzo di cosa?
Guglielmo
voglio scrivere su l primo SAD, che è 0000000, ho messo anche le x, devo scrvere prima 0x00 e poi 0x11?
Si, per "SAD for switching mode" dai l'indirizzo di registro 0x00 (mettendo tutte le 'x' a 0), poi devi vedere il valore che ci vuoi scrivere e ... 0001 0001 dovrebbe indicare che vuoi "sound trap bypass" (B0) e "negative FM TV" (B3 e B4) ... giusto ?
Guglielmo
si, esatto, quindi in totale per capirci vanno 6 Wire.write
registro
istruzione
registro
istruzione
registro
istruzione