Isi kandungan:

Bas I2C untuk ATtiny dan ATmega: 8 Langkah
Bas I2C untuk ATtiny dan ATmega: 8 Langkah

Video: Bas I2C untuk ATtiny dan ATmega: 8 Langkah

Video: Bas I2C untuk ATtiny dan ATmega: 8 Langkah
Video: How to make DIY I2C slave devices with ease - ATtiny Device 2024, Julai
Anonim
Bas I2C untuk ATtiny dan ATmega
Bas I2C untuk ATtiny dan ATmega

Saya suka pengawal mikro Atmel AVR! Sejak membina Sistem Pembangunan Ghetto yang dijelaskan dalam Instructable ini, saya tidak bersenang-senang bereksperimen dengan AVR ATtiny2313 dan ATmega168 khususnya. Saya bahkan menulis sehingga boleh menggunakan instruksi untuk menggunakan suis sebagai input, dan memperluas konsep Sistem Pembangunan Ghetto ke CPLD. Semasa projek baru-baru ini, saya memerlukan beberapa suis untuk menetapkan nilai kawalan. AVR tidak mempunyai pin I / O yang mencukupi, jadi saya harus memikirkan sesuatu. Saya boleh mencuba sistem input yang kompleks dengan papan kekunci dan paparan, tetapi ATtiny2313 akan kehabisan sumber. Nasib baik, Atmel telah memberikan jalan keluar untuk mengatasi masalah ini dengan memasukkan antara muka yang dapat menghubungkan ke cip tambahan (seperti memori atau port I / O) dengan antara muka dua wayar yang mudah. Betul, dengan hanya menggunakan dua pin I / O pada AVR kita dapat mengakses banyak pin I / O tambahan, dan sumber lain juga. Antara muka dua wayar ini secara formal dikenali sebagai bas Inter-Integrated Circuit, atau hanya bas I2C dan dicipta oleh NXP ketika masih Semikonduktor Philips. Sekiranya anda membaca Instructable ini, anda mungkin pernah mendengar tentang bas I2C dan mungkin pernah menggunakannya pada PIC atau mikrokontroler lain. Walaupun secara konsepnya sangat mudah, dan disokong oleh sumber perkakasan pada AVR, pemacu perisian masih diperlukan untuk menggunakan bas I2C. Atmel menyediakan Nota Aplikasi (lihat Sumber kemudian dalam Instruksinya), tetapi ini tidak lengkap dan tidak menunjukkan contoh selain berkomunikasi dengan peranti AVR lain. Ini bukan tujuan Instruksional ini untuk mengajar sesiapa sahaja cara membuat pemacu I2C untuk AVR. Sebaliknya, saya akan menyediakan versi pemacu Atmel yang diperluas untuk peranti ATtiny2313 dan ATmega168, saya akan menerangkan keperluan dan sekatan yang berlaku semasa menggunakannya, dan saya akan menunjukkan contoh kerja peranti I2C kepada anda. Selepas anda menjalani Instructable ini, anda akan dapat menggunakan bas I2C dengan jayanya dalam projek AVR anda. Jelas sekali, anda boleh mengabaikan pemacu untuk kereta kecil atau MEGA jika anda hanya berminat dengan salah satu daripada mereka. Bagi mereka yang berminat untuk mengetahui lebih lanjut mengenai bas I2C, saya akan memberikan pautan ke bahan yang sesuai.

Langkah 1: Apa Lagi Perkara I2C Ini?

Apa Lagi Perkara I2C Ini?
Apa Lagi Perkara I2C Ini?
Apa Lagi Perkara I2C Ini?
Apa Lagi Perkara I2C Ini?
Apa Lagi Perkara I2C Ini?
Apa Lagi Perkara I2C Ini?
Apa Lagi Perkara I2C Ini?
Apa Lagi Perkara I2C Ini?

Bas I2C adalah sambungan dua wayar yang mudah yang dapat menghubungkan pelbagai peranti bersama-sama dan membolehkannya bertukar data. Dalam bentuknya yang paling sederhana terdapat satu peranti induk yang berkomunikasi dengan pelbagai peranti hamba. Semua peranti disambungkan selari dengan dua wayar bas I2C. Kedua-dua wayar tersebut dikenali sebagai SCL dan SDA. SCL adalah garis jam dan dikendalikan oleh peranti induk. SDA adalah garis data dua arah. Untuk memindahkan data, master mengirimkan alamat hamba yang digabungkan dengan bendera baca / tulis satu bit. Sekiranya penulisan dikehendaki, master akan terus menghantar data kepada hamba yang ditujukan. Sekiranya bacaan diminta, hamba akan bertindak balas dengan data. Untuk menyelaraskan transaksi, garis SCL dan SDA dimanipulasi oleh tuan dan hamba untuk memberi isyarat kepada beberapa syarat. Ini termasuk START, STOP, ACK (mengakui) dan NAK (tidak mengakui). Perincian syarat-syarat ini dikendalikan oleh pemandu. Geeks yang sebenar di antara anda dapat mempelajari semua butiran dalam pautan yang disediakan di akhir Instructable ini. Keperluan elektriknya cukup mudah. Master dan budak mesti menggunakan tahap yang sama untuk Vcc, landasan mesti dihubungkan, dan garis SCL dan SDA mesti ditarik ke Vcc. Nilai resistor pull-up ditentukan dengan tepat oleh pengiraan berdasarkan jumlah kapasitansi pada bas, tetapi secara praktikal boleh menjadi nilai antara 1.8K dan 10K. Saya mulakan dengan 5.1K dan menggunakan nilai yang lebih rendah sehingga berjaya. Ini biasanya tidak menjadi masalah melainkan anda mempunyai banyak peranti atau panjang wayar antara peranti. Kadar data nominal pada bas I2C adalah 100Kbits / saat. Kadar 400Kbits / saat, 1Mbits / saat, dan seterusnya juga mungkin, tetapi tidak disokong oleh pemacu dalam Instructable ini. Semua peranti I2C akan berfungsi pada 100Kbits / saat. Masing-masing ATtiny2313 dan ATmega168 melaksanakan bas I2C secara berbeza. ATtiny2313 menggunakan perkakasan Universal Serial Interface (USI) - yang juga boleh digunakan untuk bas SPI. ATmega168 mempunyai perkakasan khusus untuk bas I2C yang dikenali sebagai Two Wire Interface (TWI). Setelah pemacu ditulis, perbezaan ini kebanyakannya telus kepada pengguna. Satu perbezaan yang ketara adalah dalam perisian: Pemacu ATmega168 I2C dipacu oleh gangguan sementara untuk ATtiny2313 tidak. Ini bermaksud bahawa program ATmega168 tidak perlu menunggu pemindahan data I2C berlangsung, tetapi hanya perlu menunggu sebelum memulakan pemindahan lain, atau sehingga data tiba dari operasi baca. Contoh dan perbincangan yang harus diikuti harus menjelaskan ini. Alamat I2C panjangnya 7 bit, sehingga 127 peranti boleh berada di dalam bas jika masing-masing mempunyai alamat yang unik. Seperti yang ditunjukkan dalam gambar, alamat 7 bit ini dialihkan ke kiri satu bit dan bit yang paling tidak signifikan digunakan untuk menandakan pembacaan atau penulisan peranti di alamat tersebut. Oleh itu, alamat hamba yang lengkap adalah bait 8 bit. Alamat sebenar ditentukan sebahagiannya secara dalaman ke peranti dan tidak dapat diubah (4 bit paling signifikan), dan sebahagiannya ditentukan oleh bit yang mungkin disambungkan ke pin peranti (3 bit paling penting) yang boleh diikat tinggi atau rendah untuk ditetapkan alamat tertentu. Kedengarannya membingungkan, tetapi satu contoh akan menjadikannya jelas. Lembaran data PCA8574A menunjukkan bahawa empat bit paling penting dari alamat I2C akan selalu 0111. Tiga bit seterusnya ditentukan oleh tetapan pada pin AD0, AD1 dan AD2. Pin ini boleh diikat ke tanah atau ke voltan positif (5 volt) masing-masing untuk mewakili 0 atau 1. Jadi julat alamat yang mungkin adalah 38 hingga 3F heksadesimal, seperti yang ditunjukkan dalam gambar lain dari lembaran data PCA8574. Oleh itu, dengan menukar tetapan bit alamat, sehingga 8 PCA8574A boleh berada di bas I2C pada masa yang sama. Masing-masing akan membalas alamat hamba khususnya sahaja. Sekiranya lebih banyak port I / O diperlukan, PCA8574 boleh digunakan. Satu-satunya perbezaan antara PCA8574 dan PCA8574A adalah bahawa julat alamat hamba I2C dari PCA8574 adalah 20 hingga 27 heksadesimal. Menentukan alamat peranti tertentu boleh membingungkan kerana beberapa helaian data menganggap bit baca / tulis sebagai sebahagian daripada alamat. Baca lembaran data dengan teliti dan ingat bahawa alamat hamba akan panjangnya 7 bit. Bit baca / tulis harus dilayan secara berasingan. Sekali lagi, contoh akan membantu. Lembar data untuk EEPROM 24C16 yang akan kami eksperimen mengatakan bahawa empat bit pertama (paling penting) dari alamat hamba adalah 1010. Tiga bit seterusnya dapat ditentukan oleh A0, A1 dan A2; tetapi perhatikan lembaran data juga merangkumi 24C01 hingga 24C08 yang berukuran lebih kecil EEPROM. Angka dari lembaran data menunjukkan bahawa tetapan bit alamat ini diabaikan ketika ukurannya meningkat dan diabaikan sepenuhnya untuk 24C16. Maksudnya, tiga bit terakhir tidak menjadi masalah dan 24C16 benar-benar menggunakan semua alamat hamba I2C 50 hingga 57 heksadesimal. Julat alamat hamba sebenarnya akan membahas bahagian yang berlainan dalam 24C16. 256 bait pertama berada di alamat 50 jam, 256 seterusnya pada 51 jam, dan seterusnya hingga 256 terakhir pada 57 jam - untuk jumlah 2K bait. Oleh kerana alamat RAM PCF8570 yang kami eksperimen juga berada dalam kisaran ini, 24C16 dan PCF8570 tidak dapat digunakan bersama.

Langkah 2: Pesan Beberapa Peranti I2C

Sekarang setelah anda mengetahui sedikit mengenai Bus I2C dan ingin menggunakannya, mengapa tidak memesan beberapa peranti I2C untuk bereksperimen sekarang agar mereka dapat berjalan lancar semasa anda menyiapkan perisian? Peranti yang sesuai termasuk I / O Interface Expander (kegemaran saya), Ram Statik, dan EEPROM. Masih banyak lagi, tetapi ini adalah permulaan yang baik. Pemproses AVR yang akan kami gunakan adalah ATtiny2313 dan Atmega168 (digunakan di Arduino). Sekiranya anda baru mengetahui ini, lihatlah Instructable yang hebat ini untuk mengetahui tentangnya dan membina Sistem Pembangunan Ghetto anda. Skema ATmega168 dalam Instructable ini menunjukkan bagaimana melaksanakan Sistem Pembangunan Ghetto untuk pemproses ini. Kabel port selari adalah sama dengan kabel ATtiny2313. (Saya belum mencuba versi USB Sistem Pembangunan Ghetto, jadi saya tidak pasti bagaimana bas I2C diakses di dalamnya. Sama untuk Arduino.) Berikut adalah nombor bahagian Digikey. Port Expander: IC I2C I / O EXPANDER 568-4236-5-NDRam: IC SRAM 256X8 W / I2C 568-1071-5-NDEEPROM: IC EEPROM SERIAL 16K CAT24C16LI-G-ND

Langkah 3: Pemacu I2C

Berikut adalah penerangan fungsi pemandu untuk bas I2C. Ini dikembangkan menggunakan Catatan Atmel Apps untuk permulaan. Saya tidak dapat melakukan ini tanpa mereka sebagai asas untuk membangun. Pembangunan dilakukan dengan menggunakan WinAVR dan gcc C compiler. Batasan kadar jam dijelaskan di bawah untuk setiap pemproses. Oleh kerana saya tidak dapat menguji semua kombinasi perasa / kadar jam pemproses yang mungkin, saya hanya akan mengikuti apa yang sebenarnya boleh saya uji dan cuba menunjukkan sekatan dan batasan. Berikut adalah fungsi pemacu dan cara menggunakannya. Lihat contohnya untuk maklumat lebih lanjut dan untuk melihat fungsi yang digunakan dalam program lengkap. Untuk ATtiny2313: Keperluan Jam: Pemacu direka untuk kadar jam 1MHz (kadar lalai) untuk ATtiny2313. Sekiranya anda ingin menjalankan dengan kadar yang lain, anda perlu menyesuaikan pemalar pada pemacu. Hantarkan e-mel kepada saya sekiranya anda memerlukan pertolongan untuk melakukan ini. Anda juga boleh mendapatkan sedikit petunjuk dari nota aplikasi Atmel dalam pautan di Langkah Sumber. USI_TWI_Master_Initialise () Fungsi ini memulakan perkakasan USI untuk operasi mod I2C. Panggil sekali pada permulaan program anda. Ia kembali batal dan tidak ada argumen. USI_TWI_Get_State_Info () Fungsi ini mengembalikan maklumat ralat I2C dan digunakan jika ralat berlaku semasa transaksi I2C. Oleh kerana fungsi ini hanya mengembalikan kod ralat, saya menggunakan fungsi TWI_Act_On_Failure_In_Last_Transmission (TWIerrorMsg) untuk memancarkan LED ralat. Kod ralat ditentukan dalam USI_TWI_Master.h. Inilah cara memanggilnya: TWI_Act_On_Failure_In_Last_Transmission (USI_TWI_Get_State_Info ()) USI_TWI_Start_Read_Write () Fungsi ini digunakan untuk membaca dan menulis bait tunggal ke peranti I2C. Ia juga digunakan untuk menulis beberapa bait. Terdapat 6 langkah untuk menggunakan fungsi ini.1) Menyatakan penyangga pesan dalam program anda untuk menyimpan alamat hamba dan bait data yang akan dikirim atau diterima. message char yang tidak ditandatanganiBuf (MESSAGEBUF_SIZE); 2) Masukkan Slave Address sebagai bait pertama dalam buffer. Geserkannya sedikit ke kiri dan ATAU di bit Baca / Tulis. Perhatikan bit Baca / Tulis akan menjadi 1 untuk Baca dan 0 untuk Tulis. Contoh ini adalah untuk Baca. messageBuf (0) = (TWI_targetSlaveAddress << TWI_ADR_BITS) | (BENAR << TWI_READ_BIT); 3) Semasa melakukan Tulis, masukkan bait untuk ditulis ke lokasi seterusnya dalam penyangga.4) Panggil fungsi USI_TWI_Start_Read_Write dengan penyangga mesej dan ukuran mesej sebagai argumen.temp = USI_TWI_Start_Read_Write (messageBuf, 2); 5) The nilai dikembalikan (temp dalam kes ini) dapat diuji untuk melihat apakah ralat berlaku. Sekiranya demikian, ia ditangani seperti yang dibincangkan di atas. Lihat contoh dalam program.6) Sekiranya Baca diminta, bacaan bait akan berada di lokasi kedua dalam penyangga. Sekiranya berbilang bait ditulis (seperti ke peranti memori), rutin yang sama ini dapat digunakan. Menyiapkan penyangga dan memanggil rutin sedikit berbeza. Bait kedua dalam penyangga akan menjadi alamat memori permulaan yang akan ditulis. Data yang akan ditulis adalah dalam bait berikutnya. Ukuran mesej akan berukuran termasuk semua data yang sah. Oleh itu, jika 6 bait ditulis, maka ukuran mesej akan menjadi 8 (alamat hamba + alamat memori + 6 bait data). USI_TWI_Start_Random_Read () Fungsi ini digunakan untuk membaca banyak bait dari peranti I2C, biasanya hanya bermakna untuk ingatan semacam. Menggunakan rutin ini sangat mirip dengan rutin sebelumnya, dengan dua pengecualian. Pengaturan bit Baca / Tulis tidak penting. Memanggil rutin ini akan selalu menyebabkan operasi Baca. Ukuran mesej mestilah 2 ditambah jumlah bait yang akan dibaca. Sekiranya tidak ada kesilapan, data akan berada di penyangga bermula di lokasi kedua. Untuk ATmega168: Keperluan Jam: pemandu direka untuk kadar jam 4MHz untuk ATmega168. Contoh kod menunjukkan cara menetapkan kadar jam ini. Sekiranya anda ingin menjalankan dengan kadar lain, anda perlu menyesuaikan pemalar pada pemacu. Hantarkan e-mel kepada saya jika anda perlu melakukan ini. TWI_Master_Initialise () Fungsi ini memulakan perkakasan TWI untuk operasi mod I2C. Panggil sekali pada permulaan program anda. Ia kembali batal dan tidak ada hujah. Pastikan untuk mengaktifkan gangguan dengan memanggil swi () setelah memulakan. TWI_Get_State_Info () Fungsi ini mengembalikan maklumat ralat I2C dan digunakan jika kesalahan berlaku semasa transaksi I2C. Oleh kerana fungsi ini hanya mengembalikan kod ralat, saya menggunakan fungsi TWI_Act_On_Failure_In_Last_Transmission (TWIerrorMsg) untuk memancarkan LED ralat. Kod ralat ditentukan dalam TWI_Master.h, tetapi diubah suai untuk memberi isyarat pada LED ralat. Lihat kod contoh untuk perincian. Inilah cara memanggilnya: TWI_Act_On_Failure_In_Last_Transmission (TWI_Get_State_Info ()) Perhatikan bahawa pemeriksaan ralat dilakukan dengan memastikan bahawa transaksi I2C selesai (fungsi yang dijelaskan di bawah) dan kemudian menguji sedikit dalam kata status global. TWI_Start_Read_Write () TWI_Start_Rm dua fungsi berfungsi sama dengan fungsi sepadan yang dijelaskan di atas tetapi dengan beberapa pengecualian. Mereka tidak mengembalikan nilai ralat. Pembacaan data tidak dipindahkan ke penyangga. Melakukan ini akan dilakukan dengan fungsi yang dijelaskan seterusnya. Semasa memanggil TWI_Start_Random_Read, messageSize mestilah bilangan bait data yang diminta ditambah satu, bukan dua. Pemacu I2C untuk ATmega168 didorong oleh gangguan. Iaitu, transaksi I2C dimulakan dan kemudian dilaksanakan secara bebas sementara rutin utama terus berjalan. Apabila rutin utama menginginkan data dari transaksi I2C yang dimulakan, ia mesti memeriksa untuk melihat apakah data tersebut tersedia. Keadaannya sama untuk memeriksa kesilapan. Rutin utama mesti memastikan bahawa transaksi I2C selesai sebelum memeriksa kesilapan. Dua fungsi seterusnya digunakan untuk tujuan ini. TWI_Transceiver_Busy () Panggil fungsi ini untuk melihat apakah transaksi I2C selesai sebelum memeriksa kesilapan. Contoh program menunjukkan cara menggunakan ini. TWI_Read_Data_From_Buffer () Panggil fungsi ini untuk memindahkan data dari buffer penerimaan pemandu I2C ke dalam buffer mesej. Fungsi ini akan memastikan transaksi I2C selesai sebelum memindahkan data. Walaupun nilai dikembalikan oleh fungsi ini, saya dapati memeriksa ralat sedikit secara langsung agar lebih dipercayai. Inilah cara memanggilnya. Ukuran Mesej mestilah lebih besar daripada bilangan bit data yang diinginkan. Data akan berada di messageBuf bermula di lokasi kedua.temp = TWI_Read_Data_From_Buffer (messageBuf, messageSize);

Langkah 4: Mari Bangun

Mari Bina!
Mari Bina!
Mari Bina!
Mari Bina!
Mari Bina!
Mari Bina!
Mari Bina!
Mari Bina!

Mulakan dengan memuat turun fail I2C Schematics.zip. Anda mungkin mahu membuat folder I2C di kawasan kerja anda untuk menyimpan skema dan contoh fail program. Buka zip skema ke dalam direktori ini. Anda akan menemui folder bernama I2C Schematics. Buka fail bernama I2C.pdf kecil. Skema ini menunjukkan Sistem Pembangunan Ghetto ATtiny2313, dan PCA8574A I / O Port Expander (mempunyai kotak putus besar di sekitarnya). Litar Port Expander dibina di atas papan roti. Lihat gambar untuk melihat seperti apa litar ini. Mereka sangat sederhana. Bahagian skema ATtiny2313 hanyalah Sistem Pembangunan Ghetto dengan tiga lampu berkedip (LED1, 2, dan 3, ditambah R4, 5, dan 6) dan butang tekan (S1) yang terpaut padanya, ditambah satu perincian tambahan. Perincian itu adalah penambahan jumper (JP4, 5, dan 6) yang dapat dikeluarkan untuk membolehkan sambungan jalur SC2 dan SDA bas I2C. Pelompat mesti berada di tempat untuk pengaturcaraan, kemudian dikeluarkan sehingga SCL dan SDA dapat disambungkan. Foto menunjukkan jumper di tempat dan dikeluarkan. Penempatan jumper ini bergantung kepada anda, anda hanya perlu memasukkannya ke Sistem Pembangunan Ghetto anda jika anda ingin menggunakan bas I2C. Bas I2C mesti diputuskan dan penerjun dipasang untuk pengaturcaraan. Perhatikan bahawa anda hanya perlu mengambil berat dengan JP4 dan JP6 untuk bas I2C. Masukkan JP5 jika anda fikir anda pasti mahu menggunakan bas SPI. Memasak Port Expander PCA8574A I / O sangat mudah. Sediakan sambungan Vcc (+5 volt) dan Gnd (tanah) dan sambungkan AD0, 1, dan 2 ke tanah (menjadikan alamat hamba I2C 38 hex). Kemudian sambungkan 4 lampu kilat, dan 4 suis DIP. (Sekiranya anda tidak mempunyai suis DIP, anda hanya boleh menggunakan wayar. Ikat ke tanah atau biarkan terapung untuk memberi isyarat hidup atau mati masing-masing.) Akhirnya, sambungkan perintang penarik (R11 dan 12) dari SDA dan SCL ke Vcc. Ini ditunjukkan sebagai 3.3K, tetapi sebarang nilai dari 1.8K hingga 5.1K harus berfungsi (mungkin sehingga 10K tetapi saya belum mencubanya). Setelah anda memprogram ATtiny2313, anda boleh mengeluarkan jumper dan menyambungkan SDA dan SCL untuk ujian. Sekarang untuk ATmega168. Satu-satunya kerutan di sini ialah anda mungkin tidak membina Sistem Pembangunan Ghetto untuk pemproses ini. Sekiranya itu berlaku, maka skema yang saya sediakan (MEGA I2C.pdf) akan menunjukkan caranya. Ini hanyalah permutasi versi ATtiny2313. Sekiranya anda merancang lebih awal, anda boleh memastikan kabel pengaturcaraan anda sesuai dengan kedua-dua sistem. Perbezaan utama adalah penambahan C2 dan C3. Lihat gambar untuk penempatan gambar ini, gambar tersebut mestilah sangat dekat dengan cip; salah satu daripadanya sebenarnya berada di bawah cip. Ini membantu mengelakkan kebisingan daripada penukar analog ke digital secara khusus. Anda tidak perlu memasukkan jumper kecuali anda merancang untuk menggunakan bas SPI kerana ia tidak diperlukan untuk bas I2C pada cip ini. Perhatikan bahawa papan roti PCA8754A tidak akan berubah. Anda hanya akan menyambungkan SDA dan SCL dan pergi! Mudah, ya?

Langkah 5: Mari Kod dan Uji

Mari Kod dan Uji!
Mari Kod dan Uji!
Mari Kod dan Uji!
Mari Kod dan Uji!
Mari Kod dan Uji!
Mari Kod dan Uji!

Sudah tiba masanya untuk membina pemacu dan program contoh. Kami akan mulakan dengan papan roti ATtiny2313 dan PCA8574A yang baru sahaja kami bina. Muat turun fail I2C.zip ke dalam direktori kerja I2C anda dan buka zip. Anda akan mempunyai folder baru bernama I2C. Di dalamnya anda akan menemui USI I2C (untuk ATtiny2313) dan TWI I2C (untuk ATmega168). Di USI I2C, anda akan menemui folder Port I_O. Folder itu mengandungi kod untuk program contoh pertama kami, dan pemacu USI I2C. Menggunakan WinAVR, menyusun dan memuatkan kod tersebut ke ATtiny2313. Tarik nafas dalam-dalam dan hidupkan kuasa. Inilah yang diharapkan: Semasa dihidupkan, LED 1 pada port PD6 ATtiny2313 berkelip dua kali. Tiada perkara lain yang akan berlaku sehingga anda menekan butang (S1). Setiap kali butang ditekan, suis dibaca dan tetapannya akan dipaparkan pada LED yang disambungkan ke PCA8574A. Tukar nilai suis, tekan butang, dan LED harus berubah. Terus lakukan ini sehingga anda merasa senang melihatnya berfungsi. Sekiranya (Tuhan melarang!) Perkara tidak berfungsi seperti yang diharapkan, periksa kabel anda dengan teliti. Kesalahan I2C akan ditandakan dengan sekelip mata pada LED3 (PD4) dan mungkin bermaksud anda perlu memastikan bahawa SDA dan SCL disambungkan ke pin yang betul dan ditarik dengan betul. Sekiranya perkara masih tidak berfungsi, baca bahagian lain ini untuk belajar mengenai penyahpepijatan. Sekarang kembali dan mari lihat kodnya. Buka fail USI_I2C_Port.c. Ini adalah kod untuk program contoh. (USI_TWI_Master.c dan USI_TWI_Master.h mengandungi pemacu - anda boleh mengabaikannya kecuali anda ingin tahu.) Gunakan contoh untuk membimbing aplikasi I2C anda sendiri. Kebanyakan, program ini menunjukkan kepada anda cara memulakan dan menggunakan pemacu I2C, termasuk menetapkan menaikkan alamat hamba dan sisa penyangga mesej, dan mengeluarkan data daripadanya. Anda juga akan melihat bagaimana saya melepaskan butang dan menyiapkan gelung sementara. Terdapat beberapa perincian program yang perlu disebutkan. Perhatikan bahawa data dari suis dibalik sebelum ditulis ke LED di Port Expander. Perhatikan juga bahawa port input pada Port Expander mesti ditulis sebagai Tinggi untuk menjadikannya berfungsi dengan baik. Perincian tersebut dijelaskan dalam lembaran data PCA8574A. Sentiasa baca lembaran data dengan teliti! Lebih menarik ialah penggunaan debug bersyarat. Menjelang permulaan fail program adalah pernyataan // # menentukan DEBUG dan ditaburkan di seluruh kodnya adalah pernyataan #ifdef DEBUG. Selagi DEBUG tidak ditentukan (dua garis miring menjadikan baris sebagai komen dan menjauhkannya daripada ditentukan), kod dalam pernyataan #ifdef hingga #endif tidak akan disusun. Tetapi jika perkara tidak berjalan seperti yang anda harapkan, kumpulkan semula dan muatkan semula kod tersebut dengan #define DEBUG tanpa komplemen. Anda akan mendapat lebih banyak sekelip mata pada LED yang boleh anda nyahkodkan untuk mengikuti pelaksanaan program anda dan membantu anda mencari tepat di mana keadaan menjadi salah. Sebenarnya, saya cadangkan anda mencuba ini hanya untuk melihat apa yang berlaku. Apa yang anda akan lihat ialah LED 2 (pada PD5) akan berkelip ketika pelaksanaan dijalankan melalui program. Nilai yang dibaca dari suis akan berkedip pada LED 1 (PD6) sebelum dipaparkan pada Port Expander LED. Anda seharusnya dapat mengesan program semasa berjalan dengan menggunakan LED ini. Kami akan bekerjasama dengan ATmega168 seterusnya; langkau bahagian ini jika anda hanya berminat dengan ATtiny2313. Masih dengan saya? Baik. Pindah ke folder TWI_I2C, ubah direktori kerja anda ke IO_Port, dan kompilasi dan muat TWI_I2C_Port.c ke dalam ATmega168. Putuskan sambungan SDA dan SCL dari ATtiny2313 dan sambungkannya ke ATmega168. Hubungkan daya dan tanah, dan hidupkan. Operasi harus sama! Main sehingga keseronokan mereda, kemudian mari lihat kodnya. Buka TWI_I2C_Port.c. Kodnya hampir sama kecuali untuk pengendalian ralat dan menampung pemacu yang disekat. Berikut adalah perbezaannya: Perhatikan bahawa jam mesti ditetapkan ke 4MHz agar bas I2C berfungsi dengan baik. Sei (); pernyataan menghidupkan gangguan selepas permulaan pemacu I2C. Untuk memeriksa kesilapan, bit status tertentu diuji. Semasa pembacaan, fungsi TWI_Read_Data_From_Buffer mesti dipanggil untuk memindahkan data yang dibaca ke dalam penyangga mesej. Semasa menulis, sementara (TWI_Transceiver_Busy ()) mesti digunakan untuk memastikan pemindahan selesai sebelum memeriksa kesalahan. Dua fungsi terakhir ini dijelaskan di atas dalam penerangan pemacu. Selain daripada itu, kodnya hampir sama dengan ATtiny2313. DEBUG berfungsi sama juga jika anda ingin bereksperimen dengannya.

Langkah 6: Menggunakan Memori I2C

Menggunakan Memori I2C
Menggunakan Memori I2C
Menggunakan Memori I2C
Menggunakan Memori I2C
Menggunakan Memori I2C
Menggunakan Memori I2C
Menggunakan Memori I2C
Menggunakan Memori I2C

Sekarang setelah kita belajar menggunakan bas I2C untuk membaca dan menulis Port Expander I / O, mari beralih menggunakan memori I2C, baik RAM dan EEPROM. Perbezaan utama adalah bahawa beberapa bait boleh dibaca atau ditulis dari kenangan dengan satu perintah I2C. Untuk bersiap sedia untuk percubaan ini, kita perlu sedikit mengubah suai perkakasan dan membina beberapa litar baru di papan roti. Simpan litar Port Expander kerana kami akan menggunakannya untuk memaparkan beberapa nilai memori. Tanggalkan suis DIP dari PCA8574A dan letakkan lampu berkedip pada pin tersebut. Sekiranya anda tidak mempunyai lampu kilat yang mencukupi, gerakkan lampu pada P4 hingga P7 ke P0 hingga P3. (Nilai yang akan ditunjukkan cukup kecil.) Sekarang lihat skema I2C Ram.pdf dan sambungkan PCF8570 pada papan roti. Lihat gambar juga. Pastikan mengikat pin 7 ke Vcc. Jalankan wayar untuk SDA dan SCL dari PCA8574A. Tidak diperlukan perintang penarik tambahan. Sekiranya anda juga berminat dengan EEPROM, bina litar itu juga menggunakan I2C EEPROM.pdf untuk 24C16, tetapi diberi amaran bahawa contohnya menggunakan ATmega168. Litar ini sungguh mudah. Seperti yang dibincangkan di atas, bit alamat harus diabaikan. Hanya sambungkan kuasa dan tanah. Jangan sambungkan SDA dan SCL dulu kerana kami belum selesai bereksperimen dengan Ram. Kami akan memulakan eksperimen memori kami dengan ATtiny2313 yang disambungkan ke PCA8574A Port Expander dan ke PCF8570 Ram. Program ini akan menulis beberapa nombor kepada Ram, kemudian membacanya kembali dan memaparkannya di Port Expander. Tukar direktori kerja anda ke RAM di bawah USI I2C. Gunakan fail buat untuk menyusun dan memuat turun USI_I2C_RAM.c. Perhatikan bahawa fail pemacu I2C sama dengan yang kami gunakan sebelumnya. Sambungkan kuasa dan anda akan melihat sekelip mata pada LED 1 (PD6). Data akan ditulis ke memori 4 bait pertama. Tekan butang dan dua bait akan dibaca kembali dan dipaparkan. Anda harus melihat satu lampu LED di Port Expander (P0), jeda dua saat, kemudian dua lampu LED (P0 dan P1). Jeda dua saat lagi dan LED harus mati. Tekan butang sekali lagi untuk memulakan urutan semula. Debugging serupa dengan kaedah yang dijelaskan di atas. Mari lihat kodnya. Buka USI_I2C_RAM.c. Ia mesti kelihatan serupa dengan kod sebelumnya. Perbezaan utama adalah perincian memori membaca dan menulis. Lihat cara penyangga mesej dimuat sebelum panggilan yang benar-benar menulis. Bait pertama adalah alamat hamba dengan set bit baca / tulis dengan betul. Tetapi bait seterusnya adalah alamat memori untuk mula menulis data. Kemudian datang bait data sebenar yang akan dimuat secara berurutan ke dalam memori bermula dari alamat yang kami tentukan. Kami menentukan ukuran mesej sebagai 6. Oleh itu, kami mula menulis di alamat 00 dan menulis nilai 01, 03, 02 dan 06 ke lokasi memori 00 hingga 03. Untuk membaca data dari memori, kita mesti menggunakan fungsi USI_TWI_Start_Random_Read. Penyangga mesej mendapat alamat hamba dalam bait pertama dan alamat permulaan dalam bait kedua. Kemudian panggil fungsi dengan ukuran mesej yang ditetapkan ke bilangan bait untuk dibaca ditambah 2. Perhatikan bahawa bit baca / tulis tidak penting kerana pembacaan akan dilakukan tanpa mengira. Data yang dikembalikan akan bermula di lokasi kedua dalam penyangga mesej. Setelah data dibaca, data akan dibalikkan untuk dipaparkan di Port Expander dan ditulis satu bait demi satu dengan jeda antara nilai. Akhirnya, LED Port Expander dimatikan. Penulisan ke Port Expander sama dengan apa yang dilakukan dalam contoh sebelumnya. Untuk bersenang-senang, anda boleh melepaskan pernyataan #define DEBUG seperti di atas dan melihat banyak LED yang berkedip. Teruja dengan kegembiraan setelah percubaan lain yang berjaya, mari beralih ke ATmega168 dan EEPROM. Tukar direktori kerja anda ke EEPROM di bawah TWI I2C. Gunakan fail buat untuk menyusun dan memuat turun TWI_I2C_EEPROM.c. Perhatikan bahawa fail pemacu I2C sama dengan yang kami gunakan sebelumnya untuk PCA8574A. Untuk menguji program, putuskan sambungan ATtiny2313 dan sambungkan ATmega168. Biarkan bas I2C terpasang pada Ram dan hidupkan. Hasilnya berbeza kerana sekarang kami menulis dan membaca lebih banyak data. LED 1 pada PD7 harus berkelip semasa inisialisasi. Tekan butang dan data akan dibaca kembali dari memori dan dipaparkan. LED pada PCA8574 harus berkelip mengikut urutan berikut: P1, P0 & P2, (semua mati), P0 & P1, P1 & P2. Akhirnya Port LED semua padam. Tekan butang sekali lagi untuk mengulanginya. Oh, tapi tunggu, anda katakan. Bukankah program ini untuk EEPROM? Oleh kerana kami mengakses peranti memori di alamat I2C yang sama, program yang sama berfungsi untuk Ram dan EEPROM. Matikan dan alihkan SDA dan SCL dari Ram ke EEPROM dan jalankan program sekali lagi. Ia mesti berfungsi sama. Perhatikan bahawa EEPROM dan Ram tidak dapat dihubungkan ke bas I2C pada masa yang sama kerana mereka berkongsi alamat yang sama. (Yang pandai di antara anda mungkin mempertimbangkan untuk menukar bit alamat yang dapat diprogram pada Ram, tetapi itu masih tidak akan berfungsi. 24C16 menggunakan keseluruhan blok alamat yang dapat diprogram untuk Ram.) OK, mari kita lihat program terakhir ini. Buka TWI_I2C_EEPROM.c. Perkara pertama yang perlu diberi perhatian adalah bahawa saya telah menunjukkan cara menangani EEPROM 24C16 yang lengkap. Ia dapat diakses dalam potongan 256 bait pada 8 alamat hamba I2C yang berbeza. Lihat bagaimana MEMORY_ADDR ditakrifkan sebagai alamat permulaan pada 50 heksadesimal; sebab itulah Ram bekerja. Sekiranya anda ingin mengakses blok 24C16 lain, maka gunakan alamat lain seperti yang saya nyatakan. Lihat bagaimana saya mengatur untuk menulis ke memori. Pertama alamat hamba dengan set bit baca / tulis dimasukkan ke dalam penyangga, kemudian alamat permulaan 00, kemudian 16 bait data. Fungsi TWI_Start_Read_Write dipanggil untuk menulis data (seperti sebelumnya) dengan ukuran pesan ditetapkan ke 18. Ketika butang ditekan, kami menggunakan TWI_Start_Random_Read dan TWI_Read_Data_From_Buffer untuk membaca kembali data. Setiap bait ketiga dipaparkan pada Port Expander LED. Akhirnya, LED dimatikan untuk menunggu penekanan butang seterusnya. Anda mungkin tertanya-tanya mengapa saya memilih untuk menulis 16 bait. Sekiranya anda membaca lembaran data dengan teliti, anda akan melihat bahawa 24C16 melakukan kitaran penulisan setiap kali ia menerima 16 bait walaupun lebih banyak bait dihantar. Jadi itu sepertinya nombor yang bagus untuk digunakan. Sekiranya anda memilih untuk meningkatkan ini, anda mesti menukar ukuran MESSAGEBUF_SIZE. Anda juga perlu menukar nilai TWI_BUFFER_SIZE dalam TWI_Master.h. Ini kerana pemandu menyalin data dari buffer mesej untuk digunakan oleh rutin perkhidmatan gangguan. Tahniah! Anda kini sudah bersedia untuk menggunakan bas I2C dalam projek anda sendiri!

Langkah 7: Sumber Web

Berikut adalah pautan ke lembaran data untuk bahagian yang digunakan untuk eksperimen. Anda pasti mendapatnya jika anda tidak mendapat apa-apa lagi. Port ExpanderRamEEPROM Menjadi pencipta I2C, NXP (Philips) mempunyai banyak barang. (Mereka suka menggunakan tanda kurung dalam URL mereka, jadi saya tidak dapat memasukkannya dengan betul di sini. Maaf.] Untuk sampai ke kawasan I2C, pilih Antaramuka dari senarai Produk. Anda akan dapat ke laman I2C mereka dan akses ke semua lembar data dan nota aplikasi yang mereka tawarkan. Perihalan bas I2C dan butiran teknikal khususnya ada di sini. Dapatkan lembaran data ATtiny2313 dan ATmega168 (buku data?) dari Atmel. Nota aplikasi Atmel ada di sini. Lihat AVR310 dan AVR315. Dapatkan kod juga. Lihat di sini untuk lebih banyak barangan I2C.

Langkah 8: Catatan untuk Geeks

Untuk geek sejati yang ingin mengetahui perinciannya, berikut adalah beberapa perkara yang perlu diingat jika anda melihat Nota Aplikasi Atmel dan kod pemacu: - Kaedah menangani dan memerintah peranti I2C bukan sebahagian daripada spesifikasi! Selain daripada alamat hamba dan bit baca / tulis, perintah, mod, dll tidak ditentukan dan khusus untuk peranti tertentu. Untuk memperjelasnya, perhatikan bahawa skema yang digunakan dalam contoh Atmel hanya berlaku untuk contoh itu, dan agak tidak standard.- Pelaksanaan USI berbeza dengan pelaksanaan TWI dengan beberapa cara penting. + Dengan USI, penjadualan disediakan oleh perisian; dengan TWI ia disediakan oleh Penjana Kadar Bit. + Kaedah USI tidak menggunakan gangguan; TWI tidak. Ini masuk akal kerana keluarga Mega (menggunakan TWI) dapat melakukan banyak perkara lain dan tidak boleh diganggu oleh pemindahan I2C. Versi yang didorong oleh gangguan untuk USI memang mungkin, ia tidak dilaksanakan dalam Instructable ini. Perkakasan USI tidak dioptimumkan untuk I2C dan hanya dapat menangani pemindahan 8 bit. Ini bermaksud bahawa dua pemindahan diperlukan untuk menghantar bit kesembilan (sama ada NACK atau ACK). Perkakasan TWI mengendalikannya secara automatik. Ini menjadikan pelaksanaan pemacu USI sedikit lebih rumit. + Pengesanan ralat untuk TWI dikendalikan dalam perkakasan. USI memerlukan pengendalian dalam perisian yang merumitkan keadaan. + Perkakasan TWI mengawal konfigurasi port secara langsung. Perkakasan USI memerlukan bit port dikonfigurasi sebelum port dapat digunakan. Anda akan melihatnya dalam rutin Master_Initialize untuk USI.- Atmel mendakwa mungkin menggunakan penarikan port AVR untuk penarikan bas I2C. Saya belum menemui kaedah untuk menjadikan pendekatan itu berjaya. Menggunakan dua perintang luaran sepertinya skema yang cukup mudah, jadi saya tidak menghabiskan banyak masa untuk ini.

Disyorkan: