Tombol kebijaksanaan pada mikrokontroler avr. Menghubungkan tombol - Pemrograman di CV AVR? Debouncing kontak perangkat keras


Pada pelajaran sebelumnya, saya sudah memberi tahu Anda cara menampilkan informasi dari MK: dan . Dan dalam pelajaran ini kita akan memasukkan informasi menggunakan tombol. Ada beberapa jenis tombol: mengunci dan bijaksana Dari nama tombolnya, prinsip pengoperasiannya jelas: kebijaksanaan - ditekan, kontak ditutup, dibuka - terbuka; yang memperbaiki mencatat statusnya: ditekan - kontak ditutup, ditekan lagi - kontak terbuka.

Diagram koneksi tombol standar sangat sederhana, terlihat seperti ini


Ide kerjanya adalah sebagai berikut: tegangan 5 volt dialirkan ke kaki melalui resistor 10k, kaki tersebut logis. Tetapi ketika kita menekan tombol, kita memendekkan kaki ke tanah, dan arus kecil akan mengalir melalui resistor, dan tidak akan mampu menahan 5 volt, dan tegangan pada kaki akan turun menjadi 0 volt, dan ini logis 0. Momen-momen ini akan kita tangkap dalam program. Mari kita tulis sebuah program yang akan menyalakan LED saat tombol ditekan, dan mematikannya saat ditekan.

#termasuk #termasuk void main(void) ( // menginisialisasi port D PORTD=0b00000000; DDRD=0b10000000; while (1) ( if (PIND & 0b00000100) /*periksa level logis apa yang kita miliki pada pin & - berarti bitwise “DAN” misalnya di PIND kita punya 0b00000100, maka 0b00000100 & 0b00000100 = 0b00000100, itu benar, dan jika di PIND kita punya 0b00000000, maka 0b00000000 & 0b00000100 = 0b00000000 dan ini salah */ PORTD=0 b00000000; // tulis nol pada bit ketujuh dari port D else PORTD=0b10000000; // tulis satu ke bit ketujuh dari port D); delay_ms(100); // tambahkan penundaan 100 milidetik untuk melindungi dari pantulan kontak)

Kebanyakan mikrokontroler modern memiliki resistor pull-up R1 bawaan, jadi Anda tidak perlu memasang resistor eksternal
Untuk mengaktifkan resistor pull-up internal, saat menginisialisasi port di register PORTD, atur bit yang sesuai di mana tombol digantung menjadi satu: PORTD=0b00000100;
Apa yang terjadi jika pin dikonfigurasi sebagai output:

  • Jika outputnya logis nol, tidak ada hal buruk yang akan terjadi
  • jika unit logis tiba-tiba muncul pada output, maka ketika kita menekan tombol, kita hanya akan menghubungkan output ke ground, dan arus akan mengalir melaluinya yang tidak dapat ditahan oleh kaki (arus yang melalui kaki tidak boleh melebihi 40 miliampere ), dan kemungkinan besar akan terbakar
Oleh karena itu, untuk proteksi, disarankan untuk menempatkan resistor 300 ohm antara pin mikrokontroler dan tombol.
Masih banyak lagi cara menghubungkan tombol-tombol ke mikrokontroler, misalnya menggunakan dioda atau menggunakan ADC, namun saya tidak akan menjelaskannya, karena kursus ini dirancang untuk pemula. Jika Anda membutuhkannya, Anda dapat menemukannya sendiri.

Berikut contoh berbagai program C untuk mikrokontroler Atmel AVR. Semua contoh ditulis untuk mikrokontroler ATmega16, jadi ini harus diperhitungkan saat mentransfer ke MK lain dari keluarga AVR. Frekuensi clock mikrokontroler pada semua contoh adalah 8 MHz (clocking dari osilator internal digunakan). Kode contoh dibagi menjadi beberapa blok dan dilengkapi dengan komentar. Proyek ditulis di lingkungan Eclipse() dan dapat dengan mudah diimpor ke Eclipse. Anda juga dapat menggunakan proyek ini di lingkungan studio AVR (hanya struktur file proyek yang akan berubah). Jika Anda menemukan kesalahan, harap beri tahu kami melalui email.

- Contoh paling sederhana. Ada 8 LED yang terhubung ke port C. LED menyala secara logis pada jalur port. LED port menyala dan mati selama satu siklus. Semacam analogi Hello World di dunia sistem tertanam. Unduh contoh

Port IO – Contoh ini membahas cara bekerja dengan port I/O. Terdapat 8 LED yang terhubung ke port C (jalur 0-7). Sebuah tombol dihubungkan ke jalur 2 port D, dengan pull-up ke ground. Saat ditekan, tombol mengeluarkan logika satu tingkat ke baris 0 pada port C. Siklus program diatur sebagai berikut: saat startup, lampu berjalan menyala, pertama LED pada saluran 0 port C menyala, kemudian pada saluran 1, dst. Setelah mencapai garis 7, arah tembakan berubah (dari 7 menjadi 0). Saat Anda menekan tombol, api akan berhenti dan semua LED menyala secara bersamaan. Setelah menekan tombol itu lagi, api yang menyala terus bergerak dari tempatnya berhenti.

Unduh contoh

Indikasi Dinamis – Contoh ini membahas penggunaan indikator 7 segmen. Dalam kasus saya, ia memiliki 4 digit (digit). Karena saya memasang transistor di papan untuk mengontrol bit, kontrol dilakukan dengan mengeluarkan unit logis ke bit dan segmen. Diagram koneksinya adalah sebagai berikut: segmen indikator dihubungkan ke jalur 0-7 port C, dan digit indikator dihubungkan ke jalur 0-3 port B. Saat memulai, indikator menampilkan angka 1 2 3 4.

Unduh contoh

UART – Contoh ini membahas modul periferal UART (Universal Asynchronous Receiver). Modul UART dapat dikonfigurasi untuk bekerja dengan dan tanpa interupsi (secara manual, dengan bekerja dengan flag). Contohnya bekerja sebagai berikut: ketika menerima byte, MK pergi ke pengendali interupsi (hanya interupsi penerimaan data yang digunakan) dan mem-parsing nilai numerik byte (0-255) menjadi angka, yang ditampilkan pada 7- indikator segmen. Diagram koneksi mirip dengan contoh sebelumnya. Transmisi dilakukan melalui dua jalur UART (port D jalur 0-1), di mana Anda perlu menghubungkan jalur RX dan TX dari konverter USB-UART. Untuk mengkonfigurasi tanpa gangguan, Anda harus menghapus bit RXCIE di register UCSRB dan secara manual melakukan polling antarmuka di loop program utama.

Unduh contoh

Jam – Contoh ini membahas implementasi jam sederhana dengan indikator 7-segmen dan sepasang tombol. Hanya di sini sudah diperlukan 6 digit, meski detiknya bisa dihilangkan. Tombol dengan pull-up ke tanah. Saat ditekan, tombol mengeluarkan tingkat logika tinggi ke saluran. Indikator dihubungkan seperti pada contoh sebelumnya (segmen ke port C, digit ke port B), dan tombol ke jalur 2-3 port D. Tombol tersebut digunakan PD2 untuk mengatur menit, dan PD3 untuk mengatur jam. Dengan menekan setiap tombol, nilai digit yang bersangkutan (menit atau jam) bertambah.

Unduh contoh

DS18B20 – Contoh ini membahas cara bekerja dengan sensor suhu digital DS18B20. Pembacaan suhu ditampilkan pada indikator 7 segmen. Pin DQ sensor dihubungkan ke kaki (pin) PD5. Saluran harus dihubungkan ke catu daya positif dengan resistor 4,7-10 kOhm (menurut dokumentasi). Sensor disurvei setiap 5 detik. Suhu ditampilkan pada indikator 4 digit: tanda, dua digit untuk bagian bilangan bulat dan satu untuk bagian nyata. Dokumentasi untuk sensor.

Unduh contoh

DHT11 – Contoh ini membahas cara bekerja dengan sensor suhu dan kelembapan DHT11. Pembacaan suhu ditampilkan pada indikator 7 segmen. Pin DATA (juga SDA) sensor dihubungkan ke kaki (pin) PD5. Saluran harus dihubungkan ke catu daya positif dengan resistor 4,7-10 kOhm (menurut dokumentasi). Sensor disurvei setiap 5 detik. Suhu dan kelembapan diukur, tetapi hanya kelembapan (bilangan bulat dua digit) yang ditampilkan. Dokumentasi untuk sensor.

Unduh contoh

DHT22 – Contoh ini membahas cara bekerja dengan sensor suhu dan kelembaban DHT22. Dibandingkan dengan DHT11, sensor ini memiliki akurasi lebih tinggi dan rentang pengukuran lebih luas. Pembacaan suhu ditampilkan pada indikator 7 segmen. Pin DATA (juga SDA) sensor dihubungkan ke kaki (pin) PD5. Saluran harus ditarik ke catu daya positif dengan resistor 4,7-10 kOhm (walaupun menurut dokumentasi hal ini tidak diperlukan). Sensor disurvei setiap 5 detik. Suhu dan kelembapan diukur, tetapi hanya kelembapan (dua digit bilangan real dengan satu tempat desimal) yang ditampilkan. Dokumentasi untuk sensor.

Unduh contoh

BMP180 – Contoh ini membahas cara bekerja dengan sensor suhu dan tekanan atmosfer digital BMP180. Pembacaan tekanan atmosfer ditampilkan pada indikator 7 segmen. Sensor terhubung melalui antarmuka I2C. Jalur SDA dan SCL harus dihubungkan ke catu daya positif dengan resistor 4,7-10 kOhm. Sensor disurvei setiap 10 detik. Suhu dan tekanan diukur, tetapi hanya tekanan atmosfer dalam mm yang ditampilkan. kolom merkuri (bilangan bulat). Dokumentasi untuk sensor.

Unduh contoh

BH1750 – Contoh ini membahas cara bekerja dengan sensor cahaya digital BH1750. Pembacaan cahaya ditampilkan pada indikator 7 segmen. Sensor terhubung melalui antarmuka I2C. Jalur SDA dan SCL harus dihubungkan ke catu daya positif dengan resistor 4,7-10 kOhm. Sensor disurvei setiap 5 detik. Dokumentasi untuk sensor.

Unduh contoh

Indikasi ADC – Contoh ini mirip dengan contoh UART. Bedanya byte diambil dari jalur 0 port A (baris 0 ADC, ADC0). Mikrokontroler menggunakan pengatur waktu untuk melakukan konversi tegangan analog-ke-digital pada saluran 0 port A (2 bit terbawah dibuang sebagai noise). Saat mengukur, referensi internal 5 V digunakan. Sebuah tombol dihubungkan ke jalur PD2 port D, yang menentukan mode keluaran pembacaan. Ketika tombol ditekan, hasil pengukuran ditampilkan sebagai angka dari 0 hingga 255. Jika tombol tidak ditekan, hasil pengukuran diubah menjadi volt dan ditampilkan pada indikator (akurat hingga sepersepuluh).

Unduh contoh

PWM Cepat – Contoh ini menunjukkan cara mengkonfigurasi PWM perangkat keras (modulasi lebar pulsa, PWM bahasa Inggris). LED terhubung ke jalur 4 dan 5 port D, dan tombol untuk saluran A dan B masing-masing terhubung ke jalur 2-3 dan 6-7 port D. Tombol dengan pull-up ke ground (saat ditekan, tombol mengeluarkan logika satu tingkat ke jalur port) Tombol pada jalur 2 dan 3 masing-masing menambah dan mengurangi siklus kerja PWM (mengubah kecerahan LED) saluran A. Tombol pada jalur 6 dan 7 masing-masing menambah dan mengurangi duty cycle PWM saluran B. Angka perbandingan setiap saluran bervariasi pada rentang 0 hingga 255. Untuk saluran A langkah perubahannya adalah 10, untuk saluran B langkahnya adalah 5.

Unduh contoh

HCSR04 – Contoh ini membahas cara bekerja dengan sensor jarak ultrasonik HCSR04. Pin pemicu sensor terhubung ke jalur PD3, dan pin Echo terhubung ke jalur PD2. Koneksi indikator 7 segmen serupa dengan contoh sebelumnya. MK secara berkala memeriksa sensor dan menentukan jarak ke rintangan dalam sentimeter. Setelah ini, nomor tersebut dibagi menjadi beberapa digit dan ditampilkan di layar. Dokumentasi untuk sensor.

Unduh contoh

Keyboard Matriks – Contoh ini menunjukkan cara menggunakan keyboard matriks. Mikrokontroler secara dinamis melakukan polling pada keyboard dan kemudian menentukan jumlah keyboard yang ditekan. Ukuran bidangnya adalah 3 kali 3 - kami mendapatkan 9 tombol. Menekan 8 yang pertama akan menyalakan LED pada baris yang sesuai di port A, menekan tombol ke-9 akan menyalakan semua LED di port A. Keyboard matriks terhubung ke baris 0-5 dari port C (tiga kolom dan tiga baris). Arsip berisi diagram dan papan sirkuit tercetak dari keyboard matriks (Diptrace).

Unduh contoh

Shift Register – Contoh ini membahas cara bekerja dengan modul SPI menggunakan shift register 74HC595 sebagai contoh. LED dihubungkan ke register, jalur 4 port B (bukan pin SS) digunakan sebagai jalur CS. Jalur DS (kaki 14) register menuju MOSI (PB5), jalur SHCP (kaki 11) ke jalur SCK (PB7), jalur STCP (kaki 12) ke jalur SS (PB4). Garis MR (kaki ke-10) dan OE (kaki ke-13) masing-masing harus ditarik ke level logika tinggi dan rendah. Dengan menggunakan pengatur waktu, mikrokontroler mengubah status LED: LED genap dan ganjil menyala secara bergantian. Jika Anda mengirim byte melalui UART, itu akan dikeluarkan ke port pada LED. Untuk beralih kembali ke mode berkedip, Anda perlu mengirim 0x00 (nol) melalui UART. Dokumentasi untuk chip 74HC595.

Unduh contoh

Servo SG-90 – Contoh ini membahas cara bekerja dengan drive servo SG-90. PWM perangkat keras digunakan. Jalur servo PWM terhubung ke saluran A dari PWM perangkat keras. Tombol belok terhubung ke jalur PD2 dan PD3. Tombol pada saluran PD2 menambah durasi pulsa, tombol pada saluran PD3 mengurangi durasi pulsa. Durasi pulsa bervariasi dari 1 hingga 2 ms. Deskripsi motor servo.

Unduh contoh

Lampu RGB – Contoh ini mempertimbangkan penggunaan LED RGB tiga warna. Transisi warna yang mulus diimplementasikan menggunakan perangkat lunak PWM. Jalur merah, hijau, dan biru masing-masing terhubung ke port D jalur 2, 3, dan 4.

Unduh contoh

TSOP4836 NEC – Contoh ini menunjukkan pengoperasian dengan fotodetektor TSOP4836 dan protokol transmisi NEC, yang banyak digunakan dalam kendali jarak jauh inframerah. Ketika sebuah perintah diterima, kodenya ditampilkan. Koneksi indikator 7 segmen serupa dengan contoh sebelumnya. Deskripsi fotodetektor.

Unduh contoh

Cincin WS2812 – Contoh ini membahas cara bekerja dengan LED WS2812 dengan pengontrol PWM bawaan. Sebuah cincin berisi 16 LED dihubungkan ke pengontrol (jumlah LED dalam cincin dapat ditentukan dalam kode). Perpustakaan untuk bekerja dengan WS2812 bukan milik saya (diambil dari GitHub dan sedikit dimodifikasi, hak cipta tetap dipertahankan). Program ini pertama-tama menentukan serangkaian warna (merah, hijau, biru), dan kemudian dalam satu siklus mereka bergeser dan mengubah intensitasnya dengan lancar. Jalur IN dari LED pertama dihubungkan ke jalur PD2 pada port D. Deskripsi LED.

Unduh contoh

MFRC522 RFID – Contoh ini membahas cara bekerja dengan pembaca kartu RFID MFRC522. Pembaca terhubung ke pengontrol sesuai dengan skema standar. Perpustakaan untuk bekerja dengan MFRC522 bukan milik saya (diambil dari GitHub dan sedikit dimodifikasi, hak cipta tetap ada). Saat startup, pengontrol menentukan jenis pembaca dan mengirimkan data ke UART. Ini diikuti dengan pengujian berkelanjutan terhadap deteksi perangkat RFID. Saat Anda menunjukkan kartu atau key fob, alamatnya dibaca dan dikirim ke UART (alamat 32 bit, 4 byte). Deskripsi pembaca.




MCU ATMega16 memiliki tiga timer/counter - dua 8-bit (Timer/Counter0, Timer/Counter2) dan satu 16-bit (Timer/Counter1). Masing-masing berisi register khusus, salah satunya adalah register penghitung TCNTn (n adalah angka 0, 1 atau 2). Setiap kali prosesor mengeksekusi satu instruksi, isi register ini bertambah satu (setiap 8, 64, 256, atau 1024 siklus clock). Itu sebabnya disebut menghitung. Selain itu, ada juga register pembanding OCRn (Output Compare Register), yang di dalamnya kita dapat menulis sendiri bilangan apa pun. Pencacah 8-bit memiliki register 8-bit. Saat program dijalankan, konten TCNTn bertambah dan pada titik tertentu akan bertepatan dengan konten OCRn. Kemudian (jika parameter khusus ditentukan) dalam register flag interupsi TIFR (Timer/Counter Interrupt Flag Register), salah satu bit menjadi sama dengan satu dan prosesor, melihat permintaan interupsi, segera berhenti mengeksekusi loop tanpa akhir dan pergi untuk melayani interupsi pengatur waktu. Setelah ini, prosesnya diulangi.

Di bawah ini adalah diagram waktu mode CTC (Clear Timer on Compare). Dalam mode ini, register penghitungan dihapus ketika isi TCNTn dan OCRn cocok, dan periode panggilan interupsi pun berubah.

Ini bukan satu-satunya mode pengoperasian pengatur waktu/penghitung. Anda tidak perlu menghapus register penghitungan pada saat pertandingan, maka ini akan menjadi mode pembangkitan modulasi lebar pulsa, yang akan kita bahas di artikel berikutnya. Anda dapat mengubah arah penghitungan, yaitu isi register penghitungan akan berkurang seiring berjalannya program. Dimungkinkan juga untuk menghitung bukan berdasarkan jumlah perintah yang dijalankan oleh prosesor, tetapi berdasarkan jumlah perubahan level tegangan pada "kaki" T0 atau T1 (mode penghitung); Anda dapat melakukannya secara otomatis, tanpa partisipasi prosesor , ubah status kaki OCn bergantung pada status pengatur waktu. Timer/Counter1 dapat membuat perbandingan pada dua saluran sekaligus - A atau B.

Untuk memulai pengatur waktu, Anda perlu mengatur bit yang sesuai dalam register kontrol pengatur waktu TCCRn (Timer/Counter Control Register), setelah itu ia segera mulai bekerja.

Kami hanya akan mempertimbangkan beberapa mode pengoperasian pengatur waktu. Jika Anda perlu bekerja dalam mode yang berbeda, bacalah Lembar Data untuk ATMega16 - semuanya ditulis di sana dengan sangat rinci dalam bahasa Inggris, bahkan contoh program dalam C dan assembler diberikan (bukan tanpa alasan bahwa dibutuhkan 357 halaman cetakan teks!).

Sekarang mari beralih ke tombol.

Jika kita akan menggunakan sejumlah kecil tombol (hingga 9 buah), maka tombol tersebut harus dihubungkan antara ground dan pin port mikrokontroler mana pun. Dalam hal ini, Anda harus membuat input pin ini dengan mengatur bit yang sesuai di register DDRx dan menyalakan resistor pull-up internal dengan mengatur bit di register PORTx. Dalam hal ini, tegangan pada "kaki" ini akan menjadi 5 V. Ketika tombol ditekan, input MK ditutup ke GND dan tegangan di atasnya turun menjadi nol (atau mungkin sebaliknya - output MK korsleting ke ground dalam keadaan tertekan). Ini mengubah register PINx, yang menyimpan status port saat ini (tidak seperti PORTx, yang mengatur status port saat tidak ada beban, yaitu sebelum menekan tombol apa pun). Dengan membaca status PINx secara berkala, Anda dapat menentukan bahwa suatu tombol ditekan.

PERHATIAN! Jika bit yang sesuai dalam register DDRx disetel ke 1 untuk tombol Anda, maka menekan tombol dengan baik dapat menyebabkan efek kembang api kecil - munculnya asap di sekitar MCU. Wajar saja MK harus dibuang ke tempat sampah setelah ini...

Mari kita beralih ke bagian praktisnya. Buat ruang kerja baru dan proyek baru di IAR dengan nama seperti TimerButton. Atur opsi proyek seperti yang dijelaskan di artikel sebelumnya. Sekarang mari kita ketikkan kode kecil berikut.

#termasuk"iom16.h" ruang kosong init_timer0( ruang kosong) //Inisialisasi timer/counter0( OCR0 = 255; //Isi register perbandingan //Mengatur mode pengoperasian pengatur waktu TCCR0 = (1 batal init_timer2( ruang kosong) //Inisialisasi timer/counter2( OCR2 = 255; TCCR2 = (1 //Setel interupsi kecocokan untuk itu) ruang kosong utama( ruang kosong) (DDRB = 255; init_timer0(); init_timer2(); ketika(1) { } } #pragma vektor = TIMER2_COMP_vektor //Pengatur waktu menyela 2 __interupsi kekosongan berkedip() ( jika((PORTB & 3) == 1) ( PORTB &= (0xFF // Nonaktifkan pin PB0, PB1 PORTB |= 2; // Aktifkan PB1 } kalau tidak( PORTB &= (0xFF // Nonaktifkan pin PB0, PB1 PORTB |= 1; // Aktifkan PB0 } }

Mari kita lihat cara kerjanya. Fungsi init_timern mengatur bit dalam register TCCRn, OCRn dan TIMSK, dan metode ini mungkin tampak aneh atau asing bagi sebagian orang. Kita harus menjelaskan dulu apa entrinya “(1

dimana a adalah bilangan yang representasi binernya perlu digeser, dan b menunjukkan berapa banyak bit yang perlu digeser. Dalam hal ini, hilangnya nilai yang disimpan dalam a mungkin terjadi (yaitu, tidak selalu mungkin untuk memulihkan dari C apa yang ada di a). Mari kita lihat sebuah contoh:

Apa yang akan berakhir di C setelah mengeksekusi baris C = (22

2 dalam kode biner akan terlihat seperti 00010110, dan setelah digeser ke kiri sebanyak 3 bit kita mendapatkan C = 10110000.

Demikian pula terjadi pergeseran ke kanan. Contoh lain:

arang C; … C = ((0xFF > 2);

Pertama, tindakan dalam tanda kurung bagian dalam akan dilakukan (0xFF adalah 255 dalam kode heksadesimal), dari 11111111 hasilnya adalah 11111100, kemudian akan terjadi pergeseran ke kanan dan kita mendapatkan C = 00111111. Seperti yang kita lihat, di sini dua operasi yang saling terbalik menghasilkan angka yang berbeda, karena kami kehilangan dua bit. Hal ini tidak akan terjadi jika variabel C bertipe int, karena int menempati 16 bit.

Sekarang mari kita lihat dua operator bit lagi yang banyak digunakan dalam pemrograman MK. Ini adalah operator bitwise dan (&) dan bitwise atau (|). Cara kerjanya, menurut saya, akan terlihat jelas dari contoh:

Tindakan: Hasil (dalam biner): C = 0; // C = 00000000 C = (1 // C = 00100101 C |= (1 // C = 00101101 C &= (0xF0 >> 2); // C = 00101100 C = (C & 4) | 3; // C = 00000111

Saya hampir lupa! Ada juga “bitwise eksklusif atau” (^). Ini membandingkan bit-bit yang sesuai dalam suatu angka, dan jika sama, mengembalikan 0, jika tidak, satu.

Mari kita kembali ke program kita. Dikatakan “(1

/* Timer/Penghitung 0 Daftar Kontrol */ #mendefinisikan FOC0 7 #mendefinisikan WGM00 6 #mendefinisikan COM01 5 #mendefinisikan COM00 4 #mendefinisikan WGM01 3 #mendefinisikan CS02 2 #mendefinisikan CS01 1 #mendefinisikan CS00 0

Saat mengkompilasi program, entri WGM01 cukup diganti dengan nomor 3, dan hasilnya adalah entri yang benar. WGM01 disebut makro dan, tidak seperti variabel, WGM01 tidak memakan ruang di memori (kecuali mungkin di memori pemrogram :-).

Jika Anda sekarang melihat Datasheet, tidak akan sulit untuk melihat bahwa WGM01 adalah nama bit ketiga dalam register TCCR0. Hal yang sama berlaku untuk sisa bit register ini. Kebetulan ini bukan suatu kebetulan dan berlaku untuk semua register MK (atau hampir semua). Yaitu dengan menulis “(1

Jumlahnya, garis

berarti mode CTC dihidupkan, ketika timer0 dipicu, keadaan "kaki" OS0 (alias PB3) berubah, isi counter bertambah setiap 1024 siklus clock.

Demikian pula untuk timer2: TCCR2 = (1

Register TIMSK (Register MaSK Interupsi Timer/penghitung) mengatur mode interupsi. Kami menulis

yang berarti mengganggu timer2 ketika TCNT2 dan OCR2 cocok. Fungsi yang terakhir adalah fungsi Timer2 Match Interrupt yang sebenarnya. Interupsi dinyatakan sebagai berikut:

#pragma vektor= VEKTOR __mengganggu KETIK NAMA()

di mana VECTOR adalah makro vektor interupsi (artinya hanya angka yang mengkarakterisasi interupsi ini); Makro ini dicantumkan dalam urutan penurunan prioritas di file iom16.h. TYPE adalah tipe nilai yang dikembalikan oleh fungsi, dalam kasus kita void (tidak ada). NAMA – nama khusus untuk fungsi ini. Jika ada interupsi, kami masih punya waktu untuk mengerjakannya di masa mendatang.

Saat menjalankan fungsi kami, LED yang terhubung ke PB0 dan PB1 akan berkedip secara bergantian. Ternyata frekuensinya adalah 11059200/(256*1024) = 42 Hz. Ini cepat, tapi akan terlihat dengan mata telanjang. Omong-omong, penggunaan pengatur waktu memungkinkan penghitungan interval waktu yang tepat yang tidak bergantung pada kompleksitas program Anda dan urutan eksekusinya (tetapi jika Anda memiliki tidak lebih dari satu interupsi).

Jadi, simpan file sebagai “TimerDebug.c”, tambahkan ke proyek, kompilasi, flash MK. Apa yang kita lihat? LED yang terhubung ke pin PB3 akan berkedip aktif, namun tidak ada perubahan pada PB0 dan PB1. Apa masalahnya? Apakah ada sesuatu yang salah?

Untuk mengetahuinya, kita harus men-debug program kita. Karena IAR tidak memiliki Debugger, Anda harus menggunakan AVR Studio. Lingkungan pengembangan ini dapat diunduh dari situs web produsen http://atmel.com. Saya rasa tidak akan ada masalah dengan pemasangannya. Sebelum memulai AVR Studio, pilih mode Debug di IAR dan buat file debug cof (semua opsi proyek harus diatur seperti yang dijelaskan di artikel sebelumnya).

Setelah membuka AVR Studio, kita akan melihat jendela selamat datang di mana kita akan memilih "Buka". Sekarang kita masuk ke folder dengan proyek, di sana di Debug\Exe, pilih "TimerDebug.cof" di sana, buat proyek sesuai saran mereka, pilih perangkat ATMega16 dan mode debugging Simulator. Setelah itu, jika semuanya dilakukan dengan benar, proses debugging segera dimulai

Lingkungan debugging di sini sangat nyaman, karena... memungkinkan Anda melihat konten semua register MK, serta menetapkan nilainya secara manual dengan klik mouse. Misalnya, jika Anda menyetel flag interupsi di register TIFR di bit 7 (di bawah kotak hitam di TIMSK), maka langkah program selanjutnya (menekan F10 atau F11) adalah pemrosesan interupsi (flag akan disetel secara otomatis ketika register TCNT2 dan OCR2 cocok). Namun yang mengejutkan kami, tidak akan ada gangguan!

Timbul pertanyaan: mengapa?

Mari kita buka register CPU, SREG. Register ini menentukan pengoperasian prosesor, dan khususnya bit ketujuh (I-bit, Interrupt bit) bertanggung jawab untuk memproses semua interupsi di MK. Kami belum menginstalnya. Segera setelah Anda mengaturnya, interupsi akan segera dieksekusi (jika bit ketujuh di TIFR diatur pada waktu yang sama).

Anda dapat melihat satu fitur menarik: segera setelah prosesor masuk ke pemrosesan interupsi, bit ini (tanda pengaktifan pemrosesan interupsi) dihapus, dan ketika keluar dari fungsi interupsi, bit ini secara otomatis disetel kembali. Hal ini tidak memungkinkan prosesor, tanpa menjalankan satu interupsi, untuk mengambil interupsi lainnya (bagaimanapun juga, prosesor menavigasi program dengan cara yang persis sama - dengan bendera).

Ini berarti Anda perlu menambahkan sebaris kode untuk menyetel bit ini menjadi satu. Kami akan menambahkannya ke fungsi init_timer2. Anda akan mendapatkan yang berikut ini:

ruang kosong init_timer2( ruang kosong) ( SREG |= (1 //Menambahkan baris ini OCR2 = 255; TCCR2 = (1

Sekarang, setelah memilih konfigurasi Rilis dan mem-flash MK dengan menekan F7 dan meluncurkan AVReal32.exe, kami akan senang melihat semuanya berjalan sebagaimana mestinya.

Komentar: Saat men-debug suatu program, Anda harus mengurangi interval pengatur waktu jika terlalu lama, karena selama debugging di AVR Studio, program berjalan ribuan kali lebih lambat daripada di dalam MK dan Anda tidak akan menunggu pengatur waktu menyala. Secara umum, debugging sangat mirip dengan sistem pemrograman lain, seperti Visual C++.

Sekarang, setelah mempelajari cara men-debug program, mari buat file baru di IAR (dan simpan file lama dan hapus dari proyek) dan ketik kode berikut:

#termasuk"iom16.h" lama tidak ditandatangani int penghitung = 0; //Penghitung untuk membentuk interval waktu karakter yang tidak ditandatangani B0Ditekan = 0; //Status tombol0 disimpan di sini (0 - tidak ditekan, 1 - ditekan) karakter yang tidak ditandatangani B1Ditekan = 0; //Status tombol1 disimpan di sini (0 - tidak ditekan, 1 - ditekan) //Inisialisasi timer2 //Pencacahan perlu ditingkatkan setiap 11059 siklus clock (1 ms). Kami mendapatkannya setiap 1,001175 ms ruang kosong init_timer2() ( OCR2 = 173; TCCR2 = (1 //Menginisialisasi port I/O init_io_ports() ( DDRA =(1//membentuk penundaan dalam Pause_ms milidetik ruang kosong menunda( lama tidak ditandatangani int Pause_ms) ( penghitung = 0; ketika(counter void main() ( SREG |= (1 //Aktifkan interupsi init_timer2(); //Aktifkan timer2 setiap 64 tick, hitung hingga 173 init_io_ports(); //Aktifkan port I/O ketika(1) { //Tombol pemrosesan 0 jika(B0Ditekan == 1) { //meningkatkan PORTB, menunggu rilis PORTB++; B0Ditekan = 0; ketika((PINC & (1 lainnya ( jika((PINC & (1 //Memperbaiki penekanan ( penundaan(50); jika((PINC & (1 //Cek pengepresan ( B0Ditekan = 1; } } } //Tombol pemrosesan 1 jika(B1Ditekan == 1) //Jika tombol diklik, { //mengurangi PORTB, menunggu rilis PORTB--; B1Ditekan = 0; ketika((PINC & (1 lainnya ( jika((PINC & (1 //Memperbaiki penekanan ( penundaan(200); //Menghilangkan "pentalan kunci" jika((PINC & (1 //Cek pengepresan ( B1Ditekan = 1; //Menyetel tanda "tombol ditekan". } } } } } //Interupsi oleh timer 2, sehingga penghitung bertambah #pragma vektor= TIMER2_COMP_vektor __mengganggu batal inc_delay_counter() ( penghitung++; )

Pertama, saya sarankan mengambil file firmware yang sudah jadi (file untuk artikel, folder Rilis, file TimerButton.hex, atau kompilasi teks ini) dan menuliskannya ke MK. Kemudian cabut kabel firmware, sambungkan tombol ke PC0 dan PC1 dan coba tekan. Kita akan melihat bahwa ketika Anda menekan salah satu tombol, register PORTB bertambah (LED menyala), dan ketika Anda menekan tombol lainnya, register itu berkurang. Jika tidak berhasil, coba tekan satu tombol sambil menahan tombol lainnya - ini akan berhasil. Faktanya adalah saya menghubungkan tombol-tombol dengan cara berikut: ketika Anda menekan tombol, output MK "menggantung" di udara, dan ketika dilepaskan, ia memendek ke tanah. Jika Anda menghubungkan tombol secara berbeda, Anda hanya perlu sedikit memodernisasi program.

Mari kita lihat kodenya. Di sini, bekerja dengan pengatur waktu diatur agak berbeda. Ini diaktifkan setiap 11072 siklus jam (yaitu, setiap 1,001175 ms) dan menambah variabel penghitung. Ada juga fungsi penundaan(long unsigned int Pause_ms), yang mengambil jumlah milidetik Pause_ms sebagai parameter, mereset penghitung dan menunggu penghitung mencapai nilai Pause_ms, setelah itu MK terus beroperasi. Jadi, dengan menulis penundaan (1500), kita akan membuat penundaan dalam program sebesar 1,5 detik. Ini sangat berguna untuk membentuk interval waktu.

Semuanya tampak jelas dengan pengatur waktu. Tapi untuk apa itu digunakan? Pertimbangkan loop tak terbatas while(1) di main(). Loop ini memeriksa status tombol dengan menganalisis isi register PINB. Mengapa ada penundaan 50 ms di sana? Ini adalah penghapusan apa yang disebut. "obrolan kunci" Faktanya adalah ketika Anda menekan tombol, satu kontak mengenai kontak lainnya, dan karena kontak tersebut terbuat dari logam, benturan ini bersifat elastis. Kontaknya, muncul, menutup dan membuka beberapa kali, meskipun jari hanya melakukan satu kali penekanan. Hal ini menyebabkan rekaman MK beberapa klik. Mari kita lihat grafik tegangan pada keluaran PC0 versus waktu. Ini mungkin terlihat seperti ini:

Titik A adalah saat tombol ditekan. Itu bisa diperbaiki oleh MK. Lalu ada beberapa hubung singkat dan hubung terbuka (mungkin tidak ada, atau mungkin ada 12 - fenomena ini bisa dianggap acak). Di titik B, kontak sudah terpasang dengan aman. Antara A dan B ada rata-rata sekitar 10 ms. Akhirnya di titik D terjadi pembukaan. Bagaimana cara menghilangkan fenomena tidak menyenangkan ini? Ternyata sangat sederhana. Penting untuk mencatat saat tombol ditekan (titik A), setelah beberapa waktu, misalnya 50 ms (titik C), periksa apakah tombol benar-benar ditekan, ambil tindakan yang sesuai dengan tombol ini dan tunggu saat tersebut itu dilepaskan (titik D). Artinya, Anda perlu membuat jeda dari A ke C, sehingga semua “kedipan” ada di dalam jeda tersebut. Sekarang coba hilangkan garis yang menyebabkan penundaan, kompilasi program dan jahit ke dalam MK. Hanya dengan menekan tombol, Anda dapat dengan mudah memastikan bahwa semua “siksaan” ini tidak sia-sia.

Tapi apa yang harus Anda lakukan jika Anda perlu menghubungkan, katakanlah, 40 tombol ke MK? Toh, pinnya hanya 32 pin. Tampaknya tidak mungkin. Itu sebenarnya mungkin. Dalam hal ini, algoritma yang disebut gating digunakan. Untuk melakukan ini, Anda perlu menghubungkan tombol-tombol dalam bentuk matriks, seperti yang ditunjukkan pada gambar (gambar diambil dari buku Morton "MK AVR, kursus pengantar", yang berisi tentang pemrograman AVR dalam assembler).

Ketika diterapkan pada log keluaran PB0. 1 (+5V), dan untuk menyematkan log PB1 dan PB2. 0 memungkinkan pemrosesan tombol 1, 4 dan 7. Setelah itu, status masing-masing tombol dapat diketahui dengan memeriksa tegangan pada salah satu pin PB3..PB5. Jadi, terapkan secara berurutan ke pin PB0..PB2 log. 1, status semua tombol dapat ditentukan. Jelas bahwa pin PB0..PB2 harus menjadi output, dan PB0..PB2 harus menjadi input. Untuk menentukan berapa banyak pin yang diperlukan untuk serangkaian tombol X, Anda perlu mencari sepasang faktor X yang jumlahnya paling kecil (untuk kasus kami dengan 40 tombol, ini akan menjadi angka 5 dan 8). Ini berarti hingga 256 tombol dapat dihubungkan ke satu MK (dan bahkan lebih banyak lagi dengan menggunakan decoder, tetapi lebih lanjut tentang decoder nanti). Lebih baik membuat lebih sedikit pin keluaran dan lebih banyak pin masukan. Dalam hal ini, pemindaian semua baris matriks akan memakan waktu lebih sedikit. Metode koneksi (strobo) ini tidak hanya berlaku pada tombol saja. Di sana Anda dapat menghubungkan berbagai macam perangkat, mulai dari matriks LED hingga chip memori flash.

© Kiselev Romawi
Juni 2007

Jadi kita sampai pada bagian integral dari sebagian besar proyek mikrokontroler - tombolnya. Tombol adalah perangkat yang cukup sederhana yang biasanya hanya memiliki dua keadaan; dalam bahasa pemrograman, ini adalah keadaan logis 1 (kontak tertutup) dan logis 0 (kontak terbuka). Mari kita lihat diagramnya.

Kami masih memiliki skema yang sama dengan indikator tujuh segmen, namun 4 tombol telah ditambahkan. Dengan menggunakan tombol grup A kita akan menambah atau mengurangi nilai yang ditampilkan pada tiga indikator pertama, dan menggunakan tombol grup B kita akan mengubah nilai pada dua indikator terakhir.

Pertama, mari kita bahas secara singkat tentang tombol-tombolnya. Tombol-tombolnya dapat digunakan dengan kontak yang biasanya terbuka tanpa terkunci. Kami menghubungkan satu kontak ke ground, dan yang lainnya ke pin terpisah mikrokontroler. Kami tidak akan memasang resistor pull-up ke positif, karena sudah disediakan di mikrokontroler itu sendiri. Yang tersisa hanyalah menulis program untuk melakukan polling tombol (keadaan pin mikrokontroler) dan menampilkan hasilnya pada indikator. Karena kesederhanaan skema dan kesulitan pembaca dalam memahami program C,Fokus utama pada bagian ini adalah menganalisis program.

Jadi programnya.

#termasuk //sertakan perpustakaan #include #define SPI_SS PB2 //Keluaran SS #define SPI_MOSI PB3 //Keluaran MOSI #define SPI_MISO PB4 //Keluaran MISO #define SPI_SCK PB5 //Keluaran SCK #define BUTTON_AP PD4 //Keluaran tombol A+ #define BUTTON_AM PD5 //Keluaran tombol A - #define BUTTON_BP PD6 //output tombol B+ #define BUTTON_BM PD7 //output tombol B char di; void spi(char cmd,char data) //Fungsi untuk mentransmisikan dua paket 8-bit melalui protokol SPI ( PORTB &= ~(1<999)a=999; //periksa apakah variabel a telah mencapai nilai maksimumnya jika(a<0)a=0; //проверка достижения минимального значения переменной a if(b>99)b=99; //periksa apakah nilai maksimum variabel b telah tercapai if(b<0)b=0; //проверка достижения минимального значения переменной b } return 0; }

Mari kita mulai. program CBiasanya mereka memulai dengan menghubungkan perpustakaan eksternal. Dua baris dalam program ini bertanggung jawab untuk ini:

#termasuk #termasuk

avr/io.hIni adalah perpustakaan I/O yang akan menjelaskan kepada kompiler port I/O apa yang dimiliki mikrokontroler, bagaimana labelnya, dan kemampuannya. Dan hal yang paling menarik adalah perpustakaan ini sendiri memilih dari pengaturan proyek mikrokontroler mana yang deskripsinya perlu diterapkan, yang memungkinkan Anda menggunakan perpustakaan ini untuk mikrokontroler yang berbeda. Perpustakaan ini perlu disertakan terlebih dahulu.

Pustaka kedua yang sering digunakan adalah util/delay.hmembantu menciptakan penundaan dalam eksekusi program, yang cukup memudahkan.

#tentukan BUTTON_AP PD4

menunjukkan apa yang ada pada outputPD4 (4 port mendaftarB)kami akan menghubungkan tombolnyaSEBUAH+ (lihat diagram). Hal ini diperlukan agar jika kita tiba-tiba memutuskan untuk mengalihkan tombol ke keluaran lain, kita tidak perlu mencari di seluruh program, cukup mengubahnya dimendefinisikannama keluaranPD4ke yang diinginkan, dan itu akan tetap ada dalam programTOMBOL_AP.Namun dalam hal kesimpulan untukSPItidak ada yang bisa diubah karena dukunganSPIperangkat keras dan diikat secara kaku ke pin mikrokontroler oleh pabrikan.

Bagian menarik berikutnya dari program ini adalah deskripsi port.

DDRB |= (1<

Ini adalah bagaimana bit-bit port yang terdaftar dialihkan ke outputB(secara default semua bit dari semua port diatur ke input). EBaris tersebut dapat ditulis sebagai berikut tanpa menggunakan definisi makro di dalamnyamendefinisikan

DDRB |= (1<

Entri ini setara dan dimaksudkan untuk menggantikan 1 ke dalam registerDDRBke kategori yang sesuaiBR3 (peringkat 3), BR5 (peringkat 5) DanBR2 (peringkat 2). Bagian lain dari registerDDRBtetap tidak berubah. Anda juga dapat menulis baris ini seperti ini

DDRB |= (1<<3)|(1<<5)|(1<<2);

yang tentu saja lebih membingungkan.

entri 1<<3 berarti unit biner perlu digeser ke kiri sebanyak 3 posisi,posisi di sebelah kanan diisi dengan angka nol.

1 <<3 berarti 1000 (satu nol nol nol) dalam biner. Dan saat melakukan operasi(1<<3)|(1<<5) kita mendapatkan 101000 dalam biner.

Pada baris berikutnya dari program kita menghubungkan resistor pull-up untuk tombol. Mari kita tulis satuannya ke dalam bit register yang sesuaiPORTD

PELABUHAN |= (1<

Resistor ini dibangun ke dalam mikrokontroler. Mereka dapat dihubungkan ke bit port, asalkan bit ini didefinisikan sebagai input. Resistor menarik pin mikrokontroler yang diinginkan ke logika 1.

Pengaturan lainnya dilakukan dengan cara yang sama menggunakan register mikrokontroler yang sesuai.

Sekarang mari kita lihat bagian utama dari program yang dijalankan mikrokontroler, setelah pengaturan dasar, tanpa henti. Bagian dari program ini terbungkus dalam lingkaran tanpa akhir.

Sementara(1) ( );

Semua baris program yang diapit kurung kurawal akan dieksekusi dalam lingkaran. Di dalam loop tanpa akhir ini, angka desimal dipecah sedikit demi sedikit untuk dijadikan output menjadi digit individual dari indikator tujuh segmen. Setelah pemisahan, kami mengirimkan data bitwise melaluiSPIuntuk setiap indikator individu.

Penundaan_ms(100);

untuk mencegah pemicuan palsu dari “pantulan” kontak tombol. Dan untuk kedua kalinya kami melakukan polling pada tombol tentang penekanannya dan memeriksa tanda yang ditetapkan sebelumnya tentang penekanan. Jika kondisi terpenuhi, kami mengubah nilai yang ditampilkan pada indikator. Kemudian kita reset tombol tekan flag ke 0.Setelah itu siklus berulang.

Di bagian selanjutnya - bagian terakhir - ADC (konverter analog-ke-digital) dan penerapan semua yang telah dipelajari sebelumnya dalam praktik akan dipertimbangkan.

Pada pelajaran sebelumnya, telah dibahas metode untuk mengeluarkan informasi dari mikrokontroler: menghubungkan LED dan indikator LCD. Namun bagaimana cara memasukkan informasi ke dalam mikrokontroler? Ada banyak pilihan dan perangkat untuk ini. Namun untuk saat ini, mari kita pertimbangkan opsi paling sederhana, ini adalah tombol biasa. Ada dua jenis tombol: kebijaksanaan dan penguncian. Tombol kebijaksanaan bekerja berdasarkan prinsip berikut: ditekan - kontak ditutup, dilepaskan - kontak dibuka. Perlu diperhatikan bahwa ada tombol kebijaksanaan yang awalnya tertutup dan terbuka saat ditekan. Tombol pengunci (kadang disebut: sakelar sakelar, sakelar, sakelar), berbeda dengan tombol kebijaksanaan, tetap posisinya ketika ditekan, yaitu: ditekan - kontak ditutup, ditekan lagi - kontak terbuka. Secara umum, kami telah memilah tombol-tombolnya, sekarang kami akan mencari cara untuk menghubungkan tombol-tombol ini ke mikrokontroler. Dan sebenarnya sangat mudah untuk terhubung! Mari kita lihat diagramnya:

Anda mungkin bertanya: Mengapa resistor R1? Dan kemudian, tanpa resistor R1, ketika tombol S1 terbuka, mikrokontroler pada port yang terhubung dengan semua ini akan melihat logika 1 atau logika 0, sehingga menyebabkan alarm palsu pada tombol tersebut. Untuk mencegah hal ini terjadi, perlu untuk “menarik” port ini dengan resistansi positif terhadap catu daya. Resistansi resistor R1 dapat berkisar dari 4,7 kOhm hingga 10 kOhm. Dengan resistor diperoleh gambar sebagai berikut: tombol S1 ditekan - muncul logika 0 di port MK, tombol S1 tidak ditekan - muncul logika 1 di port MK karena resistansi R1. Tentu saja, Anda perlu tahu bahwa beberapa mikrokontroler AVR memiliki resistor pull-up bawaan dengan resistansi sekitar 50 kOhm; resistor tersebut dinonaktifkan secara default. Di BASCOM-AVR, resistor ini dapat diaktifkan dengan menulis logika 1 ke port yang diperlukan.Tetapi saya sangat tidak menyarankan menggunakan yang bawaan ini, jauh lebih dapat diandalkan untuk menggunakan yang eksternal, seperti yang ditunjukkan pada diagram di atas. Nah, kita sudah menemukan solusi skematisnya, sekarang kita akan mengetahuinya secara terprogram. Untuk bekerja dengan tombol ini, Anda harus terlebih dahulu mengkonfigurasi port mikrokontroler sebagai input; di BASCOM-AVR dilakukan seperti ini:
Konfigurasi(port mikrokontroler) = masukan
Contoh:
Konfigurasi PINB.3 = masukan

Harap dicatat bahwa agar port masukan berfungsi, nama port harus dimulai dengan PIN, dan bukan dengan PORT seperti untuk konfigurasi port keluaran!

Setelah mengkonfigurasi port input, kita dapat membaca nilai 1 atau 0 darinya, dalam kasus kita 0 – tombol ditekan, 1 – tombol tidak ditekan. Dan kita dapat memeriksa apakah tombol tersebut ditekan seperti ini:
Jika(port mikrokontroler) = 0 maka
(jika tombol ditekan, lakukan tindakan yang dijelaskan di sini)
Berakhir jika
Alternatifnya, Anda dapat memeriksa apakah tombol ditekan:
Jika(port mikrokontroler) = 1 maka
(jika tombol tidak ditekan, lakukan tindakan yang dijelaskan di sini)
Berakhir jika
Contoh:
Jika PINB.3 = 0 maka
PORTB.2 = 1" jika tombol ditekan, maka hidupkan LED yang terhubung ke PB.2
Berakhir jika

Sederhana, bukan? Jadi, sekarang mari kita coba mengimplementasikan menghubungkan tombol ke mikrokontroler di perangkat keras. Mari kita ambil mikrokontroler Attiny13 dan yang dibuat sedikit lebih awal sebagai dasar. Bagi yang belum membuat debug board, berikut diagramnya:

Algoritma programnya adalah sebagai berikut: tombol S1 ditekan - LED mati, tombol S1 tidak ditekan - LED menyala. Dan berikut ini programnya sendiri di BASCOM-AVR:

$regfile = "attiny13.dat" $crystal = 8000000 Config Pinb.3 = Input Config Portb.2 = Output Do Jika Pinb.3 = 0 Maka Portb.2 = 0 Jika Pinb.3 = 1 Maka Portb.2 = 1 Loop Akhir

Ini adalah program yang sederhana. Firmware yang dikompilasi ada dalam arsip di bawah. Bit sekering tidak perlu disetel, karena dalam program sederhana seperti itu, frekuensi clock tidak terlalu penting. Bagi yang malas mengoleksi hardware, ada salah satu project favorit kami, Anda bisa mendownloadnya pada arsip di bawah ini. Bekerja dengan sirkuit di simulator Proteus:

Unduh file untuk pelajaran (proyek di , source code, firmware) bisa di bawah

Daftar elemen radio

Penamaan Jenis Denominasi Kuantitas CatatanTokobuku catatan saya
IC1 MK AVR 8-bit

ATtiny13

1 Ke buku catatan
R1, R2 Penghambat

4,7 kOhm

2 Ke buku catatan
R3 Penghambat

150 ohm

1 Ke buku catatan
HL1 Dioda pemancar cahaya 1