Saya telah menyelidiki opsi tidur ATmega328, dan membaca beberapa artikel tentang itu, dan saya ingin memahami jika ada lebih banyak pilihan.
Jadi saya ingin mendapatkan arus serendah mungkin, sehingga apa pun yang kurang dari 100uA akan bagus - selama saya bisa mendengarkan uart dan menyela untuk bangun.
Saya menggunakan PCB khusus (bukan UNO), dengan ATmega328p.
Pengaturan chip untuk tidur nyenyak:
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu ();
tidak akan bangun dengan komunikasi serial, menurut ini .
Anda harus memasukkannya ke IDLE
mode, untuk mendengarkan serial, tetapi ini akan menghabiskan beberapa mA -bad.
Saya telah menemukan tautan ini di mana Anda dapat menyambungkan perangkat keras serial ke interupsi - yang berbahaya sehingga Anda dapat kehilangan data, dan terlebih lagi, saya memerlukan 2 pin interupsi ini.
Saya juga membaca artikel Gammon ini , di mana Anda dapat menonaktifkan beberapa hal, sehingga Anda dapat tidur IDLE dengan daya yang jauh lebih rendah - tetapi dia tidak menyebutkan bagaimana sebenarnya Anda dapatkan dari ini:
power_adc_disable();
power_spi_disable();
power_timer0_disable();
power_timer1_disable();
power_timer2_disable();
power_twi_disable();
Jadi, intinya, apakah ada opsi di luar sana, untuk mendapatkan setidaknya kurang dari 0,25mA, dan juga mendengarkan port serial, tanpa manipulasi perangkat keras? Misalnya, bangun dengan input data serial yang panjang ?
Jawaban:
Papan yang kami buat melakukan ini.
Saat tidur, INT0 level rendah diaktifkan
INT0 layanan interupsi rutin menetapkan bendera dan menonaktifkan interupsi
Saat bangun, kami memeriksa benderanya (ada sumber interupsi lainnya)
Di sisi komunikasi, kami menggunakan protokol pesan yang memiliki karakter awal
>
dan karakter akhir\r
. mis>setrtc,2015,07,05,20,58,09\r
. Ini memberikan beberapa perlindungan dasar terhadap kehilangan pesan, karena karakter yang masuk tidak diproses sampai>
diterima. Untuk membangunkan perangkat, kami mengirim pesan palsu sebelum pengiriman. Satu karakter akan melakukannya, tetapi kami mengirim>wakeup\r
hehe.Perangkat tetap terjaga selama 30 detik setelah pesan terakhir diterima jika ada pesan baru. Jika pesan baru diterima, penghitung waktu 30 detik akan direset. Perangkat lunak antarmuka PC mengirim pesan tiruan setiap detik untuk menjaga perangkat tetap aktif saat pengguna telah terhubung untuk konfigurasi dll.
Metode ini sama sekali tidak menimbulkan masalah sama sekali. Papan dengan beberapa periferal menggunakan sekitar 40uA saat tidur. Arus aktual yang dikonsumsi oleh ATMega328P mungkin sekitar 4uA.
Memperbarui
Saat melihat datasheet menunjukkan bahwa pin RX juga pin perubahan interrupt pin 16 (PCINT16)
Jadi metode lain tanpa kabel mungkin
Sebelum tidur: Tetapkan bit mask interupsi penggantian port di PCMSK2 untuk PCINT16, kosongkan flag port ganti pin 2 di PCIFR, aktifkan interupsi pin ganti port 2 (PCINT16-PCINT23) dengan mengatur PCIE2 di PCICR.
Setup ISR untuk pin ganti port 2 mengganggu dan lanjutkan seperti sebelumnya.
Satu-satunya peringatan dengan interupsi perubahan port adalah bahwa interupsi dibagi di semua 8 pin yang diaktifkan untuk port itu. Jadi, jika Anda memiliki lebih dari satu perubahan pin diaktifkan untuk port, Anda harus menentukan yang memicu interupsi di ISR. Ini bukan masalah jika Anda tidak menggunakan interupsi perubahan pin lain pada port tersebut (PCINT16-PCINT23 dalam kasus ini)
Idealnya ini adalah bagaimana saya akan mendesain papan kami tetapi apa yang kami punya bekerja.
sumber
Kode di bawah ini mencapai apa yang Anda tanyakan:
Saya menggunakan interupsi pin-perubahan pada pin Rx untuk melihat kapan data serial tiba. Dalam tes ini, papan akan tidur jika tidak ada aktivitas setelah 5 detik (LED "bangun" padam). Data serial yang masuk menyebabkan pin-change mengganggu untuk membangunkan board. Ini mencari nomor dan mem-flash LED "hijau" beberapa kali.
Diukur saat ini
Berjalan pada 5 V, saya mengukur sekitar 120 nA arus saat tertidur (0,120 μA).
Pesan kebangkitan
Namun masalah adalah bahwa byte pertama yang tiba hilang karena fakta bahwa perangkat keras serial mengharapkan tingkat penurunan pada Rx (bit mulai) yang telah tiba pada saat itu sepenuhnya terjaga.
Saya menyarankan (seperti dalam jawaban geometrikal) bahwa Anda pertama kali mengirim pesan "terjaga", dan kemudian berhenti sebentar. Jeda adalah untuk memastikan perangkat keras tidak mengartikan byte berikutnya sebagai bagian dari pesan terjaga. Setelah itu harus bekerja dengan baik.
Karena ini menggunakan interupsi pin-perubahan tidak diperlukan perangkat keras lain.
Versi yang diubah menggunakan SoftwareSerial
Versi di bawah ini berhasil memproses byte pertama yang diterima secara serial. Ini dilakukan dengan:
Menggunakan SoftwareSerial yang menggunakan interupsi pin-perubahan. Interupsi yang disebabkan oleh bit mulai dari byte seri pertama juga membangunkan prosesor.
Mengatur sekering sehingga kami gunakan:
Terinspirasi oleh FarO dalam komentar, ini membuat prosesor bangun dalam 6 siklus clock (750 ns). Pada 9600 baud setiap bit adalah 1/9600 (104,2 µs) sehingga penundaan tambahan tidak signifikan.
Konsumsi daya saat tidur diukur 260 nA (0,260 μA) sehingga konsumsi sangat rendah saat tidak diperlukan.
Perhatikan bahwa dengan sekering yang diatur seperti itu, prosesor berjalan pada 8 MHz. Jadi, Anda perlu memberi tahu IDE tentang itu (mis. Pilih "Lilypad" sebagai jenis papan). Dengan begitu penundaan dan SoftwareSerial akan bekerja pada kecepatan yang benar.
sumber