Mendeteksi bit mulai di perangkat lunak UART


9

Saya bereksperimen dengan menulis perangkat lunak UART pada mikrokontroler saya menggunakan pin GPIO. Ini untuk sementara menambah saluran UART pada suatu proyek sampai kami mendapatkan desain baru yang diimplementasikan yang menggunakan UC dengan lebih banyak port UART.

Apa yang saya mengalami kesulitan dengan benar mendeteksi bit awal dalam aliran serial. Sumber aliran adalah eksternal dan tidak peduli ketika perangkat saya menyala. Jadi sangat mungkin perangkat saya akan hidup dan mulai melihat bit data di tengah transmisi byte. Tidak diragukan lagi, itu akan menyebabkan perangkat lunak saya UART membaca nilai-nilai yang salah, karena tidak akan dapat membedakan antara bit awal dan transisi tinggi ke rendah lainnya.

Apakah ini masalah yang tak terhindarkan dengan saluran UART? Atau apakah ada beberapa trik pintar yang digunakan pabrikan UC dalam UART perangkat keras mereka?


Pertanyaan bagus. Apakah perangkat eksternal Anda secara terus-menerus mengirim karakter? Jika tidak, Anda harus memeriksa apakah bit mulai dan bit berhenti selaras. Dan jika inbetween data cocok dengan cek Anda (jumlah / bit)?
Paul

Bisakah Anda meminta aliran UART eksternal mengirim pembukaan? Seperti aliran data khusus untuk menunjukkan aliran masuk yang akan berbeda dari bit awal? Jika Anda bisa melakukan itu, maka Anda dapat mengetahui apakah data itu salah jika Anda menyalakan di tengah transmisi atau tidak.
Funkyguy

1
Jika aliran serial tidak mengandung periode idle yang cukup lama - Anda tidak akan pulih dari ini. Solusi parsial dapat datang jika Anda tidak menerima bit "stop" di tempat yang diharapkan. Maka Anda akan dapat mengatur ulang negara dan coba lagi.
Eugene Sh.

1
Anda tidak perlu mukadimah khusus ... hanya istirahat sesekali lebih dari satu karakter (inc.start, stop bits). Atau, 10+ stop bit berturut-turut, yang merupakan hal yang sama.
Brian Drummond

2
@Fuaze, perangkat eksternal mengirimkan aliran panjang karakter secara terus-menerus, tetapi sesekali tidak digunakan. Kasus terburuk, saya bisa mengabaikan input sampai pertama kali idle.
Dan Laks

Jawaban:


5

Jika Anda menggunakan panjang bit stop yang mudah dilihat dari sisa aliran data, seperti waktu 1,5 bit, maka akan lebih mudah untuk mulai menerima transmisi tengah. Namun, ini datang dengan biaya overhead yang meningkat. Total throughput data yang tersedia Anda akan berkurang saat Anda menambah panjang stop bit Anda.

Jika Anda tidak menggunakan bus yang terlalu banyak, dan sering memiliki celah di antara frame, maka itu mungkin hanya masalah menunggu salah satu dari kesenjangan ini terjadi, dan kemudian mengambil transmisi hi-lo pertama sebagai awal dari Anda bit mulai berikutnya.

Perlu diingat bahwa jumlah bit data harus dapat diprediksi, seperti halnya ukuran frame, jadi bahkan jika Anda menggunakan 100% dari kapasitas bus dan stop bit Anda adalah waktu bit tunggal, Anda masih harus dapat menemukan mulai bit jika Anda mengumpulkan frame yang cukup. Setiap frame dijamin memiliki transisi hi-lo di dalamnya. Bit stop adalah yang selalu tinggi. Bit awal adalah yang selalu rendah. Dengan asumsi data Anda acak (atau cukup acak), Anda bisa melakukan sesuatu yang sederhana seperti membuat buffer ukuran frame Anda, mengatur setiap bit di dalamnya, dan kemudian terus mengumpulkan frame dan ANDing ke dalam buffer ini sampai buffer hanya memiliki 1 bit diatur. Bit ini adalah bit stop Anda. Yang setelah itu adalah bit awal Anda. Voila! Anda telah menemukannya.

Jika Anda menggunakan bit paritas, opsi lain adalah mengambil data dua frame, pilih bit rendah pertama sebagai bit awal, lalu hitung checksum dan bandingkan dengan bit paritas. Jika cocok, maka Anda (mungkin) telah menemukan bit awal. Jika tidak, pilih bit rendah berikutnya dan ulangi sampai Anda mendapatkan checksum yang baik. Jika Anda tidak dapat menemukan sedikit di dua frame data yang memeriksa sebagai bit awal yang valid, maka data Anda rusak, dan Anda harus mengambil dua frame lagi.


Gagasan rapi DAN bersama-sama membingkai hingga bit awal dan berhenti bertahan. Itu akan terlalu banyak overhead untuk aplikasi spesifik saya, tapi tetap pintar.
Dan Laks

Jika perangkat eksternal adalah sesuatu yang OP tidak memiliki kendali atas (yang telah ia nyatakan dalam komentar sebelumnya untuk pertanyaan), tidak mungkin ia akan dapat mengubah panjang bit stop.
tcrosley

Komentar itu belum dibuat pada saat saya mulai menulis jawaban ini. Namun, tiga opsi lainnya yang saya daftarkan masih berlaku jika panjang bit stop sudah diperbaiki.
Dr. Funk

3

Perangkat keras UART memiliki masalah yang sama. Tapi biasanya itu salah satu yang memecahkan sendiri dalam waktu singkat. Pada akhir setiap frame, periksa bit stop, dan jika tidak tinggi, buang frame dan tunggu transisi tinggi ke rendah berikutnya. Dengan asumsi bahwa data dari sumber tidak sepenuhnya patologis (mis. String panjang "UUUU", atau ASCII 0x55), UART akhirnya akan "berjalan" sendiri ke bit awal yang sebenarnya.


1

Dengan asumsi transmisi 8N1.

Anda harus menunggu string 9 bit tinggi atau rendah berturut-turut.

Jika tinggi itu akan menandakan celah kosong pada data atau karakter 0xFF dan STOP bit
atau
jika rendah START bit dan karakter NULL 0x00.

Salah satu dari kondisi ini akan memungkinkan sinkronisasi ulang.

Untuk mempercepatnya: Jika Anda tahu karakter tertentu yang tidak mungkin dalam data, Anda bisa mengurai data yang masuk berulang kali (setelah fakta) untuk setiap bit dan jika Anda mendapatkan serangkaian 7 karakter yang tidak masuk akal (set bit tinggi, lebih rendah huruf besar, kode kontrol, tanda baca atau apa pun) diikuti oleh karakter yang valid Anda dapat yakin Anda melakukan sinkronisasi ulang.

Anda akan memiliki masalah yang sama ketika Anda menggunakan perangkat UART built-in dan tidak dapat melakukan evaluasi bitwise dan juga harus ingat untuk mengatur ulang semua bit framing error dan semacamnya setiap kali terjadi (terutama saat power up).

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.