AlexTech
Jan 31 2011, 08:29
Поделитесь опытом плиз, слейв упорно ack отсылать не хочет :/
ILYAUL
Jan 31 2011, 08:50
Цитата(AlexTech @ Jan 31 2011, 11:29)

Поделитесь опытом плиз, слейв упорно ack отсылать не хочет :/
Браво, это же надо же какое слово
ИМПЛЕМЕНТАЦИЯ ИМПЛЕМЕНТАЦИЯ (от лат. impleo - наполняю, исполняю), осуществление, исполнение ГОСУДАРСТВОМ международных правовых норм. Каждое государство само определяет методы и средства имплементации. В международном договоре также может быть предусмотрена необходимость издания закона или иного акта для его осуществления К чему это слово Вы употребили?
Как не однократно писалось на форуме , к огромному сожалению телепатов здесь нет- схему , код
alexeyv
Jan 31 2011, 09:07
Application note AVR312 Using USI as I2C Slave
Application note AVR310 Using USI as TWI
Application note AVR319 Using USI as SPI
to ILYAUL
Из англо-русского словаря:
Цитата
implementation - выполнение, исполнение, осуществление, РЕАЛИЗАЦИЯ
Synonym: realization , accomplishment
Вы где находитесь, на форуме юристов или на форуме програмистов ?!?!
ILYAUL
Jan 31 2011, 09:09
Цитата(alexeyv @ Jan 31 2011, 12:07)

Application note AVR312 Using USI as I2C Slave
Application note AVR310 Using USI as TWI
Application note AVR319 Using USI as SPI
to ILYAUL
Из англо-русского словаря:
implementation - выполнение, исполнение, осуществление, РЕАЛИЗАЦИЯ
Вы где находитесь, на форуме юристов или на форуме програмистов ?!?!
Всё верно , только это слово применяется в юридических документах.
alexeyv
Jan 31 2011, 09:17
Цитата
Всё верно , только это слово применяется в юридических документах.
ДА НУ !!!!!!!
Откройте например правила оформления модуля в Object Pascal :
Код
unit NAME;
interface
.......
implementation // !!!!!!!!!!!!!!!!!!!!!
......
end.
Не говоря уж о хардварных языках, например, VHDL.
Да и сам Atmel выдает:
AVR302: Software I2C™ Slave Implementation
ILYAUL
Jan 31 2011, 09:25
Цитата(alexeyv @ Jan 31 2011, 12:17)

ДА НУ !!!!!!!
Откройте например правила оформления модуля в Object Pascal :
Код
unit NAME;
interface
.......
implementation // !!!!!!!!!!!!!!!!!!!!!
......
end.
Не говоря уж о хардварных языках, например, VHDL.
Убедили , не знал . Хотя наши юристы , его применяют исключительно , в гос. документах
AlexTech
Jan 31 2011, 09:27
Простите, русский с английским в голове перемешиваются )))
Собственно вот отсюда взято - "AVR310:..... This application note describes a TWI master implementation"
С английского implementation — «осуществление», «выполнение» и только по русски это имеет отношение именно к международному праву ))))
Схема... ну какая схема, два провода между мастером на меге128 и слейвом на тинке26 плюс часики ds1307.
Работает что нибудь одно, или читаю часики или пишу в слейв.
сначала протеус говорил что поддельные данные на линии SCL, код инициализации слейва был такой:
CODE
// прям в этой строчке протеус ругался и останавливал обмен, в железе же слейв был доступен, часики нет
DDR_USI |= ( 1 << PORT_USI_SCL ) | ( 1 << PORT_USI_SDA );
PORT_USI |= ( 1 << PORT_USI_SCL );
PORT_USI |= ( 1 << PORT_USI_SDA );
DDR_USI &= ~( 1 << PORT_USI_SDA );
USICR =
( 1 << USISIE ) |
( 0 << USIOIE ) |
( 1 << USIWM1 ) | ( 0 << USIWM0 ) |
( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
( 0 << USITC );
USISR = ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | ( 1 << USIDC );
поменял немного, стало так:
PORT_USI |= (1<<PORT_USI_SCL);
PORT_USI |= (1<<PORT_USI_SDA);
DDR_USI |= (1<<PORT_USI_SCL);
DDR_USI &= ~(1<<PORT_USI_SDA);
USICR = (1<<USISIE)|(0<<USIOIE)|(1<<USIWM1)|(0<<USIWM0)|(1<<USICS1)|(0<<USICS0)|(0<<USICLK)|(0<<USITC);
USISR = 0xF0;
протеус ругаться вроде перестал, часики читаются, но слейв теперь не отдает ack(ну я так думаю)
ISR( USI_OVERFLOW_VECTOR )
{
switch ( overflowState )
{
case USI_SLAVE_CHECK_ADDRESS:
if ( ( USIDR == 0 ) || ( ( USIDR >> 1 ) == slaveAddress) ) // проверяем адрес
{
if ( USIDR & 0x01 )// read/write
{
overflowState = USI_SLAVE_SEND_DATA;
}else{
overflowState = USI_SLAVE_REQUEST_DATA; // ставим флаг получить данные, сюда попадаем
}
SET_USI_TO_SEND_ACK( ); //шлем ack
// сюда попадаем
}else{
SET_USI_TO_TWI_START_CONDITION_MODE( );
}
break;
case USI_SLAVE_REQUEST_DATA: // а блин вот сюда никогда больше не попадаем
overflowState = USI_SLAVE_GET_DATA_AND_SEND_ACK;
SET_USI_TO_READ_DATA( );
break;
}
}
SET_USI_TO_SEND_ACK( )
{
USIDR = 0;
DDR_USI |= ( 1 << PORT_USI_SDA );
USISR = ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | ( 1 << USIDC )| ( 0x0E << USICNT0 );
}
Ух, как то так ))
alexeyv
Jan 31 2011, 10:06
1. Я понял, что Tiny26 использует USI как TWI в режиме слейва?? тогда надо смотреть пример из AVR312, а не AVR310.
2. А при отсоединении ds1307, поведение не меняется?
AlexTech
Jan 31 2011, 10:11
по 312 и сделано, и мной, и несколько чужих исходников пробовал, поведение одинаковое
протеус не ест вообще то, что по 312 сделано, ну да бог с ним, в железе кое как работает
в первом варианте при отсоединении часов ничего не меняется, меняется именно при отсоединении тинки, часы читаться сразу нормально начинают
а во втором варианте, как я написал, тинка не мешает часам, но не попадает собственно в процедуру приема
alexeyv
Jan 31 2011, 10:26
1. А адресс Tiny26 случайно не совпадает с адресом DS1307 ??
2. Где прерывание USI_Start_Condition ?
3. Осциллографом не пробовали смотреть обмен на линии ??
AlexTech
Jan 31 2011, 10:30
Нет )))
я так понимаю что тинка гадит на scl и мешает часам, а если это гаженье убрать (вот тут мне не отловить косяк) то ли мастер не понимает ack который
тинка шлет после проверки адреса и соответственно не передает данные, то ли тинка его реально не отправлят
ILYAUL
Jan 31 2011, 10:34
Цитата(AlexTech @ Jan 31 2011, 13:30)

Нет )))
я так понимаю что тинка гадит на scl и мешает часам, а если это гаженье убрать (вот тут мне не отловить косяк) то ли мастер не понимает ack который
тинка шлет после проверки адреса и соответственно не передает данные, то ли тинка его реально не отправлят
Отсоедините часы , зациклите START и Адрес , посмотрите , что на шине, как я понял в железе есть.
AlexTech
Jan 31 2011, 11:11
В железе есть, да, а чем смотреть то?
осциллографа нет, поэтому в протеусе и тестил, а он оказывается таких извратов не понимает ))
разве что леды на шину воткнуть :/
Вот старт:
Код
ISR( USI_START_VECTOR )
{
overflowState = USI_SLAVE_CHECK_ADDRESS;
DDR_USI &= ~( 1 << PORT_USI_SDA );
while (
// SCL his high
( PIN_USI & ( 1 << PIN_USI_SCL ) ) &&
// and SDA is low
!( ( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
);
if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
{
// not stop
USICR =
( 1 << USISIE ) |
( 1 << USIOIE ) |
( 1 << USIWM1 ) | ( 1 << USIWM0 ) |
( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
( 0 << USITC );
}else{
// stop
USICR =
( 1 << USISIE ) |
( 0 << USIOIE ) |
( 1 << USIWM1 ) | ( 0 << USIWM0 ) |
( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
( 0 << USITC );
}
USISR =
// clear interrupt flags and release SCL
( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) |
( 1 << USIPF ) |( 1 << USIDC ) |
( 0x0 << USICNT0);
}
andron86
Jan 31 2011, 11:36
Цитата(AlexTech @ Jan 31 2011, 10:27)

Схема... ну какая схема, два провода между мастером на меге128 и слейвом на тинке26 плюс часики ds1307.
....
Ух, как то так ))
ух ты, схема крутая, точно работать не будет
AlexTech
Jan 31 2011, 11:41
Лан, не надо ляля ))) все будет, ну не расписывать же мне всю обвязку
все заводится, и по отдельности работает )))
alexeyv
Jan 31 2011, 11:54
1. Процедура приема начала кадра мне не нравится. Зачем вы там выбираете из двух режимов работы по состоянию PIN_USI_SDA?
2. Есть ли какой-нибудь debug-интерфейс, типа USART подключенного к ПК?
AlexTech
Jan 31 2011, 12:00
Нууу... как придумал так и написал

а какие есть варианты? можно там конечно вообще ничего не делать, ну в другом месте тот же код будет...
да, есть usart, мега может отправлять данные в комп
alexeyv
Jan 31 2011, 12:02
А debug-интерейс на Tiny, вы же ее отлаживаете?
например так:
Код
__interrupt void USI_Start_Condition_ISR(void)
{
unsigned char tmpUSISR; // Temporary variable to store volatile
tmpUSISR = USISR; // Not necessary, but prevents warnings
// Set default starting conditions for new TWI package
USI_TWI_Overflow_State = USI_SLAVE_CHECK_ADDRESS;
DDR_USI &= ~(1<<PORT_USI_SDA); // Set SDA as input
while ( (PIN_USI & (1<<PORT_USI_SCL)) & !(tmpUSISR & (1<<USIPF)) ); // Wait for SCL to go low to ensure the "Start Condition" has completed.
// If a Stop condition arises then leave the interrupt to prevent waiting forever.
USICR = (1<<USISIE)|(1<<USIOIE)| // Enable Overflow and Start Condition Interrupt. (Keep StartCondInt to detect RESTART)
(1<<USIWM1)|(1<<USIWM0)| // Set USI in Two-wire mode.
(1<<USICS1)|(0<<USICS0)|(0<<USICLK)| // Shift Register Clock Source = External, positive edge
(0<<USITC);
USISR = (1<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Clear flags
(0x0<<USICNT0); // Set USI to sample 8 bits i.e. count 16 external pin toggles.
}
AlexTech
Jan 31 2011, 12:10
Я честно не ожидал таких сложностей с usi, поэтому не предусмотрел на тинке ничего, можно конечно проводки бросить...
Только не могу чет сообразить... тинка на 8мгц, битрейт 9600, она будет успевать передавать то...
В любом случае могу прокидывать в комп хотя бы то что на мастере творится, вечером попробую )
Вы предлагаете вообще выбросить все действия при определении старт/стоп? или мы их куда то переносим?
alexeyv
Jan 31 2011, 12:14
Никуда ничего не переносим. В стартовом прерывании определяем старт и включаем прием байта
AlexTech
Jan 31 2011, 12:22
Я ничего не путаю? это же не twi, а usi, нам по стопу надо бы ручками scl придушить??? а мы его перестаем обрабатывать в вашей версии
alexeyv
Jan 31 2011, 12:29
стоп-кондишен обрабатывается в
Код
while ( (PIN_USI & (1<<PORT_USI_SCL)) & !(tmpUSISR & (1<<USIPF)) );
какая частота у УСИ/ТВИ?
AlexTech
Jan 31 2011, 12:41
100кгц
Спасибо за подсказки, попробую, отпишусь по результатам что получится )
ILYAUL
Jan 31 2011, 14:00
А мы вообще на старт ответили? С часами всё ясно, ковырять прогу со стороны мастера нет необходимости, часы пашут ,но там автомат . А вот слейв , он ведь на старт должен ответить
AlexTech
Jan 31 2011, 14:59
Я думал что вот это:
USISR = (0<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|(0xE<<USICNT0);
while ( !(USISR & ( (1<<USISIF)|(1<<USIOIF) )) );
должно отвечать, но как то не очень получается )))
написал вместо этого дикость типа:
DDR_USI |= (1<<PORT_USI_SDA);
PORT_USI &= ~(1<<PORT_USI_SDA);
asm volatile ("NOP" :

;
PORT_USI |= (1<<PORT_USI_SDA);
DDR_USI &= ~(1<<PORT_USI_SDA);
как ни странно стало лучше, протеус по крайней мере теперь видит этот ack, ну а дальше все равно фигня...
Вот протокол обмена с часиками
S D0 A 00 A Sr D1 A 55 A 57 A 17 A 02 A 31 A 01 A 11 N P
А вот с тинкой
S 4C N P
иногда вот так
S 4C N Sr P
и после шаманства вот так
S 4C A 41 N P
кстати в инициализации должно бы быть DDR_USI |= (1<<PORT_USI_SCL); но протеус этого вообще не переваривает (
ILYAUL
Jan 31 2011, 17:43
Цитата(AlexTech @ Jan 31 2011, 17:59)

ЯВот протокол обмена с часиками
S D0 A 00 A Sr D1 A 55 A 57 A 17 A 02 A 31 A 01 A 11 N P
А вот с тинкой
S 4C N P
иногда вот так
S 4C N Sr P
и после шаманства вот так
S 4C A 41 N P
Протокол с часиками расшифровыается просто
А вот с тинькой
S- старт
4С- slave - запись
А - ASK
41- данные
а вот теперь ерунда
N-
NO ASK при записи -чушь Надеюсь понятно изложил
P - Stop
AlexTech
Jan 31 2011, 20:07
Да изложили то понятно, я в общем это понимаю кроме Sr, я блин не понимаю почему код фактически из аппнота генерит такой протокол :/
Причем в железе то тинка нормально принимает данные, только часики глушит напрочь
ILYAUL
Jan 31 2011, 20:24
Цитата(AlexTech @ Jan 31 2011, 23:07)

Да изложили то понятно, я в общем это понимаю кроме Sr, я блин не понимаю почему код фактически из аппнота генерит такой протокол :/
Излагаю
Код
S D0 A 00 A Sr D1 A 55 A 57 A 17 A 02 A 31 A 01 A 11 N P
S - старт
D0- Slave адрес часов - запись
А-ASK не проблема
00- установка на регистр секунд
А- выще
Sr - repeat startD1 - Slave чтение
Дальше смысла нет разшифровывать 55 сек 57 мин ............................
N- No ASK
P -STOP/
Вобщем-то правильно, за исключением , что N должен выдаваться перед 11 . Не важно , но просто избавляет от S D0 A 00 A Sr
Короче - при записи НИКОГДА не выдается код N - NO ASK. Slave в Вашем случае , становится в ступор , типа " да на хрен мне мастер прислал , конец приема", когда должен вроде как записывать мне данные
Соответсвенно вся шина тоже в ступоре, хрен его знает что этому мастеру нужно . И часики естествено тоже
ну теперь похоже вообще понятно изложил
AlexTech
Jan 31 2011, 21:17
Вот код мастера для тинки
Код
i2c_start();
i2c_tx_addr( (0x26<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT) );
i2c_tx(0x41);
i2c_stop();
Вот для часиков
Код
i2c_start();
i2c_tx_addr( (0x68<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT) );
i2c_tx(0);
i2c_start();
i2c_tx_addr( (0x68<<TWI_ADR_BITS) | (TRUE<<TWI_READ_BIT) );
rtc_var->seconds = i2c_rx(ACK);
rtc_var->minutes = i2c_rx(ACK);
rtc_var->hours = i2c_rx(ACK);
i2c_rx(ACK);
rtc_var->day = i2c_rx(ACK);
rtc_var->month = i2c_rx(ACK);
rtc_var->year = i2c_rx(NOT_ACK);
i2c_stop();
Вот tx и rx
Код
void i2c_tx(unsigned char byte)
{
if(i2c_error)
return;
i2c_delay();
TWDR = byte;
TWCR = ((1<<TWINT)+(1<<TWEN));
i2c_delay();
if(TWSR != MTX_DATA_ACK)
i2c_error=1;
}
unsigned char i2c_rx(unsigned char last_byte)
{
if(i2c_error)
return 0;
i2c_delay();
if(last_byte)
TWCR = ((1<<TWINT)+(1<<TWEN)+(1<<TWEA));
else
TWCR=((1<<TWINT)|(1<<TWEN));
i2c_delay();
if(((TWSR != MRX_DATA_NACK)&&(last_byte == NOT_ACK))&&(TWSR != MRX_DATA_ACK))
i2c_error=1;
return TWDR;
}
В общем все, убрал по вашей наводке i2c_stop(); из обмена с тинкой.
В протеусе ерунда полная, в железе все работает вроде, почти все...
Без этого стопа, если тинку отключить, то часики перестают читаться тоже
Ну да все равно, Спасибо большое )))
ILYAUL
Jan 31 2011, 21:48
Значит так :
Даже незнаю с чего и начать.
Шина I2C. Есть такие нюансы , которые при работе с этой шиной надо учитывать.
STOP - вот казалось бы чего проще, но нет , если у Вас "тупорылый" slave , да не один, то необходимо отследить , а выполнился ли этот Stop. Чревато - поданая тут же команда START- пипец - шина в ступоре.
Так , что посде Stop , да если ещё TWI программый , ЗАДЕРЖКА перед START
AlexTech
Jan 31 2011, 21:50
То есть i2c_stop(); все же нужен?
Все, оставил и стоп и паузу добавил на 100мс, все заработало как надо )))))
Еще раз спасибо ))))
Сколько мучений из за одной паузы, а все от неопытности...
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.