Pertanyaan C - AVR - Simple PORTB, DDRB, penjelasan PINB


Saya sedang mengerjakan proyek sekolah dan perlu mempelajari dasar-dasar C dengan pengendali atmega AVR.

Saya tidak mengerti bagaimana semuanya diatur. Misalnya PORTB, PORTD, DDRB; DDRD, PINB, PIND dan hal-hal semacam itu. Dan saya tidak tahu bagaimana semuanya bekerja dengan pernyataan if, while loops, dll.

Bisakah seseorang memberi saya penjelasan singkat?

Saya memiliki beberapa baris kode ...

DDRB = 0b00000011; // I know that here DDRB is set to input/output

Dan pernyataan if:

if (PINB & (1 << PINB0)){
    A = true;
}

Dapatkah seseorang menjelaskan kepada saya bagaimana 'pernyataan jika' ini bekerja? Mengapa PINB & (1<< PINB0))?

Terima kasih


14
2018-01-08 11:00


asal


Jawaban:


Apakah Anda berarti apa itu jika-kondisi PINB & (1<< PINB0))?

Ini memeriksa apakah PINB0 + 1 bit nomor (dari rhs) adalah ON (1) dalam PINB atau MATI (0).

Sebagai contoh. (a & (1 << 2)) periksa apakah bit ketiga AKTIF a atau MATI. Dalam ekspresi, dua operator digunakan << pergeseran kiri bitwise dan & bitwise dan di bawah ini saya telah menjelaskan untuk satu contoh byte:

  1. 1 aku s 0000 0001
  2. 1 << 2   setelah shift kiri memberi 0000 0100 
  3. a bitwise dan dengan 0000 0100 memberikan semua nol 0000 0000 atau 0000 0100

    3a. Jika semua nol maka jika kondisi salah (ketika bit ketiga dalam a adalah nol).
     3b. Jika hasilnya bitwise dan apa adanya 0000 0100 maka jika kondisi dievaluasi sebagai true (ketika bit ketiga dalam a adalah satu).


12
2018-01-08 11:08



Mikroprosesor menggunakan peta memori untuk menghubungkan fungsi perangkat keras mereka dengan perangkat lunak.

Pada dasarnya, ada alamat statis dalam memori yang akan digunakan perangkat keras untuk menentukan fungsinya. Ini khusus untuk produsen, bagian, dan kadang-kadang bahkan bagaimana bagian dikonfigurasi.

Datasheet untuk bagian ini akan memberi tahu Anda lokasi memori yang tepat untuk mengontrol fungsi yang berbeda. Namun, ini biasanya sangat membosankan. Akibatnya, datasheet juga akan (hampir) selalu memberikan nama ke lokasi tertentu dalam memori yang menggambarkan fungsionalitasnya. Sekali lagi, nama-nama ini adalah produsen dan bagian tertentu.

Untuk membuat antarmuka ini lebih mudah bagi pemrogram, orang (produsen atau komunitas) sering membuat makro ke lokasi memori ini. Misalnya, Anda dapat menemukannya

// Clock Prescalar Register for ATMega328p
#define CLKPR *0x61

dalam file header yang terkait dengan bagian (seperti AVR libc).

Sekarang, dengan menulis OSCCAL = 0b10000000 (atau apa pun yang ingin saya tulis yang diizinkan oleh spesifikasi dalam datasheet) saya dapat langsung mengakses dan mengubah modul prescalar jam untuk bagian ini.

Namun, seringkali kita tertarik dengan nilai bit tunggal, bukan seluruh byte. Sebagai hasilnya, kami menggunakan operator bitwise (seperti &, |, ~, <<  >>) untuk "menutupi" bit yang ingin kita manipulasi.

Ini menawarkan keuntungan simultan dari memungkinkan kita untuk hanya membaca nilai dari bit bunga, sementara tidak secara tidak sengaja mengubah setiap bit yang kita tidak bermaksud untuk beralih.

Banyak posisi bit juga diberikan oleh macro. Misalnya, bit 7 dalam OSCCAL bernama CLKPCE (lagi, dari datasheet).

CLKPCE kemungkinan besar didefinisikan (setidaknya dalam AVR libc - standar bervariasi) oleh:

#define CLKPCE 7

karena itu mendefinisikan sedikit pergeseran yang dibutuhkan untuk mencapai bit yang diinginkan di dalam OSCCAL.

Untuk berbicara tentang sedikit di sini, saya bisa melakukan beberapa hal.

Atur sedikit

Untuk mengatur bit, kita ingin membuatnya menjadi 1, tanpa mempengaruhi bit lainnya. Untuk melakukan ini, kami menggunakan topeng ATAU, sebagai berikut:

OSCCAL = (OSCCAL | (1 << CLKPCE));

Saya akan menyerahkan kepada Anda untuk meninjau operator bit dan melihat bagaimana ini bekerja.

Bersihkan sedikit

Di sini, kami ingin membuatnya menjadi 0, tanpa mempengaruhi bit lainnya. Ini akan terlihat seperti ini:

OSCCAL = (OSCCAL & ~(1 << CLKPCE));

Permintaan sedikit

Saat kueri, kami ingin ekspresi yang menghasilkan nol jika bit disetel (1), dan nol jika bit dihapus (0). Akan terlihat seperti ini:

(OSCCAL & (1 << CLKPCE));

The Takeaway

Dengan menggunakan operasi bitwise yang berbeda ini dengan makro yang sudah ditentukan, kita dapat secara langsung mengontrol dan menanyakan status perangkat keras dengan menggunakan peta memori statis ini.

Namun, untuk memahami semua makro ini, Anda perlu berkonsultasi (dan membaca, dan membaca ulang, dan kembali membaca) lembar data untuk bagian Anda. Untungnya, PDF yang dapat dicari tersedia secara gratis dari Atmel di halaman bagian Anda!


7
2018-01-10 18:25



if (PINB & (1 << PINB0)){
        A = true;
    }

Kode ini memeriksa apakah PIN 0 in PORTB aku s HIGH or LOW. Jika tinggi maka berikan A = true; Sini, PINB -> Membaca data dari PORTB, (1<<PINB0) -> Buat bit ke-0 sebagai 1 dan ANDkedua nilai untuk mengetahui apakah PIN 0 masuk PORTB tinggi atau tidak.


5
2018-01-08 11:04



Untuk arti register, disarankan untuk berkonsultasi

  • lembar data perangkat yang Anda gunakan dan
  • file header yang dikirimkan bersama kompiler C yang Anda gunakan.

Singkatnya, huruf terakhir (B, D) berarti port yang Anda akses: pin GPIO dikelompokkan bersama 8-bijaksana sehingga setiap port memiliki 8 pin.

DDRx adalah sarana untuk mengatur arah setiap pin port.

PORTx dan PINx digunakan untuk input dan output, tetapi seperti yang biasa saya gunakan PORTA.IN, PORTB.DDR, PORTD.OUT dll., saya tidak bisa mengatakan dari hati siapa yang melakukan apa.

Untuk dasar-dasar bahasa, ada buku dan tutorial yang memungkinkan Anda mempelajari bahasa ini.


4
2018-01-08 11:28