attiny2313 i2c slave

Обсуждаем контроллеры компании Atmel.
Ответить
KIVi
Встал на лапы
Сообщения: 126
Зарегистрирован: Вс янв 27, 2013 19:02:19

attiny2313 i2c slave

Сообщение KIVi »

У меня есть два контроллера - atmega328 и attiny2313. Они соединены по шине I2C (подтяжки 2.2 кОм). atmega выступает в роли master, attiny в роли slave. Если у atmega есть аппаратный I2C и особых проблем с ней нет, то у attiny только интерфейс-полуфабрикат USI.

И у меня это получается с переменным успехом. Код реализации I2C slave позаимствовал вот тут http://www.instructables.com/id/ATTiny- ... I2C-Slave/.

Опытным путём выяснил, что нормально фиксируется START-условие, потом он доходит до проверки адреса, но она не оканчивается ничем хорошим.

Во вложении исходный код прошивки ATTINY2313. На меге код простой:

Код: Выделить всё

        _delay_ms(1000);
	i2c_start();
	i2c_write(0x40);
	i2c_write(0);
	i2c_start();
	i2c_write(0x41);
	buf = i2c_read();
	if (buf == 0x55) led_set(LED_RED, 1);
	i2c_stop();
В 0-ом регистре i2c на attiny сохранено число 0x55 и я пытаюсь его считать, но светодиод так и не загорается - проверка не проходит. Попытка что-то записать тоже ни к чему не приводит. Управление светодиодами и функции i2c на меге точно работают, это уже проверено. Адрес slave тоже точно правильный.

P.S.: Снижение частоты шины не помогает. Качество соединений хорошее.
Вложения
pwm-controller.zip
(10.79 КБ) 235 скачиваний
Реклама
KIVi
Встал на лапы
Сообщения: 126
Зарегистрирован: Вс янв 27, 2013 19:02:19

Re: attiny2313 i2c slave

Сообщение KIVi »

Я ошибся. Проверка адреса таки проходит. А вот следующий шаг - USI_SLAVE_SEND_DATA и USI_SLAVE_RECV_DATA_WAIT не происходят уже.
Реклама
Аватара пользователя
Инженер
Прорезались зубы
Сообщения: 232
Зарегистрирован: Сб ноя 24, 2007 09:03:29
Откуда: Ульяновск

Re: attiny2313 i2c slave

Сообщение Инженер »

Вот код для CVAVR 2.05 принимающий данные по i2s с использованием USI на МК tiny2313 и выводящий в портD (адрес 0b01000000 или 0x40)
надеюсь кому-нибудь поможет
код умеет только принимать данные
Спойлер/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date : 26.05.2013
Author : Anatoliy
Company :
Comments:


Chip type : ATtiny2313
AVR Core Clock frequency: 8,000000 MHz
Memory model : Tiny
External RAM size : 0
Data Stack size : 32
*****************************************************/

#include <tiny2313.h>
#define BYTE unsigned char


// Standard Input/Output functions
#include <stdio.h>
#include <tiny2313.h>
// Declare your global variables here


unsigned char N;
unsigned char data2;


void SET_USI_TO_SEND_ACK(void)
{
PINB.5=1;
USIDR=0;
USISR=0b01111110; // установить таймер
}

void SET_USI_TO_READ_DATA(void)
{
PINB.5=0;
USISR=USISR&0b01110000; // сбросить таймер
}

void SET_USI_TO_TWI_START_CONDITION_MODE(void)
{
USICR=0b10101000;
USISR=0b11110000;
}

// USI counter overflow interrupt service routine
interrupt [USI_OVF] void usi_ovf_isr(void)
{
unsigned char data;

data=USIDR;
switch (N)
{
case 0: // проверка адреса
{
if ((data==0)||(data==0b01000000))
{
if (data&0x01)
{N=1;
}
else
{N=2; // получение данных
}
SET_USI_TO_SEND_ACK();
}
// else SET_USI_TO_TWI_START_CONDITION_MODE();
}
break;
case 1: // отправить данных
// тут должен быть код отвечающий за отправку по i2c но мне это не нужно так что тут ожидание нового старта
SET_USI_TO_TWI_START_CONDITION_MODE();
break;
case 2: // получение данных
{
N=3;
SET_USI_TO_READ_DATA();
}
break;
case 3:
{
N=2;

//Тут мы получили байт данных и что-то с ними делаем
PORTD=data;
// отправка ACK
SET_USI_TO_SEND_ACK();
}
break;
};
}

// USI start condition interrupt service routine
interrupt [USI_STRT] void usi_start_isr(void)
{
BYTE tmpUSISR;
// Place your code here
N=0;
PINB.5=0;
tmpUSISR=USISR;
while ((PINB.5==1) && !(tmpUSISR &(1<<USIPF)) );
USICR=0b11111000;
USISR=0b11110000; // сбросить таймер
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port A initialization
// Func2=In Func1=In Func0=In
// State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=0
PORTB=0xC0;
DDRB=0x00;

// Port D initialization
// Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=In Func0=In
// State6=0 State5=0 State4=0 State3=0 State2=0 State1=T State0=T
PORTD=0x00;
//DDRD=0x7C;
DDRD=0xFF;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Universal Serial Interface initialization
// Mode: Two Wire (I2C)
// Clock source: Reg.=ext. neg., Cnt.=ext. both edges
// USI Counter Overflow Interrupt: On
// USI Start Condition Interrupt: On
USICR=0b10101000;
USISR=0b11110000;


// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
DIDR=0x00;
// Global enable interrupts
#asm("sei")

while (1)
{


}
}
код предназначен для замены pcf8574 с нулевыми начальными уровнями, на данном фрагменте написан только код принимfющий данные по i2s
Ответить

Вернуться в «AVR»