jeudi 7 mai 2020

Le SC16IS750 : UART avec 8 GPIOs



Le SC16IS750 : UART avec 8 GPIOs


Aujourd'hui je partage une petite découverte récente : le SC16IS750.

Il s'agit d'un circuit permettent d'ajouter une ligne série et 8 GPIOs à un microcontrôleur, un ARDUINO par exemple.

On ne trouve pas énormément d'informations à propose de ce circuit sur le WEB. C'est une bonne raison pour l'essayer et faire un tutoriel.

Il a les caractéristiques suivantes :
  • alimentation 3.3V
  • consommation 30µA en standby
  • entrées tolérantes au 5V
  • pilotage en I2C
    • I2C 400 kbit/s
    • 2 broches d'adresse I2C
  • pilotage en SPI
    • 4 Mbit/s
  • UART : RX / TX avec lignes CTS RTS
    • baud rate jusqu'à 5 Mbit/s
    • contrôle de flux RTS/CTS
    • possibilité de configuration de 4 pins en RI, CD, DTR, DSR
    • RS485
  • 8 GPIOs bidirectionnelles
    • courant de sortie 10 mA maxi
    • sans résistances de pull-up ou pull-down
Comme on le voit son baud rate maximal sera bien supérieur à ce que donnera un objet SoftwareSerial.

Il existe des modules sur AliExpress, coûtant environ 3€.

Ces modules comportent un régulateur 3.3V. C'est un MIC5219 (marquage LG33) qui accepte au maximum 20V sur son entrée.
Il peuvent donc être alimentés en 5V ou 12V sans problème.

1. Le fonctionnement en I2C



Sur ce schéma les deux broches d'adresse sont reliées au +5V. Le circuit possède 16 adresses possibles (voir paragraphe 10.3 Addressing de la datasheet).

Pour le test l'entrée RX est rebouclée sur TX, le SC16IS750 reçoit donc ce qu'il émet.

Le sketch suivant permet de tester le montage :

#include <SC16IS750.h>

SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_I2C, SC16IS750_ADDRESS_AA);

#define SIZE    64
#define LED     1

char xmit[SIZE + 1];
char rcv[SIZE + 1];

void setup()
{
  Serial.begin(115200);
  i2cuart.begin(230400);
  i2cuart.pinMode(LED, OUTPUT);
  i2cuart.digitalWrite(LED, LOW);
  if (i2cuart.ping() != 1) {
    Serial.println("device not found");
    while (1);
  } else {
    Serial.println("device found");
  }
  Serial.println("start serial communication");
  memset(xmit, 'A', SIZE);
  xmit[SIZE] = 0;
}

void loop()
{
  static int count;

  i2cuart.print(xmit);
  while (i2cuart.available() == 0);
  memset(rcv, 0, SIZE);
  i2cuart.readBytes(rcv, SIZE);
  rcv[SIZE] = 0;
  Serial.print(rcv);
  if (memcmp(rcv, xmit, SIZE)) {
    Serial.print("\nError");
  }
  Serial.print("\nInputs: ");
  Serial.println(i2cuart.GPIOGetPortState(), HEX);
  if (++count == 10) {
    i2cuart.digitalWrite(LED, HIGH);
    delay(100);
    i2cuart.digitalWrite(LED, LOW);
    count = 0;
  }
}


Le logiciel compare ce qu'il a reçu avec ce qu'il a émis. Je n'ai pas vu d'erreur à l'affichage.

La LED clignote à chaque fois que 10 messages ont été émis et reçus. L'état des entrées est affiché en continu.

2. Le fonctionnement en SPI


Attention la broche N°1 (I2C-SPI) passe à GND au lieu de +5V. A part cela le câblage SPI est classique.

La broche chip select (CS) peut bien sûr être reliée à une autre broche de l'ARDUINO (ici : la 10).

Voici le sketch :

#include <SC16IS750.h>

SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_SPI, 10);

#define SIZE    64
#define LED     1

char xmit[SIZE + 1];
char rcv[SIZE + 1];

void setup()
{
  Serial.begin(115200);
  i2cuart.begin(230400);
  i2cuart.pinMode(LED, OUTPUT);
  i2cuart.digitalWrite(LED, LOW);
  if (i2cuart.ping() != 1) {
    Serial.println("device not found");
    while (1);
  } else {
    Serial.println("device found");
  }
  Serial.println("start serial communication");
  memset(xmit, 'A', SIZE);
  xmit[SIZE] = 0;
}

void loop()
{
  static int count;

  i2cuart.print(xmit);
  while (i2cuart.available() == 0);
  memset(rcv, 0, SIZE);
  i2cuart.readBytes(rcv, SIZE);
  rcv[SIZE] = 0;
  Serial.print(rcv);
  if (memcmp(rcv, xmit, SIZE)) {
    Serial.print("\nError");
  }
  Serial.print("\nInputs: ");
  Serial.println(i2cuart.GPIOGetPortState(), HEX);
  if (++count == 10) {
    i2cuart.digitalWrite(LED, HIGH);
    delay(100);
    i2cuart.digitalWrite(LED, LOW);
    count = 0;
  }
}

Que dire de plus ? le sketch fonctionne comme le précédent, avec une vitesse bien supérieure, grâce au bus SPI comme on peut s'en douter.

3. La librairie

On peut télécharger la librairie ici :


4. Conclusion

Voici un petit module facile à mettre en œuvre qui pourra offrir une solution de choix aux personnes ne désirant pas changer leur ARDUINO UNO, NANO ou PRO MINI pour une MEGA, pour des raisons diverses et variées : encombrement, consommation, etc.
Ce test a été réalisé avec une PRO MINI 8MHz, alimentée en 3.3V et 5V. Les deux fonctionnent.

Quelques remarques :
  • ces tests ont été effectués à 230400 baud, mais rien ne s'oppose à ce que l'on adopte une vitesse supérieure (j'ai testé avec succès à 921600 baud).
  • les lignes SDA et SCL possèdent des résistances de pull-up internes
  • la méthode digitalRead() ne fonctionne pas (probablement un bug de la librairie)
    • la méthode GPIOGetPortState() permet de lire les 8 entrées à la fois dans un byte, et donc de s'en sortir.
  • il est possible de lire une GPIO si elle est configurée en sortie (comme sur un ARDUINO)
  • la limite de 64 octets des buffers du sketch est une limite de la librairie ARDUINO. Si l'on veut émettre ou recevoir plus d'octets, il faudra le faire en plusieurs fois.

Cordialement
Henri

Aucun commentaire:

Enregistrer un commentaire