Existem várias fontes potenciais de ruído em qualquer circuito. Alguns dos mais comuns incluem:
- Fontes de alimentação mal reguladas;
- Comutação de fontes de alimentação;
- Desacoplamento capacitivo insuficiente dos trilhos de energia próximos ao MCU;
- Acoplamento indutivo de fontes eletromagnéticas próximas (incluindo 50 ou 60Hz da energia da rede elétrica; mesmo se o circuito for alimentado por bateria, ele sofrerá essa interferência quando estiver próximo o suficiente de uma fonte de energia elétrica);
- Fontes de RF próximas à frequência ressonante de um traço na placa de circuito ou em um de seus harmônicos;
- Roteamento de traços de alta corrente na placa de circuito próximo às linhas de sinal;
- Etc.
Além disso (como @jippie mencionou), a inclinação do relógio é uma causa muito comum de erros em qualquer tipo de comunicação serial que usa uma taxa de dados predeterminada. Se você estiver usando um cristal externo e fazendo interface com outro sistema que possa ser razoavelmente preciso, é menos provável que cause problemas. Os osciladores internos, no entanto, podem ter tolerâncias que são várias ordens de magnitude piores que os cristais e tendem a variar mais em faixas de temperatura.
Existem vários testes básicos que podem ser executados em um sistema em execução para determinar a imunidade básica a ruídos (e distorção) da sua interface, incluindo:
- Congelamento (resfrie o circuito até a classificação mínima de seus componentes);
- Cozimento (aqueça até a classificação máxima);
- Exposição ao IME :
- Coloque a placa em cima do cabo de alimentação de um aquecedor de ambiente;
- Tecle um rádio CB nas proximidades do quadro;
- Coloque a placa ao lado do seu roteador sem fio;
- Use fio de conexão longo (em vez de um cabo serial adequadamente construído) para a conexão UART.
Existem muitos outros - na verdade, existem grandes laboratórios de testes dedicados à qualificação EMC .
Em geral, a menos que seja aceitável um nível mínimo de perda de dados, é sempre prudente incluir algum tipo de verificação de erro no seu código de comunicação. Mesmo uma simples soma de verificação é melhor que nada.
A maioria dos erros resulta de três causas: (1) o sinal gerado pelo transmissor não representa dados válidos; (2) o sinal do transmissor não foi recebido como gerado ou (3) o receptor não estava pronto para manipular os dados quando foram recebidos. A causa mais comum que vi para o problema nº 1 é um transmissor que é reconfigurado ou desligado enquanto transmite dados. O problema 2 pode ocorrer facilmente para sinais que viajam pelo "mundo exterior" como resultado de interferências de rádio (telefones celulares podem ser surpreendentemente desagradáveis!), Mas geralmente não deve ocorrer para sinais confinados a uma única placa. O problema nº 3 pode ocorrer porque muitos bytes chegam mais rapidamente do que podem ser processados ou porque o receptor é reconfigurado, desligado ou inicializado durante uma transmissão.
Em muitos casos, é difícil eliminar completamente todos esses problemas; o objetivo de alguém deve ser garantir que o "dano" total causado por eles (probabilidade de ocorrência, vezes o dano por ocorrência) seja aceitávelmente baixo. Isso pode ser feito com mais facilidade, escolhendo uma estimativa pessimista de confiabilidade e, em seguida, projetando um protocolo para que o impacto no desempenho do sistema, mesmo nas piores falhas que eram consistentes com as estimativas, estivesse dentro de limites aceitáveis.
fonte
Erros de enquadramento podem ser causados pelo que o @jippie menciona - o receptor detectou o bit de início e onde espera o bit de parada, os dados são invertidos. Isso também pode ocorrer devido à corrupção de dados causada pela interferência da linha no bit de parada. Você sempre precisa verificar isso para cada byte recebido.
Erros de paridade ocorrem quando a paridade é implementada no link de dados e há uma corrupção que causa uma incompatibilidade de paridade nos dados recebidos. Você sempre precisa verificar isso para cada byte recebido.
A interrupção de recebimento também é considerada um erro, embora seja realmente uma indicação de que os dados recebidos caíram para zero lógico por mais de 1 byte de dados. Normalmente 1 lógico é o estado "ambiente" entre bytes de dados sucessivos e permanece assim. É um retorno aos velhos sistemas de telegrafia, eu acho. Eu não me incomodaria em verificar isso, a menos que você estivesse usando esse "recurso" para indicar (digamos) um comando de redefinição para o receptor.
Erro de saturação é quando um novo byte é recebido antes que o byte anterior seja lido por uma CPU. Um pouco diferente quando um FIFO está envolvido, mas equivale à mesma coisa - dados recebidos válidos são perdidos devido à lentidão da CPU. Sempre verifique isso antes de ler um byte e se o byte faz parte de uma mensagem (ou comando) mais longa, jogue fora toda a mensagem / comando e, de alguma forma, solicite ao transmissor que reenvie toda a mensagem / comando.
Sob execução não é realmente um erro, mas indica ao UART remetente que seu buffer de transmissão está vazio, ou seja, está solicitando um novo byte para transmitir. Você não precisa verificar isso.
fonte
Para lidar com esses erros, você deve implementar um protocolo lógico de nível superior. algo semelhante ao TCP ou verifique a pilha OSI para obter idéias.
basicamente, duas partes importantes para começar são somas de verificação e tempos limite. use um algoritmo para calcular um valor redundante que represente, em uma forma menor, o conteúdo de cada mensagem. depois verifique isso na mensagem recebida. se as somas não corresponderem, é possível que você tenha recebido um erro de enquadramento, ruído de bits, etc., etc., e precisará descartar a mensagem e tentar algum tipo de recuperação, reenviar, sinal NACK (não aceito), etc.
Além disso, certifique-se de implementar tempos limite no seu protocolo de nível superior. se você receber algum tipo de erro de enquadramento, seu UART pode nunca se recuperar e começar a processar novamente. pode estar aguardando o bit de parada em um quadro que o remetente que o UART acha que já foi enviado, mas foi corrompido por ruído, inclinação do relógio, etc. isso enviará qualquer código de entrada para um loop infinito. verifique se você tem um limite sensato de quanto tempo sua leitura de entrada deve esperar até decidir abandonar esta mensagem e, novamente, tente novamente, NACK, abandonar etc.
fonte