Era uma vez me deparei com o relógio digital eletrônico VL-76-S, novo, em embalagem, mas em mau estado. Não foram encontrados defeitos nas placas de circuito impresso no interior. Portanto, casamento de fábrica, firmware quebrado.
Vista geral do relé.O que nos surpreendeu foi o uso do microcontrolador popular e simples ATTiny2313. Externamente, esse projeto consiste em um mestre na forma de três décadas de comutadores e um terminal ao qual a energia de 220V e os contatos de um relé EM estão conectados. O intervalo da tarefa é de 0,1 ... 99,9 minutos. em incrementos de 0,1 min (6 segundos). Não há circuitos e firmware nesse design na Internet, o que não é surpreendente. Sem pensar duas vezes, decidi desenhar o circuito a partir das placas de circuito impresso e, no futuro, escrever o programa no MK.
O design consiste em três placas de circuito impresso interconectadas. Na primeira placa, são feitas uma fonte de alimentação e um relé de execução TRA3. A fonte de alimentação é feita de acordo com um circuito sem transformador: capacitores de resfriamento são usados para reduzir a tensão. Na segunda placa está o ATTiny2313 MK e outros elementos auxiliares. Na terceira placa estão os interruptores (pontos de ajuste) e um LED de controle.
Foto da terceira prancha na parte de trás.Vou começar a descrição com o terceiro quadro. Os interruptores são interruptores de 10 posições. Não há marcação neles, cada um deles tem 5 contatos. Portanto, dependendo da posição, determinados contatos são fechados em várias combinações. Ao ligar para os contatos, percebi imediatamente o padrão: uma saída fixa (geral) é fechada com as outras quatro saídas (informações) de acordo com a representação binária do número correspondente ao número da posição selecionada. Por exemplo, se a posição "3" for selecionada, a saída geral (quinto em uma linha) será fechada com a saída do terceiro e quarto, já que o número "3" na representação binária é "0011". Aqui está uma mudança tão complicada. E há três deles. Eles são conectados via conectores XP1 e XP2 à segunda placa com o MK. Um conector XP3 conecta um LED e outras porcarias não soldadas desnecessárias, para as quais há um lugar na placa. Provavelmente, esse é um comutador DPDT comum de seis pinos (como o quadrado, PB22E06, por exemplo). Talvez a placa seja universal, mas não é usada neste modelo em particular.

Foto da segunda placa (principal).Chamando os contatos dos comutadores, não entendi imediatamente o princípio de sua conexão com as portas MK. Na placa principal, 8 transistores SMD são imediatamente evidentes. Mais tarde, ele descobriu que esses transistores são usados como pares de diodos com um ânodo comum. Suas bases vão para portas MK, e coletores e emissores vão para trocar contatos. Então eles me explicaram que nesses casos existem pares de diodos, eles tocam como transistores, mas não são transistores. No total, temos 16 condutores deixando os pares de diodos na terceira placa. Três quartos deles (12 peças) chegam aos contatos de informações dos comutadores (três a quatro) e quatro permanecem livres. É fácil adivinhar que, teoricamente, eles são fornecidos para o quarto comutador, o que não está de alguma forma ausente, porque não há espaço para ele no quadro. No entanto, para não violar a lógica do raciocínio, mencionarei esse quarto interruptor imaginário. As extremidades comuns do segundo e terceiro, bem como o primeiro e o quarto comutadores (mas o quarto não fornece a placa) são conectados em pares por faixas na placa principal nos conectores XS1 e XS2. Esses dois pares estão conectados às saídas dos grupos de transistores. Esses dois grupos idênticos são feitos nos transistores BC857 e BC847 (estruturas diferentes). Suas entradas estão conectadas ao MK. Ao aplicar um "0" lógico à entrada deste grupo, a saída também será um "0" lógico. Além disso, na placa há um conector XP2 para o firmware MK, conectado aos terminais SPI da interface MK, um conector XS3 para um LED e um conector XP1 conectado por um cabo à primeira placa. Deve-se lembrar que algumas das portas MK podem ser usadas tanto para SPI (para firmware) quanto para entrada / saída comum (trabalho no circuito).
Tudo isso se reflete nos diagramas que desenhei primeiro no rascunho, depois no SPlan. As classificações dos elementos de rádio que não foram marcados (por exemplo, capacitores SMD) estão ausentes nos diagramas, não são tão importantes. Primeiro, darei um diagrama da placa principal e da placa com os instaladores (assinaturas das figuras abaixo).
Esquema do prato principal.Esquema da terceira placa com levantadoresConsidere como o interrogatório de cada levantador. Os sinais das portas PB4 e PB5 MK, lógica "0", abrem os transistores VT2 e VT1, seguidos de VT4 e VT3, conectando-se aos contatos comuns do barramento zero dos comutadores nº 1 e nº 2-nº 3, respectivamente. Isso acontece por sua vez. Primeiro, o "0" lógico vem do PB4 (o PB5 até agora foi definido como "1"), conectando o segundo e o terceiro comutadores. Nesse estado, os valores dos sinais são gravados sucessivamente pelo controlador das portas de entrada PB3, PB2, PB1, PB0 através dos grupos de diodos 2VD1 ... 2VD4 do segundo e do quarto comutador ausente. Imediatamente, os valores dos sinais dos pinos PD6, PD5, PD4, PD3 MK são fixos, aos quais os sinais do primeiro e terceiro comutadores passam pelos grupos de diodos 2VD5 ... 2VD8. Porém, como apenas o segundo e o terceiro comutadores são conectados por um contato comum, os sinais do segundo comutador chegarão às primeiras portas especificadas do MK e o quarto será ignorado. Da mesma forma, os sinais do terceiro comutador chegarão à segunda metade do MK e o primeiro será ignorado. Nesse estágio, o controlador sabe em quais posições o segundo e o terceiro comutadores estão instalados. Depois disso, o PB4 é definido como "unidade", desligando o segundo e o terceiro comutador, e o PB5 é definido como "zero". Nesse caso, o primeiro e o quarto comutador que falta estão conectados por uma extremidade comum ao "caso". O interrogatório ocorre exatamente da mesma forma que no caso anterior, mas agora os sinais daqueles switches que foram ignorados na última vez serão gravados. Assim, o controlador conhece as informações de posição de todos os interruptores. Esse processo é semelhante ao polling de um teclado matricial, mas, neste caso, uma matriz de 4 camadas com dimensões de 2 por 2 com um elemento ausente.
Resistores R8 ... R15 - pull-ups. Embora fosse possível "puxar" o próprio MK. Frequência precisa de relógio MK fornece quartzo a 10 MHz. Circuito de redefinição R1 e C4 - MK. Não há nada mais interessante neste fórum.
Foto da primeira placa (de força) na lateral dos elementos.
Foto da primeira placa (de energia) na parte de trás.Vamos seguir para o esquema da primeira placa (Fig. Acima). O esquema parecia muito interessante e, em alguns lugares, incompreensível.
Esquema da primeira placa (de potência).C1C2 - para reduzir a tensão. R1 - para descarregar o acima. Após a ponte de diodos DB1 são dois eletrólitos. Para complicar o circuito (ou para a confiabilidade) - esquema de estabilização em cascata VT3R6VD3 - VT7R12VD5. O VD5 é semelhante a um transistor SMD de emissor não utilizado. Isso fornece uma tensão CC estabilizada de 12V. Em seguida é o regulador linear VR1 em 5V. Ao mesmo tempo, a tensão é removida da ponte de diodos DB1 através do diodo VD2 para outro estabilizador de 24V VT1R3VD1. Essa tensão é fornecida à bobina do relé EM Rel1 e ao R17. O último não está claro o porquê. Na outra extremidade do R17, vem o sinal do grupo de transistores VT9VT10. O circuito deste grupo é semelhante ao circuito na placa principal. Um sinal de uma porta MK PB6 separada chega à entrada desse grupo de transistores através do conector. Por que é necessário? Por que conectar um resistor R17 a 24V? Provavelmente, havia uma idéia de que, em vez de um resistor, você pode colocar outra coisa, por exemplo, um LED de controle interno, programando a porta PB6 MK de uma certa maneira. Ou um nó de comutação adicional. Mas, mesmo assim, isso é um absurdo, como disseram meus engenheiros de rádio, depois de olhar para o quadro de projetos. A segunda extremidade do relé EM Rel1 está conectada a um grupo de transistores semelhante VT2VT5 e à porta MK PD0. O sinal "0" desta porta liga o relé EM em execução. O mais interessante é que o LED externo está conectado não paralelamente ao relé EM, mas ao gap de emissor do transistor VT2, além disso, através de dois conectores (passando pela placa principal). No terminal, os pinos 1 e 2, a julgar pelo adesivo no relé, permanecem vazios. Porém, no circuito, o contato n ° 2 é conectado a um fio comum e o contato n ° 1 é alimentado à entrada do grupo de transistores VT6VT8. A saída deste grupo é enviada para a porta MK PD2. Mais tarde, li na especificação deste modelo de relé que esses contatos são usados para controlar outros modelos de relés, montados no mesmo caso. O modelo que estou considerando não envolve controle, mas pode ser implementado ao escrever um programa no MK, pois o esquema oferece essa oportunidade. Sob o controle pode significar um início, redefinição (tanto no modo "gatilho" quanto no normal) e tudo o que vem à mente. As especificações para outros relés mostram diagramas de tempo que mostram o comportamento dos relés, dependendo de um determinado sinal de controle. Também diz abaixo: a pedido do cliente, podemos implementar qualquer diagrama possível. E o último momento do esquema. Esse sinal de controle do terminal n ° 1 também chega ao transistor VT4 inútil, alimentado por uma tensão de 12V. Isso, novamente, é uma complicação do esquema. Ou talvez ainda exista alguma idéia? Eu não mergulhei profundamente. Ficarei feliz em quaisquer comentários.
As marcações dos terminais dos conectores são assinadas através do ponto após o nome do próprio conector. Os algarismos romanos após o símbolo “~” indicam conclusões inúteis e ausentes. Estes últimos não são poucos no esquema, mas não vou me debruçar sobre eles. Abaixo, descrevo cada placa com as designações de conectores, conclusões e elementos básicos.
Esboços do quadro.Considere a descrição do código fonte do programa MK. O programa em si é simples e foi escrito por mim no CVAVR por 20 minutos. Vou discutir o algoritmo pelo qual o programa será executado. Esta informação pode parecer bastante banal para alguns, mas não será supérflua para iniciantes. Na minha versão do algoritmo, os temporizadores no relé de tempo serão interrogados não uma vez, mas continuamente. Além disso, a pesquisa continuará mesmo após o disparo do relé. Isso permitirá que você faça ajustes em qualquer lugar. Talvez esse algoritmo não coincida com o algoritmo original para a operação desse relé, mas não estou familiarizado com o algoritmo original. É no exemplo do algoritmo mencionado acima que a descrição do programa será considerada.
Código fonte do programa C com descrição.Conectamos a biblioteca para trabalhar com o ATTiny2313 MK, bem como a biblioteca de funções de atraso.
#include <tiny2313.h> #include <delay.h>
A seguir, fazemos a substituição macro necessária, de acordo com as atribuições de circuito das portas MK. Essas substituições são convenientes porque no texto do programa, em vez de, por exemplo, PORTB.5, você pode escrever getAD, o que é mais conveniente. A compilação getAD será interpretada como PORTB. Portanto, a primeira substituição são as saídas para conectar as primeiras (A) e quarta (D) chaves de ajuste. O segundo é para o segundo (B) e o terceiro (C). A seguir está a substituição para ativar o relé. E, finalmente, a substituição “Ctrl” que não é usada no programa e no modelo em consideração. Você não pode escrever.
#define getAD PORTB.5 #define getBC PORTB.4 #define RL PORTD.0 #define Ctrl PIND.2
As variáveis A, B, C são usadas para armazenar o número da posição dos três interruptores correspondentes e assumir valores de 0 a 9.
unsigned char A,B,C;
Variável i - o valor atual do número do décimo de minuto (6 segundos), ou seja, o número do “tick” mínimo do relé. A variável t é o número de décimos de minuto (ticks) recebidos do mestre.
unsigned int i=0,t;
A principal função do programa é apresentada abaixo. Nas primeiras 6 linhas eu não entendi. Eles são formados usando o utilitário auxiliar CodeWizadAVR e estão associados à presença de quartzo externo a 10 MHz.
void main(void) { #pragma optsize- CLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif
As duas linhas a seguir configuram a porta B do nosso MK. De acordo com o esquema, colocamos os 4 bits mais baixos na entrada e os mais significativos na saída (PB7 não é usado e PB6 é inútil, mas, em teoria, a saída). Portanto, de acordo com os princípios da configuração MK, que não descreverei, escrevemos o número 240 no registro DDRB (F0 em notação hexadecimal). O nível de saída inicial é "1", exceto o PB7 desnecessário. E, por precaução, vamos conectar os “resistores pull-up” do MK às entradas, mesmo que elas já estejam instaladas no circuito. Para fazer isso, vamos definir o registro PORTB como 7F em notação hexadecimal.
PORTB=0x7F; DDRB=0xF0;
A porta D. está configurada da mesma maneira: todos os pinos da entrada, exceto os dois inferiores. Os "resistores pull-up" na entrada e o nível de saída inicial "1" na saída são semelhantes.
PORTD=0x7D; DDRD=0x03;
As cinco linhas a seguir estão relacionadas à configuração de um dos temporizadores MK. Esse timer tem dezesseis dígitos, ou seja, fornece uma pontuação de até 2 ^ 16 = 65536. A frequência de contagem é determinada pela freqüência do relógio MK e pelo coeficiente de divisão (um dos cinco predefinidos). No programa descrito, foi decidido manter uma conta por 6 segundos (a etapa mínima da tarefa), depois aumentar a variável i em 1 e redefinir o timer para o início da contagem. Para garantir o que foi dito acima, você precisa levar a taxa de divisão máxima de 1024 e contar para 58594. A última é fácil de calcular. Frequência MK - 10.000.000 Hz. Usando uma taxa de divisão de 1024, a frequência do temporizador será 10.000.000 / 1.024 = 9.765.625 Hz e o período será 1.024.000 / 10.000.000 = 0,0001024 s. Dentro de 6 segundos, 6 / 0.0001024 = 58593.75 desses períodos serão empilhados. Esse número está dentro do cronômetro de 16 bits, mas não é um número inteiro; portanto, você deve arredondar para 58594. Nesse caso, o erro do nosso relé de tempo será insignificante: 58594-58593.75 = 0.25; 0,25 * 0,0001024 = 0,0000256; 0,0000256 * 999 = 0,0255744. Ou seja, para o período máximo possível de tempo (99,9 minutos), a imprecisão desse relé de tempo será de aproximadamente 25,6 milissegundos, o que é bastante aceitável na prática. A propósito, o fabricante também estipula o erro do dispositivo, e nosso erro não será pior. No registro de configuração do timer TCCR1B, escreva o valor 5. Sem entrar em detalhes, isso significa que o timer inicia e o coeficiente de divisão é 1024. No registro TCNT1, escrevemos o valor 0. Esse registro é de 16 bits e é dividido em duas metades de 8 bits: o mais novo (L ) e sênior (H). O valor é gravado nele, de onde o temporizador continuará contando. Precisamos contar do zero. O valor OCR1A registra antes do qual o timer lerá e depois chamará a função de interrupção. Nesse momento, a função principal do programa é interrompida e as ações especificadas na função dessa interrupção são executadas. Após praticar a interrupção, a função principal continuará sendo executada. Este valor, como foi dito acima, é igual a 58594 (E4E2 em notação hexadecimal). Como o registro OCR1A também é dividido em duas metades, escrevemos o valor acima em partes.
TCCR1B=0x05; TCNT1H=0x00; TCNT1L=0x00; OCR1AH=0xE4; OCR1AL=0xE2;
As próximas duas linhas configuram a resolução das interrupções corretamente (não entre em detalhes).
TIMSK=0x40; #asm("sei")
No ciclo principal, as chaves do setter são pesquisadas constantemente (de acordo com o algoritmo na descrição do circuito) usando atrasos de 30 ms para operação correta e estável. Ao definir o valor "0" em PORTB.5 (getAD = 0), preparamos o primeiro comutador. Suas conclusões estão conectadas à porta D do MK nos pinos 6, 5, 4, 3. A direção é do mais novo ao mais antigo. Ou seja, o bit de ordem inferior do comutador está conectado ao bit de ordem relativamente baixa (bit 3) da porta MK. Portanto, para receber informações da porta D do MK na posição do primeiro comutador, é necessário fazer um deslocamento bit a bit para a direita em três posições (PIND >> 3), inverter os bits recebidos com a operação “~” (já que as informações entrarão em “0”, conforme o esquema) e redefina os quatro bits altos desnecessários do valor de 8 bits recebido. A última operação é realizada pela multiplicação lógica por bit do resultado pelo número 15 (00001111 na representação binária). Após esta operação, a variável A receberá o valor da posição do primeiro interruptor. Em seguida, o primeiro interruptor é desligado e o segundo e o terceiro são preparados. O valor do segundo comutador para a variável B é obtido da porta B do MK da mesma forma, mas sem uma operação de turno, uma vez que os terminais deste comutador estão conectados aos pinos mais baixos da porta B do MK e também de forma bidirecional. As informações do terceiro comutador para a variável C são removidas da mesma maneira que as do primeiro. Depois disso, o segundo e o terceiro comutadores (getBC = 1) são "fechados" e o valor definido (o número de décimos de minuto) dos três comutadores é calculado na variável 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; } }
A comparação dessa variável e uma variável em tempo real semelhante i ocorre na função de interrupção.
interrupt [TIM1_COMPA] void timer1_compa_isr(void){ i+=1; if(i>=t){ RL=0; }else{ RL=1; } TCNT1H=0x00; TCNT1L=0x00; }
Se a última variável exceder o valor definido, o "relé em execução" (RL = 0) será ativado em "0". Além disso, ele será desativado se, ao mesmo tempo, os comutadores estiverem configurados para um valor maior que o que foi executado na variável i. Na mesma função de interrupção, a variável i é aumentada em 1 e o timer é redefinido para 0.
Os bits do FUSE foram baixados do MK e mantidos inalterados. Eu os analisei, está tudo bem lá.

Assim, não apenas o diagrama do dispositivo foi copiado, mas também foi desenvolvido um programa MK, que não difere em funcionalidade do proprietário. Além disso, tornou-se possível, no nível do software, alterar de maneira bastante flexível (e, o mais importante, gratuita) os parâmetros de tempo do dispositivo e usar a saída de controle (Nº 1 no terminal) em várias funcionalidades. O programa é tão simples que pode (ainda melhor) ser escrito em assembler, mas ainda não o estou fazendo.