Jumat, 01 April 2016

MENAMBAH I/O PORT (I/O EXPANDER) MICROCONTROLLER ATMEGA328

Sambungan dari SPI pada UC ATMega328

Terkadang dalam suatu applikasi memerlukan I/O port yang lebih banyak atau I/O port kita tidak mencukupi. Dalam hal ini kita perlu menambah I/O port kita, penambahan I/O port tidak berarti kita mempergunakan lebih dari satu microcontroller. Yang kita perlukan adalah satu unit chip tambahan yaitu MCP23S17 dari Microchip, diperlihatkan pada gambar 1. Untuk dapat menambahkan port UC ATMega328 dengan mempergunakan I/O expander MCP23017 maka kita akan membahasnya pada subbab ini. 
 
Gambar 1. I/O Expander MCP23S17 buatan Microchip 

I/O Expander MCP23S17
Pin A0, A1 dan A2 pada gambar 1 dipergunakan untuk pengalamatan (addresssing) chip MCP23017. Format alamat chip tersebut diperlihatkan pada gambar 2. sebagai contoh jika pin A1 dan A2 dihubungkan dengan Vss atau GND dan pin A0 diberi bias +5V. Pada operasi READ maka Control Byte pada gambar 2 adalah : “0-1-0-0-0-0-1-1”. Sementara pin SI dan SO menunjukkan Serial IN (data masuk) dan Serial Out (data keluar). Kedua pin tersebut masing masing dihubungkan ke pin MOSI dan pin MISO pada UC ATMega328. Sedangkan pin SCK dan CS pada MCP23S17 masing masing dihubungkan ke pin SCK dan SS pada UC ATMega328.
  
Gambar 2. Format Control Byte komunikasi SPI pada MCP23S17

Chip MCP23S17 menyediakan 16 bit I/O yang dibagi menjadi dua port yaitu port A dan port B. Masing masing port terdiri dari 8 (delapan) bit. Master, dalam hal ini UC ATMega328, dapat menkonfigurasinya sebagai input atau output melalui register IODIRA/B. Chip I/O expander tersebut dilengkapi dengan fasilitas interrupt yaitu INTA untuk port A dan INTB untuk port B. Selain itu juga, kecepatan transfer mencapai 10 MHz artinya dapat dipicu dengan serial clock mencapai 10 MHz.
Operasi Write pada komunikasi SPI dimulai dengan meberikan sinyal LOW pada pin CS. Perintah Write (alamat MCP23017/slave dengan bit R/W berlogika LOW) kemudian dikirimkan ke MCP23S17/ yang dalam hal ini bertindak sebagai slave. Untuk operasi READ juga dimulai dengan mengirimkan sinyal LOW pada pin CS kemudian diikuti dengan perintah READ yaitu alamat MCP23S17 dengan bit R/W dalam keadaan set. Sementara untuk operasi sequential WRITE/READ, chip akan menambahkan address pointer chip tersebut setelah data ditransfer. Address pointer secara automatis akan balik ke alamaat 00h setelah alamat/register terakhir diakses.
Untuk lebih jelasnya dalam mengaplikasikan chip MCP23S17 sebagai I/O expander UC ATMega328 adalah sebagai berikut :
  1. Master, dalam hal ini UC ATMega328, membangkitkan pulsa low pada pin SS.
  2. Master mengirimkan control byte, yaitu alamat Slave yang dalam hal ini MCP23S17
  3. Master mengirimkan alamat register dari Slave yang akan digunakan.
  4. Master megirimkan atau membaca actual data.
  5. Master membangkitkan pulsa high pada pin SS

    Prosedur diatas digambarkan pada gambar 3. Register-register beserta alamat pada chip tersebut diperlihatkan pada gambar 4. 
     
                      Catatan:  Address pin A0, A1, A2 adalah di enable/disable melalui IOCON, HAEN
                       Gambar 3. Prosedur komunikasi SPI pada I/O Expander MCP23S17

GPIO PORT. GPIO module chip MCP23S17 mengandung data port (GPIOn), internal pull-up resistor dan output latches (OLATn).
 Gambar 4. Alamat register register MCP23S17

Pembacaan register GPIOn adalah membaca harga pada port tersebut. Penulisan register tersebut secara actual menyebabkan penulisan ke latch (OLATn), Sedangkan pembacaan reister OLATn hanya membaca posisi latch bukan membaca harga pada port. Sementara penulisan pada register OLATn memaksa output driver keharga/level pada OLATn. Ketika pin dikonfigurasi sebagai input maka mematikan turn-off output driver dan menjadikannya sebagai high-impedance.
Pada gambar 4 terdapat BANK -= 1 dan BANK = 0 maksudnya adalah alamat alamat register dapat berubah mengikuti harga BANK. Mengatur harga BANK (“1” atau “0”) adalah untuk memudahkan mode sequensial atau mode byte dalam pengaksesan register. Menentukan Harga BANK tersebut dengan cara mengakses bit ke-7 dari register IOCON (I/O EXPANDER CONFIGURATION REGISTER). Register-register untuk mengkonfigurasi atau mengontrol diperlihatkan pada gambar 5.
Register-register I/O Expander MCP23S17
IODIR – I/O DIRECTION REGISTER
 
catatan: R/W-1 adalah harga bit tersebut saat POR (Power on Reset) atau harga default “1”
 
Register IODIR berfungsi mengontrol/mengendalikan aliran data I/O. Ketika pada posisi set (“1”), pin yang terkait menjadi input dan ketika pada state clear (“0”) pin tersebut menjadi output. Dapat disimpulkan bahwa pengaturan I/O pada MCP23S17 berlawanan dengan pengaturan I/O pada UC ATMega328.
 
 Gambar 5. Register-register MCP23S17 dalam keadaan POR yaitu BANK = 0

IPOL – INPUT POLARITY PORT REGISTER
 
Jika bit pada register IPOL dalam state “1” maka register GPIO yang terkait dengan bit tersebut akan merefleksikan inverted value dari pin. Jika bit berharga “0” maka register GPIO akan merefleksikan harga yang sama dengan pin.

GPINTEN – INTERRUPT-ON-CHANGE PINS
 
 
Jika bit pada register GPINTEN dalam state set (“1”) maka pin yang terkait menjadi interrupt enable ketika pin tersebut mengalami perubahan logika.
1 = Enable GPIO input pin for interrupt-on-change event.
0 = Disable GPIO input pin for interrupt-on-change event.

DEFVAL – DEFAULT VALUE REGISTER
 
Register ini akan bekerja jika register GPINTEN dan register INTCON keduanya pada state enable.


INTCON – INTERRUPT-ON-CHANGE CONTROL REGISTER

 IOC7:IOC0: bit-bit ini mengendalikan interrupt-on-change. Pengaturan register INTCON terkait dengan register DEFVAL

IOCON – I/O EXPANDER CONFIGURATION REGISTER

                                                                           
bit 7 BANK: Mengatur pengalamatan register
bit 6 MIRROR: pin-pin INT merupakan mirror dari bit.
1 = pin-pin INT secara internal terhubung
0 = pin-pin INT tidak terhubung. INTA terhubung dengan PORTA dan INTB dengan PORTB
bit 5 SEQOP: Mode operasi sequensial
1 = Mode operasi sequensial di-diaable
0 = Mode operasi sequensial di-enable
bit 4 DISSLW: Mengendalikan Slew Rate pada komunikasi dengan metode I2C atau TWI.
1 = Slew rate disabled.
0 = Slew rate enabled.
bit 3 HAEN: Hardware Address Enable
1 = Enables the MCP23S17 address pins.
0 = Disables the MCP23S17 address pins.

bit 2 ODR: dipergunakan untuk mengkonfigurasi INT pin sebagai open-drain output.
1 = Open-drain output.
0 = Active driver output.

bit 1 INTPOL: dipergunakan untuk mengatur palaritas INT out pin
1 = Active-high.
0 = Active-low.

bit 0 tidak dipergunakan
GPPU – GPIO PULL-UP RESISTOR REGISTER
 
     1 = Pull-up enabled. 0 = Pull-up disabled
Jika bit berada pada state “1” maka pin yang terkait secara internal akan memiliki pull-up resistor.
 
INTF – INTERRUPT FLAG REGISTER

   1 = Pin caused interrupt. 0 = Interrupt not pending.
GPIO – GENERAL PURPOSE I/O PORT REGISTER
 
Register GPIO merefleksikan harga pada port. Pembacaan register ini merupakan pembacaan terhadap port. “1” = port high, “0” = port low. Penulisan (writing) terhadap register GPIO hanya mengubah harga pada register OLAT.

 OLAT – OUTPUT LATCH REGISTER
 
Pembacaan (Reading) pada register OLAT menghasilkan pembacaan isi register tersebut bukan harga pada port. Sementara Writing pada register mengubah output Latch yang akan mengubah pin pin yang dikonfigurasi sebagai output. 


Contoh.
/*****************************************************************************
//   PROGRAM I/O EXPANDER MENGGUNAKAN CHIP MCP23S17 PADA UC ATMEGA328
// Slave Select (PB2) dihubungkan ke CS pin
//MOSI (PB3) dihubungkan ke SI
//MISO (PB4) dihubungkan ke SO
//SCK (PB5) dihubungkan ke SCK
//GPB0 … GPB7 sebagai input yaitu dihubungkan dgn switch
//GPA0 … GPA7 sebagai output yaitu dihubungkan dgn LED
// Untuk lebih jelasnya rangkaian disajikan pada gambar 6
*****************************************************************************/
#include <avr/io.h>
#include <util/delay.h>
// MCP23S17 difungsikan sebagai SPI Slave   
#define Perintah_Write 0x40  // A2=0,A1=0,A0=0
#define Perintah_Read  0x41
// Alamat register MCP23S17 dengan BANK=0 (default)
#define IODIRA 0x00
#define IODIRB 0x01
#define IOCONA 0x0A
#define GPPUA  0x0C
#define GPPUB  0x0D
#define GPIOA  0x12
#define GPIOB  0x13

// ===== FUNGSI UNTUK WRITE ATAU MENGIRIMKAN DATA KE MCP23S17=======
void SPI_Write(unsigned char addr, unsigned char data)
{
  // Mengaktifkan CS pin yaitu PB2 pada PORTB. Aktif LOW
  PORTB &= ~(1<<PB2); 
  // Kirim perintah tulis (Write) kepada MCP23S17 (Opcode MCP23S17)
  SPDR =  Perintah_Write;
  // Tunggu sampai pengiriman perintah write selesai
  while(!(SPSR & (1<<SPIF)));
  // Kirim alamat register MCP23S17 (Control Register Address MCP23S17) 
  SPDR = addr;
  // Tunggu sampai pengiriman alamat register MCP23S17 selesai
  while(!(SPSR & (1<<SPIF)));  
  // Kirim Data  (Actual Data)
  SPDR = data;
  // Tunggu sampai Actual Data terkirim
  while(!(SPSR & (1<<SPIF)));
  // Menon-aktifkan CS pin yaitu PB2 pada PORTB. Non-aktif HIGH
  PORTB |= (1<<PB2);
}

// ======== FUNGSI MEMINTA DATA (READ) DARI MCP23S17============

unsigned char SPI_Read(unsigned char addr)
{
  // Mengaktifkan chip MCP23S17
  PORTB &= ~(1<<PB2);
  // Kirim perintah baca (READ) kepada MCP23S17  (Opcode  MCP23S17)
  SPDR =  Perintah_Read;
  //  Tunggu sampai pengiriman perintah READ terkirim
  while(!(SPSR & (1<<SPIF)));
 //  Kirim alamat register MCP23S17 (Control Register Address MCP23S17)
  SPDR = addr;
  // Tunggu sampai alamat register terkirim
  while(!(SPSR & (1<<SPIF)));  
  // Kirim dummy load untuk membaca data dari MCP23S17
  SPDR = 0x00;
  // Tunggu sampai data yang dikirimkan MCP23S17 lengkap
  while(!(SPSR & (1<<SPIF)));  
  // Menon-aktifkan MCP23S17
  PORTB |= (1<<PB2);
  return(SPDR);
}

//==========PROGRAM UTAMA=======================

int main(void)
{
  unsigned char Baca_Port; 
  
// Set  PORTD sbg Output:
  DDRD=0xFF;
  PORTD=0x00;
  // Set MOSI (PB3),SCK (PB5) and PB2 (SS) sebagai output, pin lainnnya sbg input
  DDRB = (1<<PB3)|(1<<PB5)|(1<<PB2);
 // Menon-aktifkan chip MCP23S17
  PORTB |= (1<<PB2);
  // meng-enable SPI, Master, set clock rate Fosc/2
  SPCR = (1<<SPE)|(1<<MSTR);
  SPSR |= (1<<SPI2X);
 // Inisialisasi MCP23S17 sebagai I/O Expander
  SPI_Write(IOCONA,0x28);   // I/O Control Register: BANK=0, SEQOP=1, HAEN=1 (Enable Addressing)
  SPI_Write(IODIRA,0x00);   // GPIOA sbg Output
  SPI_Write(IODIRB,0xFF);   // GPIOB sbg Input
  SPI_Write(GPPUB,0xFF);    // Enable Pull-up Resistor pada GPIOB
  SPI_Write(GPIOA,0x00);    // Reset Output pada GPIOA
  
  while(1)
 {
        Baca_Port = SPI_Read(GPIOB);    // Baca PORT B MCP23S17 (GPIOB)
        if (Baca_Port == 0xF0) 
           {
            SPI_Write(GPIOA,0xF0);         // Write  ke PORTA MCP23S17 (GPIOA), 4 LED Nyala dan 4 LED padam
            PORTD = Baca_Port;                    //PORTD ATMega328 merupakan refleksi dari GPIOB
            _delay_ms(500); 
            }         
         else
        {
          SPI_Write(GPIOA,0x0F);   // Write  ke PORTA MCP23S17 (GPIOA), 4 LED Nyala dan 4 LED padam
          PORTD = Baca_Port;            // PORTD ATMega328 merupakan refleksi dari GPIOB
          _delay_ms(500);
        }
}
  return 0;
}

// ======= AKHIR PROGRAM UTAMA ==========================
 
 
 
                                                                                                                                                                      
Gambar 6. Penggunaan MCP23S17 sebagai I/O Ekspander

Tidak ada komentar:

Posting Komentar