ATmega328PB i2c master mode example source

ATmega328PB에서 마스터 모드로 동작하는 i2c 예제 소스다.
i2c led 컨트롤용으로 만들었던 코드다.
급하게 만들어서 read 함수가 없다. 컨트롤용이라 write만...
datasheet를 보고 만들었다.
지금은 보드가 없어 read 함수 구현 테스트가 힘들다. 보드 생기면 구현해서 업데이트하자.

iic.h
#ifndef IIC_H_
#define IIC_H_

void iic_init(int ch);
int write_iic(int ch, int address, int *data, int len);

#endif /* IIC_H_ */

iic.c
#define F_CPU 8000000UL //
//#define F_CPU 16000000UL //

#include <math.h>
#include <stdlib.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/twi.h>
#include <util/delay.h>
#include "iic.h"
 
#ifndef TWI_FREQ
#define TWI_FREQ 100000L
#endif

#define iic_timeout_ms 100

void iic_init(int ch)
{
if(ch == 0)
{
TWSR0 &= ~(1<<TWPS0);
TWSR0 &= ~(1<<TWPS1);
TWBR0 = ((F_CPU / TWI_FREQ) - 16) / 2;
}
else
{
TWSR1 &= ~(1<<TWPS0);
TWSR1 &= ~(1<<TWPS1);
TWBR1 = ((F_CPU / TWI_FREQ) - 16) / 2;
}
}

int iic_get_status_reg(int ch)
{
if(ch == 0)
{
return TWSR0&TW_STATUS_MASK;
}
return TWSR1&TW_STATUS_MASK;
}

void iic_set_control_reg(int ch, int val)
{
if(ch == 0)
{
TWCR0 = val;
}
else
{
TWCR1 = val;
}
}

int iic_get_control_reg(int ch, int mask)
{
if(ch == 0)
{
return TWCR0&mask;
}
return TWCR1&mask;
}

int iic_wait(int ch, int time_out_ms, int state)
{
int tick = 0;
do
{
if(iic_get_control_reg(ch,(1<<TWINT)))
{
break;
}
_delay_ms(1);
tick++;
} while (tick < time_out_ms);
if(iic_get_status_reg(ch) != state)
{
return -1;
}
return 0;
}

int iic_start(int ch)
{
int tick = 0;
int twi_status = 0;
iic_set_control_reg(ch,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN));
do
{
if(iic_get_control_reg(ch,(1<<TWINT)))
{
break;
}
_delay_ms(1);
tick++;
} while (tick<iic_timeout_ms);
twi_status =iic_get_status_reg(ch);
if(twi_status == TW_START || twi_status == TW_REP_START)
{
return 0;
}
return -1;
}

void iic_stop(int ch)
{
iic_set_control_reg(ch,(1<<TWINT)|(1<<TWEN)|(1<<TWSTO));
}

void iic_send_data(int ch, char data)
{
if(ch == 0)
{
TWDR0 = data;
}
else
{
TWDR1 = data;
}
iic_set_control_reg(ch,(1<<TWINT)|(1<<TWEN));
}

int write_iic(int ch, int address, int *data, int len)
{
int i = 0;
if(!data) return -1;
// start
if(iic_start(ch) < 0)
{
return -1;
}
// address
iic_send_data(ch,address | TW_WRITE);
if(iic_wait(ch,iic_timeout_ms,TW_MT_SLA_ACK) <0)
{
iic_stop(ch);
return -1;
}
//
for(i = 0; i<len;i++)
{
iic_send_data(ch,data[i]);
if(iic_wait(ch,iic_timeout_ms,TW_MT_DATA_ACK) <0)
{
iic_stop(ch);
return -1;
}
}
iic_stop(ch);
return 0;
}


[관련 포스트]

댓글

이 블로그의 인기 게시물

base64 인코딩 디코딩 예제 c 소스

바로 프로젝트 적용 가능한 FIR Filter (low/high/band pass filter )를 c나 python으로 만들기

간단한 cfar 알고리즘에 대해

쉽게 설명한 파티클 필터(particle filter) 동작 원리와 예제

windows에서 간단하게 크롬캐스트(Chromecast)를 통해 윈도우 화면 미러링 방법