Ini pertanyaan yang selalu ditanyakan ayahku. " Kenapa tidak menjalankan semua instruksi dan berhenti di akhir? "
Mari kita lihat contoh patologis. Kode berikut dikompilasi dalam kompiler C18 Microchip untuk PIC18:
void main(void)
{
}
Ini menghasilkan output assembler berikut:
addr opco instruction
---- ---- -----------
0000 EF63 GOTO 0xc6
0002 F000 NOP
0004 0012 RETURN 0
.
. some instructions removed for brevity
.
00C6 EE15 LFSR 0x1, 0x500
00C8 F000 NOP
00CA EE25 LFSR 0x2, 0x500
00CC F000 NOP
.
. some instructions removed for brevity
.
00D6 EC72 CALL 0xe4, 0 // Call the initialisation code
00D8 F000 NOP //
00DA EC71 CALL 0xe2, 0 // Here we call main()
00DC F000 NOP //
00DE D7FB BRA 0xd6 // Jump back to address 00D6
.
. some instructions removed for brevity
.
00E2 0012 RETURN 0 // This is main()
00E4 0012 RETURN 0 // This is the initialisation code
Seperti yang Anda lihat, main () dipanggil, dan pada akhirnya berisi pernyataan pengembalian, meskipun kami sendiri tidak secara eksplisit menempatkannya di sana. Ketika main kembali, CPU menjalankan instruksi berikutnya yang hanya merupakan GOTO untuk kembali ke awal kode. main () hanya dipanggil berulang kali.
Sekarang, setelah mengatakan ini, ini bukan cara orang akan melakukan sesuatu biasanya. Saya belum pernah menulis kode tertanam yang memungkinkan main () keluar seperti itu. Sebagian besar, kode saya akan terlihat seperti ini:
void main(void)
{
while(1)
{
wait_timer();
do_some_task();
}
}
Jadi saya biasanya tidak akan membiarkan main () keluar.
"OK, ok," katamu. Semua ini sangat menarik bahwa kompiler memastikan tidak pernah ada pernyataan pengembalian terakhir. Tetapi apa yang terjadi jika kita memaksakan masalah ini? Bagaimana jika saya memberi kode pada assembler saya, dan tidak melompat kembali ke awal?
Yah, jelas CPU hanya akan terus menjalankan instruksi berikutnya. Itu akan terlihat seperti ini:
addr opco instruction
---- ---- -----------
00E6 FFFF NOP
00E8 FFFF NOP
00EA FFFF NOP
00EB FFFF NOP
.
. some instructions removed for brevity
.
7EE8 FFFF NOP
7FFA FFFF NOP
7FFC FFFF NOP
7FFE FFFF NOP
Alamat memori berikutnya setelah instruksi terakhir di main () kosong. Pada mikrokontroler dengan memori FLASH, instruksi kosong berisi nilai 0xFFFF. Paling tidak pada PIC, kode op itu ditafsirkan sebagai 'nop', atau 'no operation'. Itu tidak melakukan apa-apa. CPU akan terus menjalankan nops-nops tersebut hingga ke memori.
Apa setelah itu
Pada instruksi terakhir, penunjuk instruksi CPU adalah 0x7FFe. Ketika CPU menambahkan 2 ke penunjuk instruksinya, ia mendapat 0x8000, yang dianggap sebagai melimpah pada PIC dengan hanya 32k FLASH, dan itu membungkus kembali ke 0x0000, dan CPU dengan senang hati melanjutkan menjalankan instruksi kembali pada awal kode , sama seperti jika itu telah diatur ulang.
Anda juga bertanya tentang perlunya mematikan. Pada dasarnya Anda dapat melakukan apa pun yang Anda inginkan, dan itu tergantung pada aplikasi Anda.
Jika Anda memang memiliki aplikasi yang hanya perlu melakukan satu hal setelah dinyalakan, dan kemudian tidak melakukan apa-apa lagi, Anda cukup meletakkannya (1); di akhir main () sehingga CPU berhenti melakukan sesuatu yang terlihat.
Jika aplikasi membutuhkan CPU untuk mematikan, maka, tergantung pada CPU, mungkin akan ada berbagai mode tidur yang tersedia. Namun, CPU memiliki kebiasaan untuk bangun lagi, jadi Anda harus memastikan tidak ada batasan waktu untuk tidur, dan tidak ada Watch Dog Timer yang aktif, dll.
Anda bahkan dapat mengatur beberapa sirkuit eksternal yang memungkinkan CPU untuk benar-benar memotong dayanya sendiri setelah selesai. Lihat pertanyaan ini: Menggunakan tombol tekan sesaat sebagai sakelar sakelar on-off yang terkunci .