Rumah - Pengaturan internet
Interupsi di atmega8. Kursus pelatihan

Salah satu kelebihan mikrokontroler ATmega8 adalah jangkauan interupsi yang berbeda-beda.

Mengganggu adalah peristiwa yang menyebabkan eksekusi program utama dihentikan dan suatu fungsi dipanggil yang menangani interupsi jenis tertentu.

Interupsi dibagi menjadi internal dan eksternal. Sumber interupsi internal termasuk modul mikrokontroler internal (timer, transceiver USART, dll.). Interupsi eksternal terjadi ketika sinyal eksternal tiba di pin mikrokontroler (misalnya sinyal di pin RESET dan INT). Sifat sinyal yang menyebabkan terjadinya interupsi diatur dalam register kontrol MCUCR, khususnya di bit - ISC00 (bit 0) dan ISC01 (bit 1) untuk input INT 0; ISC10 (bit2) dan ISC11 (bit3) untuk masukan INT1.

Pada mikrokontroler ATmega8, setiap interupsi mempunyai interupsi tersendiri vektor interupsi(alamat di awal area memori program di mana perintah untuk melompat ke rutinitas interupsi tertentu disimpan). Di mega8, semua interupsi memiliki prioritas yang sama. Jika beberapa interupsi terjadi secara bersamaan, maka interupsi dengan bilangan vektor lebih rendah akan diproses terlebih dahulu.

Vektor interupsi di Atmega8

Alamat Sumber interupsi Keterangan
0x0000 MENGATUR ULANG Atur ulang sinyal
0x0001 INT0 Permintaan interupsi eksternal pada input INT0
0x0002 INT1 Permintaan interupsi eksternal pada input INT1
0x0003 T/C1 Pengambilan waktu T/C1
0x0004 T/C1 Cocokkan Timer T/C1 Bandingkan Register A
0x0005 T/C1 Cocokkan dengan register perbandingan B pada timer T/C1
0x0006 T/C1 Penghitung T/C1 meluap
0x0007 T/C0 Penghitung T/C0 meluap
0x0008 SPI Transfer data SPI selesai
0x0009 UART Transceiver UART telah selesai menerima data.
0x000A UART Daftar data UART kosong
0x000B UART Transmisi data melalui transceiver UART selesai
0x000C ANA_COMP Interupsi dari komparator analog

Manajemen interupsi

4 register bertanggung jawab untuk mengelola interupsi di ATmega8:

GIMSK(alias GICR) - melarang/mengaktifkan interupsi berdasarkan sinyal pada input INT0, INT1

GIFR- pengelolaan semua interupsi eksternal

WAKTU, TIFR- pengelolaan interupsi dari pengatur waktu/penghitung

Daftar GIMSK (GICR)

INTFx=1: terjadi interupsi pada input INTx. Saat memasuki rutinitas penanganan interupsi, INTFx secara otomatis diatur ulang ke status log. 0

Daftar WAKTU

7 6 5 4 3 2 1 0
TOIE1
OCIE1A
OCIE1B
-
TICI
-
TOIE0
-

TOIE1=1: Interupsi luapan T/C1 diaktifkan

OCIE1A=1: interupsi ketika register perbandingan A cocok dengan isi counter T/C1 yang diaktifkan

OCIE1B=1: interupsi ketika register pembanding B cocok dengan isi counter T/C1 yang diaktifkan

TICI=1: interupsi diaktifkan ketika kondisi penangkapan terpenuhi

TOIE0=1: Interupsi luapan T/C0 diaktifkan

Daftar TIFR

7 6 5 4 3 2 1 0
TOV1
OCF1A
OCF1B
-
ICF1
-
TOV0
-

TOV1=1: Terjadi luapan T/C1

OCF1A=1: register perbandingan A bertepatan dengan isi counter T/C1 yang diperbolehkan

OCF1B=1: register perbandingan B cocok dengan isi counter T/C1 yang diperbolehkan

ICF=1: kondisi penangkapan terpenuhi

TOV0=1: Terjadi luapan T/C0

Saat memasuki subrutin penanganan interupsi, flag register TIFR yang sesuai dengan interupsi secara otomatis diatur ulang ke status log. 0

Interupsi hanya berfungsi ketika interupsi umum diaktifkan di register status SREG (bit 7 = 1). Ketika interupsi terjadi, bit ini secara otomatis diatur ulang ke 0, menonaktifkan interupsi berikutnya.

Dalam contoh ini, pin INT0 diaktifkan dalam mode input pull-up. Ketika pin dihubung pendek ke ground menggunakan tombol, logika 0 diatur di atasnya (tepi sinyal turun dari tegangan suplai ke 0) dan pengendali interupsi dipicu, menyalakan bola lampu yang terhubung ke pin nol port B

batalkan lampuON()
{
PORTB.0=1;
DDRB.0=1;
}

interupsi kekosongan ext_int0_isr(batal)
{
lampuON();
}

DDRD.2=0;
PORTD.2=1;

SREG|= (1 sementara(1) (

Contoh di atas juga menunjukkan bagaimana vektor interupsi diatur dalam Code Vision AVR (interrupt void ext_int0_isr(void)). Vektor interupsi diatur dengan cara yang sama untuk kasus lain:

EXT_INT0 2
EXT_INT1 3
TIM2_COMP 4
TIM2_OVF 5
TIM1_CAPT 6
TIM1_COMPA 7
TIM1_COMPB 8
TIM1_OVF 9
TIM0_OVF 10
SPI_STC 11
USART_RXC 12
USART_DRE 13
USART_TXC 14
ADC_INT 15
EE_RDY 16
ANA_COMP 17
DUA 18
SPM_READY 19

Pertama-tama, apa itu interupsi?
Interupsi adalah sejenis fungsi yang akan dieksekusi ketika sinyal tiba di beberapa input pengontrol.
Saat bekerja di AVR Studio, interupsi dibuat menggunakan makro ISR() , SINYAL() Dan MENGGANGGU(). Mereka menandai beberapa fungsi sebagai pengendali interupsi. Perbedaan mereka adalah itu MENGGANGGU() Dan ISR() tentukan fungsi penangan untuk kasus ketika interupsi umum diaktifkan (penangan dapat diinterupsi), dan SINYAL() untuk kasus ketika gangguan umum dinonaktifkan.

Dengan ini, mari kita selesaikan teorinya dan beralih ke praktik (walaupun akan ada lebih banyak teori di bawah).
Mari kita buat diagram berikut di ISIS:

Seperti yang mungkin sudah Anda duga, kami akan menulis interupsi (yang dihasilkan oleh sebuah tombol) yang akan menyala dan mematikan dioda.
Jadi, buka studio dan buat proyek standar.
Untuk menggunakan interupsi, sertakan file header:

#termasuk

Mari kita sepakat bahwa interupsi (secara fisik) tidak akan menghidupkan atau mematikan daya pada kaki pengontrol (seperti yang telah saya anggap sudah dilakukan), tetapi hanya akan mengubah bendera. Pada nilai tertentu dioda akan hidup dan mati.
Mari kita atur tanda ini secara global:

Int angka = 1;

Sekarang mari kita nyatakan interupsi:

ISR(SIG_INTERRUPT1)( jika (angka == 1) angka = 0; jika tidak angka = 1; )

Seperti yang Anda lihat, apa yang disebut vektor interupsi ditunjukkan dalam tanda kurung makro. Vektor ini memberi tahu kompiler input mana yang akan menghasilkan interupsi. Untuk INT1 adalah SIG_INTERRUPT1. Untuk ADC, misalnya, ini adalah SIG_ADC. (seluruh daftar dijelaskan dengan sempurna dalam buku “Pemrograman Shpak Yu.A. dalam C untuk mikrokontroler AVR dan PIC.”)
Sekarang mari kita beralih ke fungsi utama “program” kita.
Kita perlu mengaktifkan interupsi secara umum dan untuk INT1 khususnya:

sei(); // secara umum GIMSK |= (1<

Setelah ini selesai, Anda perlu mengkonfigurasi perilaku interupsi. Itu dapat dihasilkan dengan berbagai cara.
Unduh datasheet (ada tautan saat membuat proyek) dan temukan tabel berikut di bagian interupsi:

Saya pikir Anda akan mengerti bagaimana menerjemahkannya.
Mari kita atur status pembangkitan interupsi untuk setiap "perubahan logis ke INT1".

MCUCR = (0<

Sekarang mari kita atur seluruh port C sebagai output:

DDRC = 0xff; // port C - keluaran

Nah, ini seharusnya sudah jelas:

While (1)( if (num == 1) PORTC |= 1; // nyalakan keluaran pertama C else PORTC &= ~1; // matikan keluaran pertama C _delay_ms(100); // tunggu 100ms )

Tidak perlu menunggu. Selain itu, hal ini mengurangi kinerja. Tapi aku ingin seperti itu.
Keseluruhan program:

#define F_CPU 8000000UL // 8MHz #termasuk #termasuk #termasuk int angka = 1; ISR(SIG_INTERRUPT1)( if (num == 1) num = 0; else num = 1; ) int main (void)( sei(); GIMSK |= (1<

Kami mengkompilasi hex dan merakit sirkuit di Proteus. Kami menikmati fungsi interupsi saat mengubah posisi tombol.

Sering terjadi bahwa sirkuit mikro harus bekerja dan bekerja dengan tenang, tetapi untuk beberapa peristiwa, tinggalkan semuanya dan lakukan hal lain. Dan kemudian - kembali ke tugas awal lagi... Ini seperti jam tangan, misalnya - ini menunjukkan waktu hingga waktu jam alarm tiba. Dan sepertinya tidak ada pengaruh eksternal - menekan tombol, mengatur ulang - dan sirkuit mikro beralih sendiri.

Hal ini dapat diimplementasikan dengan menggunakan interupsi - sinyal yang menginformasikan prosesor tentang terjadinya suatu peristiwa.

Berikut ini contoh dari kehidupan sehari-hari - Anda sedang duduk di dapur, minum teh dengan selai raspberry dan camilan lezat, dan menunggu tamu. Bagaimana Anda tahu bahwa seseorang telah tiba? Ada dua pilihan: kita akan teralihkan dari kemacetan, maksud saya, teh, setiap lima menit dan berlari untuk memeriksa apakah ada orang yang berdiri di depan pintu, atau membeli bel pintu dan dengan tenang menunggu di tempat yang panas sampai seseorang membunyikannya.

Jadi, ketika ada tamu yang menelepon, ini adalah sebuah acara. Oleh karena itu, kami berhenti dan bergegas ke pintu.

Jadi, sirkuit mikro mengalami gangguan. Dan bukan hanya satu. Interupsi dibagi menjadi eksternal - ini dipicu pada tegangan tertentu pada beberapa pin sirkuit mikro (INT0, INT1 dan terkadang seluruh port PCINT) - dan internal - ketika penghitung meluap, pengatur waktu pengawas dipicu, saat menggunakan USART, ketika komparator analog, ADC dan periferal lainnya terganggu.

Oleh karena itu, timbul masalah prioritas. Ini seperti kita masih duduk dan minum teh, tetapi mereka tidak hanya membunyikan bel pintu kita, tetapi juga telepon kita... Dan Anda tidak dapat terkoyak, ada yang perlu dilakukan terlebih dahulu. Oleh karena itu, lembar data berisi tabel vektor interupsi. Semakin rendah angka interupsi, semakin tinggi prioritasnya.

Ada beberapa kehalusan di sini...

Suatu peristiwa terjadi - permintaan interupsi dikirim, yaitu, apa yang disebut "bendera permintaan interupsi" disetel. Jika semuanya baik-baik saja, gangguan teratasi, maka hidup ini indah dan berproses.

Namun jika interupsi dinonaktifkan - misalnya, interupsi dengan prioritas lebih tinggi sedang diproses - maka tanda permintaan ini akan tetap hang hingga interupsi tersebut diaktifkan. Setelah ini, chip memeriksa register permintaan dalam urutan prioritas, dan jika ada tanda, memprosesnya.

TETAPI! Ternyata meskipun interupsi sudah diproses, bukan fakta bahwa peristiwa yang menyebabkannya masih hidup... Ini seperti bel pintu dan telepon berdering pada saat yang sama, Anda menjawab telepon, dan para tamu sudah sudah memutuskan bahwa tidak ada seorang pun di rumah dan pergi. Dan sepertinya ada acara – bel pintu berbunyi, tapi tidak ada orang di balik pintu.

Masalah lainnya adalah ketika interupsi lain sedang diproses dan flag permintaan sudah dikibarkan, kejadian tersebut dapat terjadi beberapa kali lagi. Kami menjawab panggilan telepon, membuka pintu - dan sudah ada banyak tamu di sana! Menakutkan? Menakutkan...

Fitur lain dari penggunaan interupsi - dan bukan hanya interupsi: masuk kembali (atau masuk kembali).

Program reentrant adalah program yang dapat dipanggil oleh banyak pengguna (atau proses) tanpa, minimal, menyebabkan kesalahan dan, maksimal, tidak menyia-nyiakan komputasi—misalnya, pengguna lain tidak perlu menjalankan kode lagi.

Dengan kata lain, jika di dapur saat Anda menyambut tamu, tidak ada yang mencuri barang, maka semuanya masuk kembali)

Secara umum, ini adalah hal yang serius - jika Anda tidak memperhitungkannya, Anda dapat menderita untuk waktu yang lama dengan pertanyaan "mengapa tidak berhasil?!" Hal ini perlu diperhitungkan, misalnya jika beberapa interupsi diproses, dan masing-masing interupsi mengubah beberapa variabel global...

Interupsi biasanya TIDAK masuk kembali. Artinya, pada saat interupsi sedang berjalan, Anda tidak dapat memanggil interupsi yang sama lagi. Hal ini untuk melindungi dari masuknya kembali ke dalam handler maka interupsi secara otomatis dilarang pada saat pemrosesannya (jika Anda ingin mengaktifkan interupsi dalam interupsi. prosedur penanganannya, Anda perlu berpikir sepuluh, dua puluh kali sebelum mengambil langkah gegabah).

Mari kita pertimbangkan untuk bekerja dengan interupsi eksternal: pertama, kita perlu mengonfigurasi peristiwa mana yang akan memicu interupsi, dan, kedua, mengizinkan sirkuit mikro untuk memproses interupsi ini.

Register MCUCR bertanggung jawab atas bit pertama dalam chip ATmega8 - ISC11-ISC10, bertanggung jawab atas INT1, dan ISC01-ISC00, bertanggung jawab atas INT0.

Tabel 1. Definisi event untuk menghasilkan interupsi melalui INT1

Oleh karena itu, sama halnya dengan INT0.

Sekarang yang tersisa hanyalah mengaktifkan interupsi pada pin yang kita perlukan - register GIGR memiliki bit INT0 dan INT1; atur ke "1" yang diinginkan - dan interupsi eksternal diaktifkan! Namun masih terlalu dini untuk bersukacita - selain interupsi eksternal, interupsi secara umum harus diaktifkan - setel bit paling kiri I dari register SREG ke "1". Hal yang sama dapat dilakukan dengan perintah assembler: asm sei;

Mari kita lihat contoh sederhana: sebuah tombol dipasang ke pin INT0 (D.2) dari chip ATmega8 (ke pin dan ke nol); tekan - terjadi interupsi dan LED pada pin B.0 menyala. Oleh karena itu, LED terhubung ke kaki dan ke unit:

//program untuk ATmega8 ketika Anda menekan tombol pada pin INT0 (D.2) - terhubung ke 0 - //menyalakan LED pada pin B.0 melalui interupsi eksternal - terhubung ke 1 //mendefinisikan ulang tipe typedef unsigned char byte; sbit DDRButton di ddD2_bit; //tombol pembangkitan sbit pinButton di pinD2_bit; sbit portButton di portD2_bit; sbit ddrLight di ddB0_bit; //output untuk LED, untuk output pull-up, putar 0 pada tombol sbit portLight di portB0_bit; byte tombol bendera = 0; //tanda klik tombol; ditekan - 1 void INT0_interrupt() org IVT_ADDR_INT0 //Anda perlu menulis setidaknya fungsi kosong - //karena kompiler tidak membuatnya sendiri. Kalau tidak, itu tidak akan berfungsi ( flagButton = 1; ) //memproses penekanan tombol - dengan mempertimbangkan bouncing void buttonLight() ( if(flagButton) //jika tombol ditekan ( portLight = 0; //nyalakan LED delay_ms(500); portLight = 1; //matikan LED flagButton = 0; ) ) void main() ( //menginisialisasi semua port yang digunakan ddrB = 0; portB = 0; ddrD = 0; portD = 0; // menginisialisasi tombol - ke input dengan pull-up portButton = 1; //menginisialisasi LED, yang menyala dengan 0 dan dengan menekan tombol - ke output dan ke 1 portLight = 1; interupsi eksternal MCUCR.ISC00 = 0; //interupsi dihasilkan oleh logika 0 pada INT0 MCUCR.ISC01 = 0; //aktifkan interupsi eksternal INT0 asm sei;//SREG.B7 = 1; interupsi pada prinsipnya (perintah bit I mirip dengan while(1) ( buttonLight() ; ) )

Sedikit tentang sintaksis. Fungsi interupsi ditulis seperti ini: void function_name() org IVT_ADDR_INT0.

Kata kunci org menunjukkan bahwa alamat interupsi dari lembar data akan muncul berikutnya. Kami mendapatkan nama interupsi dari perpustakaan: kami mengetik IVT lalu tekan Ctrl + Spasi (Saya suka hal-hal seperti itu ˆˆ). Anda juga dapat menggunakan iv sebagai pengganti kata org, dilihat dari bantuan kompiler.

Catatan kecil lainnya: pertama, interupsi tidak boleh rumit - beberapa baris dan hanya itu. Hal ini disebabkan oleh fakta bahwa ketika memproses sebuah interupsi, sirkuit mikro tidak dapat diganggu oleh hal lain, yang berarti bahwa jika kita memiliki beberapa interupsi, maka kita dapat melewatkan terjadinya suatu peristiwa.

Mungkin juga kita tidak memerlukan pemrosesan interupsi sama sekali - misalnya, sirkuit sudah cukup bangun dari mode tidur. Namun dalam kasus ini, Anda masih perlu menulis fungsi interupsi, bahkan fungsi kosong - yang disebut "stub". Pada prinsipnya, beberapa kompiler secara otomatis menulis fungsi kosong untuk setiap interupsi, tetapi ini bukan kasus kami - kami harus melakukannya secara manual.

Hari ini kita akan melihat konsep interupsi dan cara menggunakannya. Tentu saja, kami tidak dapat melakukannya tanpa program pelatihan, tetapi kali ini kami tidak akan mengedipkan LED. Sudah bagus. Mari kita membuat sesuatu seperti bel pintu.

Tugas: membuat mikrokontroler mengeluarkan bunyi bip saat menekan tombol.
Diagram untuk contoh kita. File proyek.

Kami membuat proyek cincin di ruang kerja lama.
Tetapkan pengaturan proyek untuk konfigurasi Rilis:

Pilih jenis mikrokontroler.
Opsi Umum > Target > Konfigurasi prosesor
Saya punya ATmega8535 ini.

Izinkan penggunaan nama bit yang ditentukan dalam file header
Di Opsi Umum > Sistem, centang kotak Aktifkan definisi bit di I/O-Sertakan file
Kami belum menggunakan nama bit sejauh ini, tapi hari ini kami membutuhkannya.

Ubah jenis file keluaran.
Tautan> Keluaran.
Di kolom Output file, centang kotak Override default dan ganti ekstensi d90 dengan hex
Di bidang Format, pilih Lainnya dan di menu tarik-turun Format keluaran, pilih jenis file intel-standart

Simpan proyek dan ruang kerja.

________________ Interupsi ____________________________

Bayangkan situasinya. Anda sedang duduk di tempat kerja dan mempelajari program mikrokontroler lainnya. Bos mendatangi Anda dan berkata: “Dengar, Pash, kami membeli osiloskop untuk departemen kami - Tektronix, empat saluran. Bantu Vasya menyeret mereka.” Anda berpikir: “Ya ampun, hanya pikiran itu saja yang menghalangi... dan menimpa Anda.” Dan bosnya memandang Anda seperti itu, dan matanya sangat baik, sangat baik. Bagaimana kamu bisa menolaknya? Nah, Anda meninggalkan semuanya dan pergi bersama seorang teman untuk membeli osiloskop. Mereka membawanya masuk. Kami telah melaporkan. Dan mereka duduk untuk program mereka lagi. Kira-kira seperti inilah mekanisme interupsinya.

Cukup sederhana, tetapi ada beberapa poin mendasar.
Pertama:
- kamu melakukan pekerjaanmu
- pada saat yang sama, seseorang sedang membeli osiloskop
- setelah terjadinya peristiwa "osiloskop dibeli" - Anda menghentikan pekerjaan Anda
- untuk beberapa waktu Anda melakukan pekerjaan lain - membawa osiloskop
- kemudian Anda kembali ke tempat kerja Anda dan melanjutkan pekerjaan Anda dari bagian terakhir yang Anda tinggalkan

Kedua:
- Anda dapat dengan mudah mengirim atasan Anda dan tidak pergi kemana-mana
- setelah berangkat ke osiloskop, Anda bisa tinggal di sana untuk waktu yang lama, atau bahkan tidak kembali sama sekali
- ketika Anda kembali ke tempat kerja, Anda mungkin sudah melupakan ide cemerlang Anda

Ini semua sangat mirip dengan apa yang terjadi di mikrokontroler. Mikrokontroler AVR mencakup sejumlah perangkat periferal (pengatur waktu/penghitung, konverter analog-ke-digital, komparator analog, transceiver asinkron... dll.). Kekuatan mikrokontroler adalah semua perangkat ini dapat bekerja secara paralel dan independen satu sama lain, serta paralel dengan program yang dijalankan. Setiap perangkat periferal dapat memicu interupsi ketika peristiwa tertentu terjadi. Interupsi hanya akan terjadi jika diaktifkan. Pengaktifan interupsi diatur untuk setiap perangkat secara terpisah. Selain itu, ada flag aktif/nonaktif global untuk semua interupsi - ini adalah flag I di register SREG. Ketika terjadi interupsi, mikrokontroler menyimpan isi penghitung program PC di stack, yaitu mengingat lokasi di mana interupsi tersebut terjadi. Memuat alamat vektor interupsi yang sesuai ke dalam penghitung program dan melompat ke alamat tersebut. Itu mengenai perintah lompat tanpa syarat, yang menuju ke subrutin pemrosesan interupsi. Menonaktifkan interupsi dengan menyetel ulang bendera I, menjalankan subrutin. Setelah menjalankan rutinitas penanganan interupsi, mikrokontroler mengaktifkan interupsi dengan menyetel flag I dan mengembalikan konten penghitung program, yaitu kembali ke tempat yang sama dalam program di mana ia diinterupsi.

Secara teori, pengendali interupsi tidak boleh merusak isi register mikrokontroler, karena mungkin berisi data dari program yang sedang dijalankan. Untuk melakukan ini, pada awal subrutin penanganan interupsi, isi register mikrokontroler disimpan di tumpukan, dan pada akhir subrutin dikembalikan. Dengan demikian, setelah keluar dari interupsi, mikrokontroler akan dapat terus menjalankan program seolah-olah tidak terjadi apa-apa. Saat memprogram dalam assembler, programmer sendiri yang mengatur penyimpanan register; di C, ini dilakukan oleh kompiler.

_______________________________________________________________

Sekarang mari kita bicara tentang pengatur waktu. ATmega8535 memiliki tiga pengatur waktu/penghitung - dua delapan bit (T0, T2) dan satu enam belas bit (T1). Kami akan menggunakan pengatur waktu/penghitung delapan bit T0. Timer ini terdiri dari tiga register - register kontrol TCCR0, register penghitungan TCNT0, dan register perbandingan OCR0. Ketika pengatur waktu dimulai, register penghitung TCNT0 meningkatkan nilainya sebesar satu untuk setiap tepi jam. Frekuensi jam dipilih dari beberapa kemungkinan nilai dalam register kontrol TCCR0. Juga, dengan menggunakan register ini, mode pengoperasian pengatur waktu diatur. Timer T0 dapat memicu interupsi ketika peristiwa "melimpah" terjadi - ini adalah saat register penghitung TCNT0 meluap dan ketika peristiwa "kebetulan" terjadi - ini adalah saat nilai register penghitung TCNT0 menjadi sama dengan nilainya dari register perbandingan OCR0. Flag yang mengaktifkan interupsi ini terletak di register TIMSK.
Kami akan mengonfigurasi pengatur waktu/penghitung T0 untuk memicu interupsi peristiwa "kecocokan" pada 5 kHz. Pada fungsi handler kita akan membalikkan keadaan output mikrokontroler yang terhubung dengan speaker piezo. Dengan demikian, frekuensi bunyi piezo akan menjadi 2,5 kHz. (Yang disambung piezospeakernya! Jangan sampai tertukar. Resistansi piezospeaker tergantung frekuensi dan pada 2,5 KHz biasanya satuan Com, jadi bisa langsung disambungkan ke output mikrokontroler, tanpa a membatasi resistor).

Sekarang tentang programnya. Tidak mungkin lagi menulis program baris demi baris, jadi saya akan segera memberikan teksnya. Di bawah ini kami akan menganalisis semua lininya satu per satu, dan semuanya akan menjadi jelas. Saya sengaja tidak menggunakan makro; programnya kecil dan saya tidak ingin mengacaukannya.

ke dalam utama( ruang kosong )
{
//mengatur port I/O
DDRD = (0<PELABUHAN = (1<

//atur pengatur waktu T0
TCCR0 = (1<TCNT0 = 0;
OCR0 = 0xc8;

//aktifkan interupsi
__aktifkan_interupsi();

//loop program utama – melakukan polling pada tombol
ketika(1){
jika((PIND & (1<TIMSK = (1<kalau tidak
TIMSK = 0;
}
kembali 0;
}

//penangan interupsi untuk pengatur waktu T0

__mengganggu ruang kosong Timer0CompVect( ruang kosong)
{
PORTD ^= (1<}

Pengaturan pelabuhan

Di sirkuit kami, sebuah tombol dan speaker piezo terhubung ke port D. Pin yang menghubungkan tombol harus dikonfigurasi sebagai input dan resistor pull-up harus dihidupkan. Pin yang terhubung dengan speaker piezo harus disetel ke output.

DDRD = (0<PELABUHAN = (1<

Mengatur pengatur waktu

Mode pengoperasian pengatur waktu T0 adalah CTC (reset secara kebetulan), sinyal jam adalah clk/8. Kami mencerminkan hal ini dalam register TCCR0

TCCR0 = (1<

Untuk jaga-jaga, kami mereset register penghitungan TCNT0

Tulis 0xc8 ke register perbandingan OCR0. Mengapa? Karena saya menghitungnya kalkulator. Nah, di atas kertas perhitungannya seperti ini.
Frekuensi jam mikrokontroler 8 MHz
Sinyal jam pengatur waktu adalah 8000000 Hz/8 = 1000000 Hz.
Waktu satu jam pengatur waktu 1/1000000 = 1 µs
Waktu satu siklus frekuensi yang kita perlukan adalah 1/5000 Hz = 200 μs
Berapa banyak detak pengatur waktu yang cocok dalam 200 µs? 200/1 = 200 kutu
200 dalam heksadesimal = 0xс8

Untuk penjelasan rinci tentang pengatur waktu T0, lihat dokumentasi untuk ATMega8535.

Kami telah mengonfigurasi pengatur waktu dan mengaktifkan interupsi umum menggunakan fungsi bawaan.

__aktifkan_interupsi();

Tombol jajak pendapat

Ketika tombol tidak ditekan, keluaran mikrokontroler dihubungkan ke daya melalui resistor pull-up internal, yaitu ada satu pada keluaran; ketika tombol ditekan, keluarannya dihubung pendek ke ground, yaitu ada adalah nol pada keluarannya. Untuk menentukan apakah suatu tombol ditekan, Anda perlu membaca isi register PIND dan memeriksa nilai bit nol (tombol terhubung ke PD0). Kami akan melakukan polling tombol dalam putaran tanpa akhir.

ketika (1)
{
jika((PIND & (1<//jika tombol ditekan, mikrokontroler akan berbunyi
}
kalau tidak {
//jika tidak, diamlah seperti ikan
}
}

Jangan lupa == bukan operator penugasan =.

Tombol penanganan tekan/lepas

Dengan menekan tombol tersebut kita akan mengaktifkan interupsi pengatur waktu T0, dan dengan melepaskannya kita akan menonaktifkannya. Untuk melakukan ini, kita akan memanipulasi bit OCIE0 dari register TIMSK

TIMSK = (1<// izinkan gangguan pada pengatur waktu T0 karena kejadian yang kebetulan

TIMSK = 0; //menonaktifkan interupsi

Karena kita hanya menggunakan satu pengatur waktu, tidak perlu menyetel atau menyetel ulang bit satu per satu.

Fungsi interupsi

_____________________ Sintaks fungsi interupsi _____________________

Fungsi interupsi ditentukan menggunakan direktif #pragma vector= dan kata fungsi __mengganggu. Fungsi tersebut harus bertipe void dan tidak boleh menggunakan parameter apa pun.

#pragma vektor = Alamat
__mengganggu ruang kosong Nama( ruang kosong)
{
//kode kita terletak di sini
}

Nama– nama fungsi, pilih sesuai kebijaksanaan kami
Alamat– alamat vektor interupsi, dapat ditentukan berdasarkan nomor, atau dengan nama yang ditentukan dalam file header mikrokontroler (iom8535.h – bagian Definisi Vektor Interupsi)

______________________________________________________________

Untuk tugas kita, fungsi pengendali interupsi terlihat seperti ini

#pragma vektor = TIMER0_COMP_vect
__mengganggu ruang kosong Timer0CompVect( ruang kosong)
{
PORTD ^= (1<//membalikkan sinyal pada pin PD1
}

Ya, itu saja. Saya harap semuanya jelas.
Pada artikel selanjutnya kita akan membuat mikrokontroler memainkan melodi.

Interupsi - suatu peristiwa yang memerlukan respons segera dari prosesor. Responsnya adalah prosesor menghentikan pemrosesan program saat ini ( program terputus) dan mulai menjalankan beberapa program lain ( mengganggu program), dirancang khusus untuk acara ini. Setelah menyelesaikan program ini, prosesor kembali menjalankan program yang terputus.

Setiap acara yang memerlukan interupsi disertai dengan sinyal interupsi, memberi tahu komputer tentang hal ini, dan menelepon permintaan interupsi.

Status program mewakili sekumpulan status semua elemen penyimpanan pada titik waktu yang sesuai (misalnya, setelah perintah terakhir dijalankan). Ketika interupsi terjadi, mikrokontroler menyimpan isi penghitung program pada tumpukan dan memuat alamat vektor interupsi yang sesuai ke dalamnya. Perintah terakhir dari rutinitas interupsi harus berupa perintah yang kembali ke program utama dan memulihkan penghitung program yang disimpan sebelumnya. Saat pengendali interupsi sedang dijalankan, beberapa informasi mungkin berubah. Oleh karena itu, ketika berpindah ke pengendali interupsi, perlu untuk menyimpan elemen yang sedang diubah. Himpunan elemen-elemen tersebut adalah vektor status program. Dalam hal ini, informasi lain tentang status sel memori tidak signifikan atau dapat dipulihkan secara terprogram.

Vektor keadaan awal berisi semua informasi yang diperlukan untuk peluncuran awal program. Dalam banyak kasus, vektor keadaan awal hanya berisi satu elemen - alamat awal program yang diluncurkan.

Vektor interupsi adalah vektor keadaan awal program interupsi (penangan) dan berisi semua informasi yang diperlukan untuk berpindah ke penangan, termasuk alamat awalnya. Setiap jenis interupsi memiliki vektor interupsinya sendiri, yang memulai eksekusi pengendali terkait. Biasanya, vektor interupsi disimpan di lokasi memori tetap yang dialokasikan secara khusus dengan alamat pendek, yang mewakili tabel vektor interupsi. Untuk melompat ke program interupsi yang sesuai, prosesor harus memiliki vektor interupsi dan alamat vektor tersebut. Di alamat ini, sebagai suatu peraturan, terdapat perintah lompat tanpa syarat ke subrutin penanganan interupsi.

Sebagai aturan, kontrol penyimpanan dan pengembalian ditugaskan ke pengendali interupsi. Dalam hal ini, handler terdiri dari tiga bagian - persiapan (prolog) dan final (epilog), yang menyediakan peralihan program, dan program interupsi aktual, yang melakukan operasi yang diminta oleh permintaan. Waktu respons didefinisikan sebagai interval waktu sejak permintaan interupsi diterima hingga program interupsi mulai dieksekusi.


tp– waktu respons sistem terhadap gangguan;
tz– waktu untuk menyimpan status program yang terputus;
t hal– waktu program interupsi sebenarnya;
tidak masuk– waktu untuk memulihkan keadaan program yang terputus

Jika ada beberapa sumber permintaan, maka harus ditetapkan prosedur tertentu untuk melayani permintaan masuk, yang disebut hubungan prioritas atau disiplin pelayanan. Himpunan semua jenis interupsi prosesor yang mungkin adalah sistem interupsi mikrokontroler. Disiplin layanan menentukan mana dari beberapa permintaan yang diterima secara bersamaan yang diproses terlebih dahulu, dan apakah pengendali interupsi ini atau itu berhak untuk menginterupsi permintaan ini.
Jika permintaan interupsi dengan prioritas lebih tinggi diterima saat interupsi sedang diproses, kontrol ditransfer ke pengendali interupsi dengan prioritas lebih tinggi dan pengendali interupsi dengan prioritas lebih rendah ditangguhkan. Muncul mengganggu sarang. Jumlah maksimum program yang dapat ditangguhkan satu sama lain disebut kedalaman interupsi.

Jika permintaan interupsi tidak dilayani pada saat permintaan baru datang dari sumber yang sama (prioritas yang sama), maka mengganggu saturasi sistem. Dalam hal ini, beberapa permintaan interupsi akan hilang, yang tidak dapat diterima untuk pengoperasian normal mikrokontroler.

Karakteristik sistem interupsi adalah:

  • jumlah total permintaan interupsi jumlah sumber permintaan interupsi;
  • jenis representasi interupsi - sebagai aturan, permintaan interupsi diwakili oleh level sinyal logis;
  • prioritas interupsi – menentukan urutan pemrosesan setiap permintaan interupsi; semakin tinggi prioritasnya, semakin pendek penundaan eksekusi program interupsi;
  • waktu respons – interval waktu antara munculnya permintaan interupsi dan dimulainya eksekusi program interupsi;
  • penundaan interupsi – ditentukan oleh total waktu untuk menyimpan dan memulihkan program;
  • kedalaman, biasanya bertepatan dengan jumlah tingkat prioritas dalam sistem interupsi;
  • mengganggu saturasi sistem;
  • saat-saat gangguan program yang diperbolehkan (biasanya akhir eksekusi perintah berikutnya).

Interupsi penyamaran digunakan untuk memberitahu mikrokontroler agar merespons setiap jenis interupsi atau mengabaikannya. Masker interupsi mewakili kode biner yang bitnya dipetakan ke sumber permintaan interupsi. Satu bit dalam kode biner memberitahu mikrokontroler untuk menangani jenis interupsi ini. Sebaliknya, bit nol tidak memungkinkan mikrokontroler melanjutkan pemrosesan interupsi dari jenis yang ditentukan.
Sebagai aturan, selain menutupi interupsi, ada juga bit pengaktif interupsi global, yang nilai nolnya menonaktifkan semua penangan interupsi (kecuali untuk reset perangkat keras dan melompat ke awal program yang dijalankan).
Selain kode biner masker interupsi, ada juga kode biner bendera interupsi, yang memungkinkan pengendali interupsi untuk mengatur sumber interupsi jika ada beberapa sumber dengan permintaan yang ditentukan di mikrokontroler.



 


Membaca:



Cara Mereset Kata Sandi Administrator di Mac OS X Tanpa Disk Instalasi

Cara Mereset Kata Sandi Administrator di Mac OS X Tanpa Disk Instalasi

Meskipun judulnya ambigu, artikel ini tidak akan membahas tentang meretas akun di Mac OS X (Anda dapat membaca tentang ini jika Anda mau...

Menyiapkan Pembela Bayangan

Menyiapkan Pembela Bayangan

Dan masih banyak lagi. Secara khusus, kami telah membahas hal-hal seperti (yang juga dapat berfungsi sebagai semacam perlindungan terhadap infeksi, atau setidaknya cara untuk kembali...

Mengapa prosesor di komputer saya menjadi sangat panas?

Mengapa prosesor di komputer saya menjadi sangat panas?

Saya tidak berencana untuk menulis artikel ini; saya diminta untuk menulisnya oleh banyak pertanyaan tentang laptop yang terlalu panas, membersihkannya, dan mengganti pasta termal. Pada...

Apa itu mode "Turbo" di browser modern: Chrome, Yandex, Opera

Apa itu mode

Banyak browser web terkenal, misalnya Yandex.Browser, memiliki mode "Turbo" khusus, yang dapat meningkatkan kecepatan secara signifikan...

gambar umpan RSS