Desarrollo inverso del interruptor de tiempo VL-76-S

Érase una vez el interruptor de tiempo digital electrónico VL-76-S, nuevo, empaquetado pero en mal estado. No se encontraron defectos en las placas de circuito impreso en el interior. Por lo tanto, matrimonio de fábrica, firmware roto.


Vista general del relé.

Lo que nos sorprendió fue el uso del popular y sencillo microcontrolador ATTiny2313. Externamente, este diseño consiste en un maestro en forma de tres décadas de interruptores y un terminal al que se conectan la alimentación de 220 V y los contactos de un relé EM. El rango de la tarea es 0.1 ... 99.9 minutos. en incrementos de 0.1 min (6 segundos) No hay circuitos ni firmware en este diseño en Internet, lo cual no es sorprendente. Sin pensarlo dos veces, decidí dibujar el circuito de las placas de circuito impreso y en el futuro escribir el programa en el MK.

El diseño consta de tres placas de circuito impreso interconectadas. En la primera placa, se hacen una fuente de alimentación y un relé TRA3. La fuente de alimentación se realiza de acuerdo con un circuito sin transformador: los condensadores de enfriamiento se utilizan para reducir el voltaje. En la segunda placa está el ATTiny2313 MK y otros elementos auxiliares. En la tercera placa hay interruptores (puntos de ajuste) y un LED de control.


Foto del tercer tablero desde atrás.

Comenzaré la descripción con el tercer tablero. Los interruptores son interruptores de 10 posiciones. No hay marcas en ellos, cada uno de ellos tiene 5 contactos. Por lo tanto, dependiendo de la posición, ciertos contactos están cerrados en varias combinaciones. Invocando contactos, inmediatamente capté el patrón: una salida fija (general) se cierra con las otras cuatro salidas (información) de acuerdo con la representación binaria del número correspondiente al número de la posición seleccionada. Por ejemplo, si se selecciona la posición "3", la salida general (quinta consecutiva) se cierra con la salida de la tercera y cuarta, ya que el número "3" en representación binaria es "0011". Aquí hay un cambio tan complicado. Y hay tres de ellos. Están conectados a través de conectores XP1 y XP2 a la segunda placa con MK. Un conector XP3 conecta un LED y alguna otra basura innecesaria sin soldar, para lo cual hay un lugar en la placa. Lo más probable es que este sea un interruptor DPDT común de seis pines (como uno cuadrado, PB22E06, por ejemplo). Quizás la placa sea universal, pero no se usa en este modelo en particular.


Foto de la segunda placa (principal).

Al llamar a los contactos de los conmutadores, no entendí de inmediato el principio de su conexión a los puertos MK. En la placa principal, 8 transistores SMD son inmediatamente evidentes. Más tarde descubrió que estos transistores se usan como pares de diodos con un ánodo común. Sus bases van a los puertos MK, y los colectores y emisores van a cambiar los contactos. Luego me explicaron que en tales casos hay pares de diodos, suenan como transistores, pero no son transistores. En total, tenemos 16 conductores que dejan los pares de diodos en la tercera placa. Tres cuartos de ellos (12 piezas) llegan a los contactos de información de los interruptores (tres a cuatro), y 4 permanecen libres. Es fácil adivinar que, en teoría, se proporcionan para el cuarto interruptor, que de alguna manera no está ausente, porque no hay espacio para ello en el tablero. Sin embargo, para no violar la lógica del razonamiento, mencionaré este cuarto interruptor imaginario. Los extremos comunes de los interruptores segundo y tercero, así como el primero y el cuarto (pero el cuarto no proporciona la placa) están conectados por pares entre sí mediante pistas en la placa principal en los conectores de acoplamiento XS1 y XS2. Estos dos pares están conectados a las salidas de los grupos de transistores. Estos dos grupos idénticos están formados en los transistores BC857 y BC847 (estructuras diferentes). Sus entradas están conectadas a la MK. Al aplicar un "0" lógico a la entrada de este grupo, la salida también será un "0" lógico. Además, en la placa hay un conector XP2 para firmware MK, conectado a los terminales SPI de la interfaz MK, un conector XS3 para un LED y un conector XP1 conectado por un cable a la primera placa. Debe recordarse que algunos de los puertos MK pueden usarse tanto para SPI (para firmware) como para entrada-salida ordinaria (funciona en el circuito).

Todo lo anterior se refleja en los diagramas que dibujé primero en borrador, luego en SPlan. Las clasificaciones de los elementos de radio que no estaban marcados (por ejemplo, condensadores SMD) están ausentes en los diagramas, no son tan importantes. Primero, daré un diagrama de la placa principal y la placa con los colocadores (firmas de las imágenes a continuación).


Esquema del tablero principal.



Esquema del tercer tablero con setters

Considere cómo el interrogatorio de cada setter. Las señales de los puertos PB4 y PB5 MK lógica "0" abren los transistores VT2 y VT1, seguidos de VT4 y VT3, que se conectan a los contactos comunes del bus cero de los interruptores No. 1 y No. 2-No. 3, respectivamente. Esto sucede a su vez. Primero, el "0" lógico proviene de PB4 (PB5 hasta ahora se ha establecido en "1" lógico), conectando el segundo y el tercer conmutador. En este estado, los valores de las señales son grabados a su vez por el controlador desde los puertos de entrada PB3, PB2, PB1, PB0 a través de los grupos de diodos 2VD1 ... 2VD4 desde el segundo y cuatro interruptores faltantes. Inmediatamente, los valores de las señales de los pines PD6, PD5, PD4, PD3 MK son fijos, a los cuales las señales del primer y tercer conmutadores llegan a través de los grupos de diodos 2VD5 ... 2VD8. Pero, dado que solo el segundo y el tercer conmutadores están conectados por un contacto común, las señales del segundo conmutador llegarán a los primeros puertos especificados del MK, y el cuarto será ignorado. Del mismo modo, las señales del tercer interruptor llegarán a la segunda mitad del MK, y el primero será ignorado. En esta etapa, el controlador sabe en qué posiciones están instalados los interruptores segundo y tercero. Después de eso, PB4 se establece en "unidad", apagando los interruptores segundo y tercero, y PB5 se establece en "cero". En este caso, el primer interruptor y el cuarto que faltan están conectados por un extremo común al "caso". Su interrogación ocurre exactamente igual que en el caso anterior, pero ahora se registrarán las señales de esos interruptores que se ignoraron la última vez. Por lo tanto, el controlador conoce la información de posición de todos los interruptores. Este proceso es similar a sondear un teclado matricial, pero en este caso una matriz de 4 capas con dimensiones de 2 por 2 con un elemento faltante.

Resistencias R8 ... R15 - pull-ups. Aunque, fue posible "parar" en el MK en sí. Frecuencia de reloj precisa MK proporciona cuarzo a 10 MHz. R1 y C4 - Circuito de reinicio MK. No hay nada más interesante en este foro.


Foto de la primera placa (de potencia) desde el lado de los elementos.


Foto de la primera placa (alimentación) desde la parte posterior.

Pasemos al esquema del primer tablero (Fig. Arriba). El esquema parecía muy interesante y en algunos lugares incomprensible.


Esquema de la primera placa (potencia).

C1C2 - para reducir el voltaje. R1 - para descargar lo anterior. Después del puente de diodos DB1 hay dos electrolitos. Para complicar el circuito (o por confiabilidad) - esquema de estabilización en cascada VT3R6VD3 - VT7R12VD5. VD5 es similar a un transistor SMD de emisor no utilizado. Esto proporciona un voltaje de CC estabilizado de 12V. El siguiente es el regulador lineal VR1 a 5V. Al mismo tiempo, el voltaje se elimina del puente de diodos DB1 a través del diodo VD2 a otro estabilizador VT1R3VD1 de 24V. Este voltaje se suministra a la bobina del relé EM Rel1 y a R17. Lo último no está claro por qué. En el otro extremo de R17 viene la señal del grupo de transistores VT9VT10. El circuito de este grupo es similar al circuito de la placa principal. Una señal de un puerto MK PB6 separado llega a la entrada de este grupo de transistores a través del conector. ¿Por qué es necesario? ¿Por qué conectar una resistencia R17 a 24V? Lo más probable es que haya una idea de que, en lugar de una resistencia, puede colocar algo más, por ejemplo, un LED de control interno, programando el puerto PB6 MK de cierta manera. O un nodo de conmutación adicional. Pero, de todos modos, esto no tiene sentido, como dicen mis conocidos ingenieros de radio, después de haber mirado la placa de diseño. El segundo extremo del relé EM Rel1 está conectado a un grupo de transistores similar VT2VT5, y está conectado al puerto MK PD0. La señal "0" de este puerto activa el relé EM en ejecución. Lo más interesante es que el LED externo está conectado no paralelo al relé EM, sino a la brecha del emisor del transistor VT2, además, a través de dos conectores (que pasan por la placa principal). En el terminal, los números de pin 1 y 2, a juzgar por la etiqueta en el relé, permanecen vacíos. Pero en el circuito, el contacto No. 2 está conectado a un cable común, y el contacto No. 1 se alimenta a la entrada del grupo de transistores VT6VT8. La salida de este grupo se envía al puerto PD2 MK. Más tarde, leí en la especificación para este modelo de relé que estos contactos se utilizan para controlar otros modelos de relé, ensamblados en el mismo caso. El modelo que estoy considerando no implica control, pero se puede implementar al escribir un programa en MK, ya que el esquema brinda esta oportunidad. Bajo el control puede significar un inicio, reinicio (tanto en "disparador" como en modo normal) y todo lo que se le ocurra. Las especificaciones para otros relés muestran diagramas de temporización que muestran el comportamiento de los relés dependiendo de una señal de control dada. También dice a continuación: a petición del cliente, podemos implementar cualquier diagrama posible. Y el último momento en el esquema. Esta señal de control del terminal No. 1 también llega al inútil transistor VT4, alimentado por un voltaje de 12V. Esto, nuevamente, es una complicación del esquema. ¿O tal vez todavía hay alguna idea establecida? No profundicé profundamente. Estaré encantado de cualquier comentario.

Las marcas de los terminales de los conectores se firman a través del punto después del nombre del conector en sí. Los números romanos después del símbolo "~" indican conclusiones inútiles y faltantes. Los últimos no son pocos en el esquema, pero no me detendré en ellos. A continuación les doy bocetos de cada placa con las designaciones de conectores, conclusiones y elementos básicos.


Bocetos de tablero.

Considere la descripción del código fuente para el programa MK. El programa en sí es simple y lo escribí en CVAVR durante 20 minutos. Discutiré el algoritmo por el cual se ejecutará el programa. Esta información puede parecer bastante banal para algunos, pero no será superflua para los principiantes. En mi versión del algoritmo, los temporizadores en el relé de tiempo serán interrogados no una vez, sino continuamente. Además, el sondeo continuará incluso después de que se haya disparado el relé. Esto le permitirá hacer ajustes sobre la marcha. Quizás este algoritmo no coincida con el algoritmo original para el funcionamiento de este relé, pero no estoy familiarizado con el algoritmo original. Es en el ejemplo del algoritmo mencionado anteriormente que se considerará la descripción del programa.

Código fuente para el programa C con descripción.
Conectamos la biblioteca para trabajar con el ATTiny2313 MK, así como la biblioteca de funciones de retraso.

#include <tiny2313.h> #include <delay.h> 

A continuación, hacemos la macro sustitución necesaria, de acuerdo con las asignaciones de circuito de los puertos MK. Estas sustituciones son convenientes porque en el texto del programa en lugar de, por ejemplo, PORTB.5, puede escribir getAD, que es más conveniente. La compilación getAD se interpretará como PORTB.5. Entonces, la primera sustitución son las salidas para conectar el primer (A) y el cuarto (D) conmutadores de punto de ajuste. El segundo es para el segundo (B) y el tercero (C). Lo siguiente es la sustitución para habilitar el relé. Y, finalmente, la sustitución "Ctrl" que no se utiliza en el programa y en el modelo en consideración. No puedes escribirlo.

 #define getAD PORTB.5 #define getBC PORTB.4 #define RL PORTD.0 #define Ctrl PIND.2 

Las variables A, B, C se utilizan para almacenar el número de posición de los tres interruptores correspondientes y tomar valores de 0 a 9.

 unsigned char A,B,C; 

Variable i: el valor actual del número de décimas de minuto (6 segundos), es decir, el número del "tic" mínimo del relé. La variable t es el número de décimas de minuto (ticks) recibidas del maestro.

 unsigned int i=0,t; 

La función principal del programa se presenta a continuación. En las primeras 6 líneas no entendí. Se forman utilizando la utilidad auxiliar CodeWizadAVR y están asociados con la presencia de cuarzo externo a 10 MHz.

 void main(void) { #pragma optsize- CLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif 

Las siguientes dos líneas configuran el puerto B de nuestro MK. Según el esquema, colocamos los 4 bits más bajos en la entrada y los más significativos en la salida (PB7 no se usa y PB6 es inútil, pero, en teoría, la salida). Por lo tanto, de acuerdo con los principios de configuración de MK, que no describiré, escribimos el número 240 en el registro DDRB (F0 en notación hexadecimal). El nivel de salida inicial es "1", excepto el PB7 innecesario. Y por si acaso, conectemos las "resistencias pull-up" de MK a las entradas, aunque ya estén instaladas en el circuito. Para hacer esto, configuremos el registro PORTB en 7F en notación hexadecimal.

 PORTB=0x7F; DDRB=0xF0; 

El puerto D se configura de la misma manera: todos los pines en la entrada, excepto los dos inferiores. Las "resistencias pull-up" en la entrada y el nivel de salida inicial "1" en la salida son similares.

 PORTD=0x7D; DDRD=0x03; 

Las siguientes cinco líneas se relacionan con la configuración de uno de los temporizadores MK. Este temporizador tiene dieciséis dígitos, es decir, proporciona una puntuación de hasta 2 ^ 16 = 65536. La frecuencia de conteo está determinada por la frecuencia del reloj MK y el coeficiente de división (uno de los cinco predefinidos). En el programa descrito, se decidió mantener una cuenta durante 6 segundos (el paso mínimo de la tarea), luego aumentar la variable i en 1 y restablecer el temporizador al comienzo del conteo. Para garantizar lo anterior, debe tomar la relación de división máxima de 1024 y contar hasta 58594. Esta última es fácil de calcular. Frecuencia MK - 10,000,000 Hz. Usando una relación de división de 1024, la frecuencia del temporizador será de 10,000,000 / 1,024 = 9,765.625 Hz, y el período será de 1,024,000 / 10,000,000 = 0.0001024 s. En 6 segundos, se apilarán 6 / 0.0001024 = 58593.75 de dichos períodos. Este número se encuentra dentro del temporizador de 16 bits, pero no es un entero, por lo que debe redondear a 58594. En este caso, el error de nuestro relé de tiempo será insignificante: 58594-58593.75 = 0.25; 0.25 * 0.0001024 = 0.0000256; 0.0000256 * 999 = 0.0255744. Es decir, durante el período de tiempo máximo posible (99,9 minutos), la inexactitud de este relé de tiempo será de aproximadamente 25,6 milisegundos, lo cual es bastante aceptable en la práctica. Por cierto, el fabricante también estipula el error del dispositivo, y nuestro error no será peor. En el registro de configuración del temporizador TCCR1B, escriba el valor 5. Sin entrar en detalles, esto significa que se inicia el temporizador y el coeficiente de división es 1024. En el registro TCNT1, escribimos el valor 0. Este registro es de 16 bits y se divide en dos mitades de 8 bits: la más joven (L ) y senior (H). El valor se escribe en él, desde donde el temporizador seguirá contando. Necesitamos contar desde cero. El valor OCR1A registra antes de que el temporizador leerá, después de lo cual llamará a la función de interrupción. En este momento, se interrumpe la función principal del programa y se realizan las acciones especificadas en la función de esta interrupción. Después de practicar la interrupción, la función principal continuará ejecutándose. Este valor, como se dijo anteriormente, es igual a 58594 (E4E2 en notación hexadecimal). Dado que el registro OCR1A también se divide en dos mitades, escribimos el valor anterior en partes.

 TCCR1B=0x05; TCNT1H=0x00; TCNT1L=0x00; OCR1AH=0xE4; OCR1AL=0xE2; 

Las siguientes dos líneas configuran la resolución de las interrupciones correctamente (no entre en detalles).

 TIMSK=0x40; #asm("sei") 

En el ciclo principal, los interruptores de configuración se sondean constantemente (de acuerdo con el algoritmo en la descripción del circuito) utilizando 30 ms de retraso para un funcionamiento correcto y estable. Al establecer el valor "0" en PORTB.5 (getAD = 0), preparamos el primer interruptor. Sus conclusiones están conectadas al puerto D del MK a los pines 6, 5, 4, 3. La dirección es de la más joven a la más antigua. Es decir, el bit de orden inferior del conmutador está conectado al bit de orden relativamente bajo (bit 3) del puerto MK. Por lo tanto, para recibir información del puerto D del MK en la posición del primer conmutador, es necesario hacer un desplazamiento bit a la derecha en tres posiciones (PIND >> 3), invertir los bits recibidos con la operación "~" (ya que la información vendrá en "0", según el esquema) y restablezca los cuatro bits altos innecesarios del valor de 8 bits recibido. La última operación se realiza mediante la multiplicación lógica en bits del resultado por el número 15 (00001111 en representación binaria). Después de esta operación, a la variable A se le asignará el valor de posición del primer interruptor. A continuación, se apaga el primer interruptor y se preparan el segundo y el tercero. El valor del segundo conmutador a la variable B se toma del puerto B del MK de manera similar, pero sin una operación de cambio, ya que los terminales de este conmutador están conectados a los pines más bajos del puerto B del MK y también en forma co-direccional. La información del tercer cambio a la variable C se elimina de la misma manera que la primera. Después de eso, los interruptores segundo y tercero (getBC = 1) están "cerrados" y el valor establecido (el número de décimas de minuto) de los tres interruptores se calcula en la variable t.

 while(1){ delay_ms(30); getAD=0; delay_ms(30); A=(~(PIND>>3)&15); delay_ms(30); getAD=1; getBC=0; delay_ms(30); B=(~PINB)&15; C=(~(PIND>>3)&15); delay_ms(30); getBC=1; t=100*A+10*B+C; } } 

La comparación de esta variable y una variable similar en tiempo real ocurre en la función de interrupción.

 interrupt [TIM1_COMPA] void timer1_compa_isr(void){ i+=1; if(i>=t){ RL=0; }else{ RL=1; } TCNT1H=0x00; TCNT1L=0x00; } 

Si la última variable excede el valor establecido, el "relé de ejecución" (RL = 0) se encenderá en "0". Además, se apagará si, al mismo tiempo, los interruptores se configuran en un valor mayor que el que se ejecutó en la variable i. En la misma función de interrupción, la variable i aumenta en 1 y el temporizador se restablece a 0.

Los bits de FUSIBLE se cancelaron de MK y se dejaron sin cambios. Los analicé, todo está bien allí.





Por lo tanto, no solo se copió el diagrama del dispositivo, sino que también se desarrolló un programa MK, que no difiere en funcionalidad del propietario. Además, a nivel de software se hizo posible cambiar de manera bastante flexible (y, lo más importante, libre) los parámetros de tiempo del dispositivo y usar la salida de control (No. 1 en el terminal) en varias funcionalidades. El programa es tan simple que puede (incluso mejor) escribirse en ensamblador, pero aún no lo estoy haciendo.

Source: https://habr.com/ru/post/es414345/


All Articles