Detectando o bit inicial no software UART

9

Estou experimentando escrever um software UART no meu microcontrolador usando pinos GPIO. Isso é para adicionar temporariamente um canal UART em um projeto até obtermos o novo design implementado que usa um uC com mais portas UART.

Estou com dificuldade em detectar corretamente um bit de início em um fluxo serial. A fonte do fluxo é externa e não se importa quando meu dispositivo é ligado. Portanto, é muito provável que meu dispositivo seja ligado e comece a ver bits de dados no meio de uma transmissão de bytes. Sem dúvida, isso fará com que o UART do meu software leia valores incorretos, pois não será capaz de diferenciar um bit de início e qualquer outra transição de alto para baixo.

Esse é um problema inevitável com um canal UART? Ou existe algum truque inteligente que os fabricantes de uC usam em seus UARTs de hardware?

Dan Laks
fonte
Boa pergunta. O seu dispositivo externo envia caracteres continuamente? Caso contrário, verifique se o bit inicial e o bit final estão alinhados. E se os dados entre eles corresponderem ao seu cheque (soma / bit)?
Paul
Você pode fazer com que o fluxo UART externo envie um preâmbulo? Como um fluxo de dados especiais para indicar a entrada de um fluxo que seria distinto de um bit inicial? Se você pudesse fazer isso, seria capaz de dizer se os dados estão errados, se você ligar no meio de uma transmissão ou não.
Funkyguy
11
Se o fluxo serial não contiver um período de inatividade suficientemente longo - é improvável que sua arte se recupere disso. A solução parcial pode surgir caso você não esteja recebendo o bit "stop" onde esperado. Então você seria capaz de redefinir o estado e tentar novamente.
Eugene Sh.
11
Você não precisa de um preâmbulo especial ... apenas um descanso ocasional por mais de um caractere (incluindo iniciar, parar bits). Ou mais de 10 bits de parada seguidos, o que é a mesma coisa.
Brian Drummond
2
@Fuaze, o dispositivo externo envia um longo fluxo de caracteres continuamente, mas fica ocioso ocasionalmente. Na pior das hipóteses, posso simplesmente ignorar a entrada até a primeira vez em que ela estiver ociosa.
quer

Respostas:

5

Se você usar um tamanho de bit de parada que seja facilmente discernido do restante do fluxo de dados, como um tempo de 1,5 bits, será fácil começar a receber a transmissão intermediária. No entanto, isso tem um custo de sobrecarga aumentada. Seu rendimento total de dados disponível sofrerá à medida que você aumentar a duração do seu bit de parada.

Se você não estiver usando o barramento com muita freqüência e com intervalos entre os quadros, pode ser apenas uma questão de esperar que um desses intervalos ocorra e depois pegar a primeira transmissão oi-lo no início do seu próximo bit de início.

Lembre-se de que o número de bits de dados deve ser previsível, assim como o tamanho do quadro, portanto, mesmo se você estiver usando 100% da capacidade do barramento e seu bit de parada for um único bit, ainda será possível encontrar o bit de início se você coletar quadros suficientes. É garantido que todos os quadros tenham uma transição oi-lo. O bit de parada é aquele que está sempre alto. O bit inicial é aquele que é sempre baixo. Supondo que seus dados sejam aleatórios (ou aleatórios o suficiente), você pode fazer algo tão simples quanto criar um buffer do tamanho do seu quadro, definir cada bit nele e continuar coletando quadros e ANDando-os nesse buffer até que o buffer tenha apenas 1 conjunto de bits. Este bit é o seu bit de parada. O seguinte é o seu bit de início. Voila! Você encontrou.

Se você estiver usando um bit de paridade, outra opção seria coletar dois quadros de dados, escolher o primeiro bit baixo como o bit inicial e calcular a soma de verificação e comparar com o bit de paridade. Se corresponder, você (provavelmente) encontrou o bit inicial. Caso contrário, escolha o próximo bit baixo e repita até obter uma boa soma de verificação. Se você não conseguir encontrar um bit em seus dois quadros de dados com check-out válido, então seus dados foram corrompidos e você precisará pegar mais dois quadros.

Dr. Funk
fonte
Idéia bacana de AND frames juntos até que apenas os bits de início e parada sobrevivam. Isso vai sobrecarregar demais o meu aplicativo específico, mas inteligente, no entanto.
quer
Se o dispositivo externo é algo sobre o qual o OP não tem controle (o que ele declarou em um comentário anterior à pergunta), é improvável que ele consiga alterar a duração do bit de parada.
precisa saber é o seguinte
Esse comentário não havia sido feito no momento em que comecei a escrever esta resposta. No entanto, as outras três opções listadas ainda se aplicam no caso de o comprimento do bit de parada ser fixo.
Dr. Funk
3

UARTs de hardware têm o mesmo problema. Mas geralmente é aquele que se resolve em pouco tempo de qualquer maneira. No final de cada quadro, verifique o bit de parada e, se não estiver alto, descarte o quadro e aguarde a próxima transição de alto para baixo. Supondo que os dados da fonte não sejam totalmente patológicos (por exemplo, seqüências longas de "UUUU" ou ASCII 0x55), o UART acabará "caminhando" até o bit de início real.

Dave Tweed
fonte
1

Assumindo transmissão 8N1.

Você deve esperar por uma sequência de 9 bits altos ou baixos seguidos.

Se alto, isso significará uma lacuna ociosa nos dados ou um caractere 0xFF e um bit STOP
ou,
se for baixo, um bit START e um caractere NULL 0x00.

Qualquer uma dessas condições permitirá ressincronização.

Para acelerar: Se você conhece certos caracteres que não são possíveis nos dados, você pode analisar os dados recebidos repetidamente (após o fato) de cada bit e se obtiver uma série de 7 caracteres sem sentido (conjunto de bits alto, menor maiúsculas e minúsculas, códigos de controle, pontuação ou o que for) seguido de um caractere válido, você pode ter certeza de que está ressincronizado.

Você terá os mesmos problemas ao usar um periférico UART interno e não poderá fazer a avaliação bit a bit, além de lembrar de redefinir todos os bits de erro de estrutura sempre que ocorrerem (especialmente na inicialização).

KalleMP
fonte