Escribí sobre este sistema antes. Centraré mis preguntas ahora en la dirección de "protección ESD".
Tengo un sistema basado en SPI en el que una Raspberry habla con un dispositivo de expansión GPIO mediante comunicación SPI. El chip lee y/o escribe '0'/'1' y lo envía a la Raspberry por bus.
El circuito del expansor GPIOs es un circuito muy simple, pero algunos días un peligroso sobreconsumo/sobrecalentamiento (casi se quema) se dispara aleatoriamente después de horas de funcionamiento correcto. Esto se detiene cuando reinicio el dispositivo. Después de esto, el dispositivo tiene un comportamiento normal y un consumo normal. Hoy en día el sistema se está conectando y probando en una protoboard. Entonces, el cableado o el material de laboratorio pueden estar afectando poco o mucho.
Algunas personas sugieren que este comportamiento parece ser un "bloqueo" causado por ESD. De lo contrario, podría ser causado por picos de voltaje, picos positivos o GND negativos. Entonces, me dijeron que mis GPIO deben protegerse con resistencias, diodos y capacitores. Pero no veo ningún ejemplo con diodos, Cs y Rs protegiendo entradas/salidas en otros proyectos basados en microcontroladores o microprocesadores. Lo más que he visto son resistencias en serie en algunos de los pines GPIO.
Mi circuito es mucho más simple que los que he visto:
8 pines de expansión serán entradas. El resto serán salidas.
Las salidas del expansor escribirán '0', nunca '1'.
Las entradas del expansor tienen un Rpull interno que pone la entrada a 3,3 V cuando no está conectado.
Puse un cable en cada salida y este cable podría conectarse directamente a las entradas o no. Entonces, cuando lea los 8 pines de entrada, los que están conectados a las entradas leerán '0', y el resto, leerá '1'.
Una entrada leería estos 3 escenarios:
Una característica particular de este sistema es que el resto de veces no se configurarán GPIOs como entradas o salidas. Entonces, durante una ejecución, un pin se puede configurar como entrada durante la inicialización, pero en la siguiente ejecución, el mismo pin se puede configurar para que sea una salida.
Este fenómeno de sobrecalentamiento no ocurre más de una o dos veces al día. Pero me temo que una vez sería suficiente para destruir el sistema.
En el diseño final de PCB, los pines GPIO se rastrearán a través de la placa para lograr un conector de 64 pines. La entrada y la salida se conectarán a través de un cable que conectará -o no- dos de los pines del conector de 64 pines por conexión humana durante la ejecución. De esta forma, se podría cerrar un circuito entre una entrada y una salida. Pero también podría haber circuitos abiertos entre el resto de entradas y salidas.
He agregado 10K Rs en cada dispositivo GPIO y estoy usando 100nF entre VDD y GND. Parece que no sucede más hace dos días, pero me gustaría asegurar mis GPIO si el circuito realmente lo necesita.
¿Este circuito necesita protección GPIO? ¿Son suficientes estas resistencias?
Pregunta
¿Cómo es que mi extensor GPIO MCP23S17 se calienta mucho y se vuelve loco?
/ continuar, ...
Respuesta
Parte 1 - Configuración de la prueba
Sugeriría comenzar con una versión más pequeña de los requisitos del usuario. Por ejemplo, en lugar de hacer las cosas muy flexibles, cualquier pin puede ser de entrada o salida, puede en la fase de prueba, permitir que solo entren 8 pines y solo salga otro pin.
PA0~7 configurado en modo de entrada
PB0~7 configurado en modo de salida
Solo cuando encuentre el modo fijo de entrada/salida de los pines OK en la prueba, entonces generalizará el programa.
mcp23017_test_v0.2_2020aug0101 PÚBLICO
Parte 2 - Aclaración sobre ESD y enganche
Es posible que haya notado que los proveedores generalmente envían los componentes en bolsas de plástico metálicas y también en esponjas metálicas. Eso es para antiestático.
Los operarios de las fábricas de montaje y ensayo llevan brazaletes antiestáticos como este:
Soy un aficionado a jugar con componentes baratos, y nunca me molesto, porque las posibilidades de contraer el virus ESD son muy, muy pequeñas.
Es en los viejos tiempos, cuando los componentes electrónicos eran caros, que la gente se molestaba. O te quedas en un país muy seco, usando ropa de poli/plástico/nylon, entonces necesitas preocuparte. Por supuesto, todo el mundo tiene la posibilidad de ser alcanzado por un rayo. Tal vez debería buscar más en Google para tener una idea.
(Ref. A.2) Equipo ESD que mejora la seguridad y la protección en el lugar de trabajo: AntiStat
Parte 3 - Recomendación para usar fuente de alimentación externa para MCP23S17
Siempre recomiendo a los novatos que NO usen el riel de 5 V o 3 V de Rpi para alimentar el MCP23S17 u otros dispositivos periféricos, sino que usen una fuente de alimentación externa, al menos para la etapa de creación de prototipos.
De esta manera, si MCP23S17 se vuelve loco, el Rpi aún se sienta feliz. Así que restablecí manualmente MCP23S17 y no es necesario restablecer Rpi, los programas continúan.
Parte 4 - Posibles causas de sobrecalentamiento
Lo que dices sobre el sobrecalentamiento es un poco preocupante.
MCP23S17 no puede manejar grandes corrientes. Usualmente uso chips de búfer para manejar grandes corrientes. Si está sobrecargando los 16 pines de salida GPIO con una gran corriente, tendrá un gran problema.
Revisé la hoja de datos e hice un resumen:
(1) Potencia total = 700 mW
(2) Pin VSS de corriente máxima = 150 mA
(3) Corriente máxima en pin VDD = 25 mA
(4) Corriente de pinza de entrada = ±20 mA
(5) Corriente de sujeción de salida = ±20 mA
(6) Corriente de salida máxima absorbida por cualquier pin de salida = 25 mA
(7) Corriente de salida máxima generada por cualquier pin de salida = 25 mA
Como puede ver, si carga 6 pines GPIO con 25 mA, entonces la corriente total supera el límite de 150 mA del pin Vss. Usualmente utilizo el chip ULN2803A de 8 tipos grandes para hacer todo el trabajo pesado. Cada uno de los 8 tipos grandes puede manejar 500 mA,...
Parece que usa 10Ω para la resistencia de protección/limitación en serie. Es posible que desee hacer los cálculos para asegurarse de que no se exceda el límite de corriente de GPIO individual y Vcc total.
Parte 5: prueba y programación de par/intercambio
A menudo es una buena idea utilizar más de dos muestras para realizar pruebas de par/intercambio. A menudo, un componente puede estar defectuoso al recibirlo o dañado por un cableado o una prueba descuidados. Muy a menudo, solo mediante la comparación y el contraste de intercambio se encuentran errores de cableado por descuido. Puede usar MCP23s08 o MCP23017 para pruebas cruzadas. Solo la parte de configuración es diferente en las versiones I2C y SPI de MCP23x17. Las principales funciones de operación son idénticas para MCp23SS17 y MCP23017 017. Tomar fotografías de vez en cuando es una buena documentación para referencia posterior.
/ continuar, ...
Referencias
Parte A - Hojas de datos y artículos
(A.1) Hoja de datos de MCP23S17/MCP23017 - MicroChip
(A.2) Equipos ESD que mejoran la seguridad y la protección en el lugar de trabajo: AntiStat
(A.5) Servocontrolador/PWM de 12 bits de 16 canales I2C de Adafruit - $15
(A.6) Hoja de datos del controlador PWM PCA9685 - NXP
(A.7) Hoja de datos mcp23s17 - Microchip
(A.8) Módulo AliExpress MCP23S17
(A.9) Módulo TaoBao MCP23S17
(A.10) Convertidor de nivel lógico (ULN2803, TBX/TSX0102/4/6/8, etc.) 1/2
(A.11) Convertidor de nivel lógico (ULN2803, TBX/TSX0102/4/6/8, etc.) 2/2
(A.12) TVS, diodo de sujeción MOV - Liz London 2019mar16
(A.13) (TVS) Diodo de supresión de voltaje transitorio - Wikipedia
(A.14) Diodos de protección ESD (diodos TVS) - Toshiba
(A.15) Protección ESD por diseño de chips y microcircuitos - Biblioteca en línea, Wiley
(A.16) ESD (descarga electrostática) - Wikipedia
(A.17) Tapas de desacoplamiento, diseño de PCB - Olin Lathrop, EE SE, 2011jun07, visto 80k veces
Parte B - Discusiones del foro
Parte C - Esquemas
(C.1) mcp23s17_test_2020jul3002 Esquema de CircuitLab - tlfong01 2020jul3001
(C.2) mcp23017_test_v0.2_2020aug0101 PÚBLICO tlfong01 2020aug01
Apéndices
Apéndice A - Condensadores de derivación y desacoplamiento - Robert Keim, AAC
Introducción
No es inconcebible que un estudiante de ingeniería dedicado y exitoso se gradúe de la universidad sin saber casi nada acerca de uno de los componentes más omnipresentes e importantes que se encuentran en los circuitos reales: el condensador de derivación. Incluso los ingenieros experimentados pueden no entender completamente por qué incluyen condensadores cerámicos de 0,1 µF junto a cada pin de alimentación de cada IC en cada placa de circuito que diseñan.
Este artículo proporciona información que lo ayudará a comprender por qué los capacitores de derivación son necesarios y cómo mejoran el rendimiento del circuito, y un artículo de seguimiento se centrará en los detalles relacionados con la elección de capacitores de derivación y las técnicas de diseño de PCB que maximizan su eficacia.
Solución
es conveniente que un problema tan grave pueda resolverse de manera efectiva con un componente simple y ampliamente disponible. Pero, ¿por qué el condensador? Una explicación sencilla es la siguiente: un capacitor almacena carga que se puede suministrar al circuito integrado con una resistencia en serie muy baja y una inductancia en serie muy baja.
Por lo tanto, las corrientes transitorias se pueden suministrar desde el condensador de derivación (a través de una resistencia e inductancia mínimas) en lugar de desde la línea de alimentación (a través de una resistencia e inductancia comparativamente grandes). Para entender mejor esto, necesitamos revisar algunos conceptos básicos relacionados con cómo un capacitor afecta un circuito.
Primero, sin embargo, una breve nota sobre la terminología: los componentes discutidos en este artículo se denominan regularmente " condensadores de derivación " y " condensadores de desacoplamiento ".
Aquí hay una distinción sutil: "desacoplamiento" se refiere a reducir el grado en que una parte de un circuito influye en otra, y "derivación" se refiere a proporcionar una ruta de baja impedancia que permite que el ruido "pase por" un IC en su camino. al nodo de tierra.
Ambos términos se pueden usar correctamente porque un condensador de derivación/desacoplamiento realiza ambas tareas. En este artículo, sin embargo, se prefiere el "condensador de derivación" para evitar confusiones con un condensador de desacoplamiento en serie que se usa para bloquear el componente de CC de una señal.
Un enfoque estándar
El análisis anterior nos ayuda a comprender un esquema de derivación clásico:
un capacitor de 10 µF dentro de una pulgada o dos del IC, y
un condensador cerámico de 0,1 µF lo más cerca posible del pin de alimentación:
El capacitor más grande suaviza las variaciones de baja frecuencia en el voltaje de suministro, y el capacitor más pequeño filtra con mayor eficacia el ruido de alta frecuencia en la línea de alimentación.
Si incorporamos estos condensadores de derivación en la simulación de 8 inversores discutida anteriormente, se elimina el zumbido y la magnitud de la perturbación de voltaje se reduce de 1 mV a 20 µV , ...
Apéndice B - Problema de puesta a tierra y solución
(1) Problemas de bucle de tierra y cómo deshacerse de ellos - Tomi Engdahl 2013
(3) Problema de conexión a tierra del circuito del botón pulsador Rpi GPIO
Apéndice C - Protoplaca antigua MCP23S17/ MCP23017 para pruebas
Estoy pensando en usar mi viejo MCP23S17 o MCP23017 para hacer algunas pruebas. Mirando el desordenado cableado de mi vieja placa MCP23017, ahora recuerdo por qué la última vez dejé de trabajar en SPI MCP23S17 y cambié a I2C MCP23017, porque el cableado de bricolaje es muy complicado y es difícil solucionar problemas de hardware. Para I2C MCP23S17, hay borads de ruptura baratos, diciéndome mucho tiempo haciendo cableado.
Apéndice D - Notas de configuración de la protoplaca MCP23s17
Apéndice E: prueba de SPI 00, 01, 10, 11, 12 Bucle invertido y repetición de envío de un byte OK
# Program:
# spi_loopback_v55.py tlfong01 2020aug03hkt1220
#
# Function:
# 1. SPI one byte loopback
# 2. SPI repeatedly send one byte
#
# System Config:
# Rpi4B buster (r2020may23), python 3.7.3 (r2019dec20), thonny v3.2.7 (r2020jan22)
# $ date Thu 25 Jun 2020 04:36:13 PM HKT
# $ uname -a Linux raspberrypi 4.19.118-v7l+ #1311 SMP Mon Apr 27 14:26:42 BST 2020 armv7l GNU/Linux
# $ ls /dev/ttyUSB* /dev/ttyUSB0
# $ ls /dev/ttyS0 /dev/ttyS0
# $ ls /dev/ttyAMA0 /dev/ttyAMA0
# Test Function Definitions:
#
# Test 1 - loopBackTest() - SPI port send and receive one byte.
# Function - Send one byte to MSOI and read it back from MISO.?
# Setup - Connet MOSI pin to MISO pin to form a loop.
#
# Test 2 - repeatSendByte() - SPI port repeatedly send out single bytes. ?
# Function - Repeat many times sending a byte, pause after each byte.
# 1. SPI ports setup notes
# To enable SPI and setup SPI 10, 11, 12 ports, add these two lines to /boot/config.txt
# dtparam=spi=on
# dtoverlay=spi1-3cs
# To list SPI devices
# pi@raspberrypi:~ $ ls /dev/spi*
# /dev/spidev0.0 /dev/spidev0.1 /dev/spidev1.0 /dev/spidev1.1 /dev/spidev1.2
# 2. Notes of loopback function
# Call example - testLoopbackOneByte(spiPort00)
# Function - send byte 0x5b to SPI MOSI and read byte from MISO
# Setup - must connect MOSI pin to MISO pin to loop back
# Note - 1. Only checks if MISO echoes MOSI, CS0, CS1, CS2 is not checked
# 2. To check if SPI 0, CS0, CS1, or SPI1 CS0, CS1, CS2, need a scope to display repeat send bytes
from time import sleep
import spidev
# *** Setup SPI Ports ***
spiPort00 = spidev.SpiDev()
spiPort00.open(0,0)
spiPort00.max_speed_hz = 100000
spiPort01 = spidev.SpiDev()
spiPort01.open(0,1)
spiPort01.max_speed_hz = 100000
spiPort10 = spidev.SpiDev()
spiPort10.open(1,0)
spiPort10.max_speed_hz = 100000
spiPort11 = spidev.SpiDev()
spiPort11.open(1,1)
spiPort11.max_speed_hz = 100000
spiPort12 = spidev.SpiDev()
spiPort12.open(1,2)
spiPort12.max_speed_hz = 100000
# *** Define SPI Functions ***
def spiSendRecvOneByte(spiPort, sendByte):
sendByteArray = [sendByte]
recvByteArray = spiPort.xfer(sendByteArray)
return recvByteArray
def loopBackOneByte(spiPort, sendByte):
recvByteArray = spiSendRecvOneByte(spiPort, sendByte)
recvByte = recvByteArray[0]
print('\nBegin testLoopbackOneByte(),....')
#print('')
print(' sendByte = ', hex(sendByte))
print(' recvByte = ', hex(recvByte))
#print('')
print('End testLoopbackOneByte(),....')
return
def repeatSendOneByte(spiPort, sendByte, pauseTimeBetweenBytes, repeatCount):
print('\nBegin repeatSendByte(),....')
print(' Now use a scope to display the SPI signals, MOSI, MISO, CSn, ...')
for i in range(repeatCount):
spiSendRecvOneByte(spiPort, sendByte)
sleep(pauseTimeBetweenBytes)
print('End repeatSendByte().')
return
# *** Test Funtions ***
def testLoopbackOneByte(spiPort, dataByte):
loopBackOneByte(spiPort, dataByte)
return
def testRepeatSendOneByte(spiPort, dataByte, pauseSeconds, repeatTimes):
repeatSendOneByte(spiPort, dataByte, pauseSeconds, repeatTimes)
return
# *** Main ***
# *** Test SPI Loopback Functions, Comment out not required tests ***
print('\n*** testLoopbackOneByte(spiPort00, 0x5b) ***', end = '')
testLoopbackOneByte(spiPort00, 0x5b)
#print('\n*** testLoopbackOneByte(spiPort01, 0x5b) ***', end = '')
#testLoopbackOneByte(spiPort01, 0x5b)
#print('\n*** testLoopbackOneByte(spiPort10, 0x5b) ***', end = '')
#testLoopbackOneByte(spiPort10, 0x5b)
#print('\n*** testLoopbackOneByte(spiPort11, 0x5b) ***', end = '')
#testLoopbackOneByte(spiPort11, 0x5b)
#print('\n*** testLoopbackOneByte(spiPort12, 0x5b) ***', end = '')
#testLoopbackOneByte(spiPort12, 0x5b)
# *** Test SPI Repeat Send One Byte Functions, Comment out not required tests ***
# *** SPI 00, 01 Repeat Send One Byte ***
#print('\n*** testRepeatSendOneByte(spiPort00, 0x5b, 0.001, 200000) ***', end = '')
#testRepeatSendOneByte(spiPort00, 0x5b, 0.001, 200000)
#print('\n*** testRepeatSendOneByte(spiPort01, 0x5b, 0.001, 200000) ***', end = '')
#testRepeatSendOneByte(spiPort01, 0x5b, 0.001, 200000)
# *** SPI Repeat Send One Byte 10, 11, 12 ***
#print('\n*** testRepeatSendOneByte(spiPort10, 0xb5, 0.001, 200000) ***', end = '')
#testRepeatSendOneByte(spiPort10, 0xb5, 0.001, 200000)
#print('\n*** testRepeatSendOneByte(spiPort11, 0xb5, 0.001, 200000) ***', end = '')
#testRepeatSendOneByte(spiPort11, 0xb5, 0.001, 200000)
#print('\n*** testRepeatSendOneByte(spiPort12, 0xb5, 0.001, 200000) ***', end = '')
#testRepeatSendOneByte(spiPort12, 0xb5, 0.001, 200000)
# End of program
''' Smple output tlfong 01 2020aug03hkt1219
>>> %Run spi_loopback_v54.py
*** testLoopbackOneByte(spiPort00, 0x5b) ***
Begin testLoopbackOneByte(),....
sendByte = 0x5b
recvByte = 0x5b
End testLoopbackOneByte(),....
*** testLoopbackOneByte(spiPort01, 0x5b) ***
Begin testLoopbackOneByte(),....
sendByte = 0x5b
recvByte = 0x5b
End testLoopbackOneByte(),....
*** testLoopbackOneByte(spiPort10, 0x5b) ***
Begin testLoopbackOneByte(),....
sendByte = 0x5b
recvByte = 0x5b
End testLoopbackOneByte(),....
*** testLoopbackOneByte(spiPort11, 0x5b) ***
Begin testLoopbackOneByte(),....
sendByte = 0x5b
recvByte = 0x5b
End testLoopbackOneByte(),....
*** testLoopbackOneByte(spiPort12, 0x5b) ***
Begin testLoopbackOneByte(),....
sendByte = 0x5b
recvByte = 0x5b
End testLoopbackOneByte(),....
>>>
Python 3.7.3 (/usr/bin/python3)
>>> %Run spi_loopback_v54.py
*** testRepeatSendOneByte(spiPort00, 0x5b, 0.001, 200000) ***
Begin repeatSendByte(),....
Now use a scope to display the SPI signals, MOSI, MISO, CSn, ...
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Python 3.7.3 (/usr/bin/python3)
>>> %Run spi_loopback_v54.py
*** testRepeatSendOneByte(spiPort01, 0x5b, 0.001, 200000) ***
Begin repeatSendByte(),....
Now use a scope to display the SPI signals, MOSI, MISO, CSn, ...
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Python 3.7.3 (/usr/bin/python3)
>>> %Run spi_loopback_v54.py
*** testRepeatSendOneByte(spiPort10, 0xb5, 0.001, 200000) ***
Begin repeatSendByte(),....
Now use a scope to display the SPI signals, MOSI, MISO, CSn, ...
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Python 3.7.3 (/usr/bin/python3)
>>> %Run spi_loopback_v54.py
*** testRepeatSendOneByte(spiPort11, 0xb5, 0.001, 200000) ***
Begin repeatSendByte(),....
Now use a scope to display the SPI signals, MOSI, MISO, CSn, ...
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Python 3.7.3 (/usr/bin/python3)
>>> %Run spi_loopback_v54.py
*** testRepeatSendOneByte(spiPort12, 0xb5, 0.001, 200000) ***
Begin repeatSendByte(),....
Now use a scope to display the SPI signals, MOSI, MISO, CSn, ...
End repeatSendByte().
>>>
'''
# *** End ***
Apéndice F - Repetir capturas de pantalla del alcance del byte de envío
Apéndice G - Configuración de dos placas MCP23S17 Proto
fin de respuesta
Sólo yo
Suvi_Eu
Suvi_Eu
tlfong01
tlfong01
tlfong01
tlfong01
tlfong01
tlfong01
tlfong01
tlfong01
tlfong01
Suvi_Eu
Suvi_Eu
Suvi_Eu
Suvi_Eu
tlfong01
tlfong01
tlfong01
tlfong01
tlfong01