본문 바로가기

Lab.

I2C GPIO

#include <mega128.h>
#include <delay.h>
#include <stdio.h>


    unsigned char ucNack=0;
    unsigned char ucHibyte=0;
    unsigned char ucLobyte=0;
    unsigned char lo_byte=0;
    unsigned char hi_byte=0;

void nops(unsigned char num)
{
    unsigned char i;
    for(i=0 ; i<num ;i++)
    {
      delay_us(1);
    }
}


void twi_init(void)
{
    DDRD |= 0x03; // Set SCL, SDA to output
    PORTD |= 0x03; // Set SCL, SDA High
}

void twi_start(void)
{
    DDRD |= 0x02; // Set SDA to output
    PORTD = 0x03; // Set SCL, SDA High
    delay_us(10);

    PORTD &= 0xFD; // Clear SDA
    delay_us(1);
    PORTD &= 0xFE; // Clear SCL
    delay_us(10);
}

void twi_stop(void)
{
    DDRD |= 0x02; // Set SDA to output

    PORTD &= 0xFD; // Clear SDA Low
    PORTD &= 0xFE; // Clear SCL Low
    delay_us(10);

    PORTD |= 0x01; // Set SCL High
    delay_us(10);
    PORTD |= 0x02; // Set SDA High
}

void twi_clock(void)
{
    PORTD |= 0x01; // Set SCL High
    delay_us(10); // Small delay
    PORTD &= 0xFE; // Clear SCL Low
    delay_us(10);
}

unsigned char twi_ackn(void)
{
    unsigned char ackn = 0; // Temp RAM for Ackn flag

    PORTD &= 0xFE; // Clear SCL Low
    DDRD &= 0xFD; // Set SDA to input
    PORTD |= 0x01; // Clock the ACK bit
    delay_us(10);
    if((PIND & 0x02) == 0x02) ackn=1; // Check the ACK bit on SDA
    else ackn =0;
    nops(7);
    //printf("ackn= : %d \n", ackn);
    PORTD &= 0xFE; // Clear SCL Low
    delay_us(10);

    DDRD |= 0x02;
    PORTD &= 0xFD; // Clear SDA Low

    return ackn; // Return our ACK bit
}

void write_twi_byte(unsigned char byte)
{
    unsigned char i;

    DDRD |= 0x02; // Set SDA to output
    PORTD &= 0xFE; // Clear SCL Low
    delay_us(10);
   

    for (i=0; i<8 ; i++)
    {                          
        delay_us(5);
        if((byte & 0x80)==0x80) PORTD |= 0x02; // Set SDA High
        else PORTD &= 0xFD; // Clear SDA Low

        PORTD |= 0x01; // Set SCL High, Clock data 
        delay_us(10);
        byte = byte << 1; // Shift data in buffer right one
        delay_us(10); // Small delay
        PORTD &= 0xFE; // Clear SCL
        nops(12); // Small delay  
        delay_us(10);
    }
    PORTD &= 0xFD; // Clear SDA Low
   
    if(twi_ackn()==1) ucNack=1;    
  
// while(twi_ackn()); // Check for acknowledge from I2C device
}


unsigned char read_twi_byte(unsigned char ch)
{
    unsigned char i, buff=0;

    DDRD |= 0x02; // Set SDA to Output
    PORTD &= 0xFD;
    nops(2);

    for(i=0; i<8; i++)
    {
        buff <<= 1;
        DDRD &= 0xFD; // Set SDA to input
        PORTD |= 0x01; // Set SCL High, Clock bit out
        delay_us(10);
        nops(10); // Small delay
        delay_us(10);

// Read data on SDA pin
        if ((PIND & 0x02)==0x02) {
            buff |= 0x01;
        }
        PORTD &= 0xFE; // Clear SCL
        delay_us(10);
        nops(12); // Small delay
    }

    DDRD |= 0x02; // Set SDA to Output
    if(ch==0) // Ack
    {
        PORTD &= 0xFD; // Clear SDA Low
        twi_clock();
    }
    else // No Ack
    {
        PORTD |= 0x02; // Clear SDA High
        twi_clock();
        nops(8); // Small delay
        PORTD &= 0xFD; // Clear SDA Low
        nops(4); // Small delay
        PORTD |= 0x02; // Clear SDA High
    }
    return buff;
}

void read_data(unsigned char add)
{
    ucHibyte=0;
    ucLobyte=0;

    twi_start();
    write_twi_byte(0x38);  //slave address 
    delay_us(10);

    write_twi_byte(0x38);
    delay_us(10);

    twi_start(); 
    delay_us(10);
    write_twi_byte(0x39);
    delay_us(10);

    ucLobyte=read_twi_byte(0);
    delay_us(10);           

    ucHibyte=read_twi_byte(1);
    delay_us(10);
    twi_stop();

    if (ucNack==1) printf("\n\rNo Ack!!!");
    else {
    printf("\n\rRead Data[%02X] = %02X %02X \n\r", add, ucLobyte, ucHibyte);
    }
    ucNack=0;        
}


void main(void)
{
        // USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: Off
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 57600
UCSR0A=0x00;
UCSR0B=0x08;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x10;
   
   
   
    printf("asdf");
    twi_init(); 
   
    

       
    while(1){
        read_data(0x38);
       
       
       
        delay_ms(100);
   
   
    }
}