소프트웨어 UART에서 시작 비트 감지


9

GPIO 핀을 사용하여 마이크로 컨트롤러에 소프트웨어 UART를 작성하는 실험을하고 있습니다. 이는 더 많은 UART 포트가있는 uC를 사용하는 새로운 디자인이 구현 될 때까지 프로젝트에 UART 채널을 일시적으로 추가하는 것입니다.

내가 어려움을 겪고있는 것은 직렬 스트림에서 시작 비트를 올바르게 감지하는 것입니다. 스트림의 소스는 외부이며 장치의 전원을 켤 때 신경 쓰지 않습니다. 따라서 내 장치의 전원이 켜지고 바이트 전송 중에 데이터 비트가 표시되기 시작합니다. 의심 할 여지없이, 시작 비트와 다른 고 / 저 전환 간의 차이를 알 수 없으므로 소프트웨어 UART가 잘못된 값을 읽게됩니다.

이것이 UART 채널에서 불가피한 문제입니까? 또는 uC 제조업체가 하드웨어 UART에 사용하는 영리한 트릭이 있습니까?


좋은 질문. 외부 장치가 문자를 계속 전송합니까? 그렇지 않으면 시작 비트와 정지 비트가 정렬되어 있는지 확인해야합니다. 그리고 그 사이의 데이터가 당신의 체크 (합계 / 비트)와 일치한다면?
Paul

외부 UART 스트림이 프리앰블을 보낼 수 있습니까? 시작 비트와 다른 스트림이 수신되고 있음을 나타내는 특수 데이터의 스트림처럼? 그렇게 할 수 있다면, 전송 도중에 전원을 켜야하는지에 따라 데이터가 잘못된 지 알 수 있습니다.
Funkyguy

1
직렬 스트림에 유휴 기간이 충분하지 않은 경우이 시간에서 복구 할 가능성이 없습니다. "정지"비트를 예상하지 못한 경우 부분 솔루션이 제공 될 수 있습니다. 그런 다음 상태를 재설정하고 다시 시도 할 수 있습니다.
유진 Sh.

1
특별한 프리앰블이 필요하지 않습니다. 한 문자 (inc.start, stop bits)보다 더 긴 휴식 일뿐입니다. 또는 10 개 이상의 정지 비트가 연속으로 표시됩니다.
Brian Drummond

2
@Fuaze, 외부 장치는 긴 문자 스트림을 지속적으로 전송하지만 가끔 유휴 상태입니다. 최악의 경우, 처음 유휴 상태가 될 때까지 입력을 무시할 수 있습니다.
Dan Laks

답변:


5

1.5 비트 시간과 같이 나머지 데이터 스트림에서 쉽게 식별 할 수있는 정지 비트 길이를 사용하는 경우 전송 중 전송을 쉽게 시작할 수 있습니다. 그러나 이로 인해 오버 헤드가 증가합니다. 정지 비트의 길이를 늘리면 사용 가능한 총 데이터 처리량이 줄어 듭니다.

버스를 많이 사용하지 않고 프레임 사이에 빈틈이있는 경우, 이러한 간격 중 하나가 발생할 때까지 기다린 후 첫 번째 고속 전송을 시작하는 것이 문제 일 수 있습니다. 다음 시작 비트.

데이터 크기의 수는 프레임 크기와 마찬가지로 예측 가능해야합니다. 따라서 버스 용량의 100 %를 사용하고 정지 비트가 단일 비트 시간 인 경우에도 여전히 데이터 비트를 찾을 수 있어야합니다. 충분한 프레임을 수집하면 비트를 시작하십시오. 모든 프레임에는 하이로 전환이 보장됩니다. 정지 비트는 항상 높은 비트입니다. 시작 비트는 항상 낮은 비트입니다. 데이터가 무작위 (또는 임의의 임의)라고 가정하면 프레임 크기의 버퍼를 만들고 모든 비트를 설정 한 다음 버퍼가 1이 될 때까지 프레임을 수집 하고이 버퍼에 AND로 AND하는 것과 같은 간단한 작업을 수행 할 수 있습니다 비트 세트. 이 비트는 정지 비트입니다. 그 다음이 시작 비트입니다. 짜잔! 당신은 그것을 찾았습니다.

패리티 비트를 사용하는 경우 또 다른 옵션은 두 프레임 분량의 데이터를 잡고 첫 번째 하위 비트를 시작 비트로 선택한 다음 체크섬을 계산하고 패리티 비트와 비교하는 것입니다. 일치하면 시작 비트를 찾은 것입니다. 그렇지 않은 경우 다음 하위 비트를 선택하고 양호한 체크섬을 얻을 때까지 반복하십시오. 두 개의 데이터 프레임에서 유효한 시작 비트로 체크 아웃 된 비트를 찾을 수 없으면 데이터가 손상된 것이므로 두 개의 프레임을 더 가져와야합니다.


시작 및 정지 비트 만 살아남을 때까지 프레임을 AND로 깔끔하게 정리하십시오. 내 특정 응용 프로그램에는 너무 많은 오버 헤드가 있지만 그럼에도 불구하고 영리합니다.
Dan Laks

외부 장치가 OP가 제어 할 수없는 것 (질문에 대한 이전 의견에서 언급 한 것)은 정지 비트의 길이를 변경할 수 없을 것입니다.
tcrosley 2016 년

이 답변을 작성하기 시작했을 때는 그 의견이 없었습니다. 그러나 내가 나열한 다른 세 가지 옵션은 정지 비트 길이가 고정 된 경우에도 여전히 적용됩니다.
Dr. Funk

3

하드웨어 UART도 같은 문제가 있습니다. 그러나 어쨌든 짧은 순서로 스스로를 해결하는 것이 일반적입니다. 각 프레임의 끝에서 정지 비트를 확인하고 높지 않은 경우 프레임을 버리고 다음 고에서 저 전이를 기다립니다. 소스의 데이터가 완전히 병리 적이 지 않다고 가정하면 (예를 들어, "UUUU의 긴 문자열 또는 ASCII 0x55") UART는 결국 실제 시작 비트로 "보관"합니다.


1

8N1 전송을 가정합니다.

9 개의 높은 비트 또는 낮은 비트의 문자열을 연속적으로 기다려야합니다.

높으면 데이터의 유휴 간격 또는 0xFF 문자 및 STOP 비트
또는
낮은 시작 비트 및 NULL 0x00 문자를 나타냅니다.

이러한 조건 중 하나가 재 동기화를 허용합니다.

속도를 높이려면 : 데이터에서 사용할 수없는 특정 문자를 알고 있으면 각 비트에 대해 수신 데이터를 반복적으로 (사실 후) 구문 분석 할 수 있으며 넌센스 (높은 비트 세트, 낮은 비트) 대소 문자, 제어 코드, 문장 부호 등) 뒤에 유효한 문자를 사용하면 재 동기화 할 수 있습니다.

내장 UART 주변 장치를 사용할 때 비트 단위 평가를 수행 할 수없고 모든 프레이밍 오류 비트 및 이러한 오류가 발생할 때마다 (특히 전원이 켜질 때마다) 재설정해야한다는 점을 기억해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.