|
|
  |
Кто нибудь писал имплементацию twi/i2c на usi для слейва? |
|
|
|
Jan 31 2011, 12:00
|
Частый гость
 
Группа: Участник
Сообщений: 83
Регистрация: 2-12-05
Пользователь №: 11 688

|
Нууу... как придумал так и написал  а какие есть варианты? можно там конечно вообще ничего не делать, ну в другом месте тот же код будет... да, есть usart, мега может отправлять данные в комп
Сообщение отредактировал AlexTech - Jan 31 2011, 12:01
|
|
|
|
|
Jan 31 2011, 12:02
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
А 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. }
|
|
|
|
|
Jan 31 2011, 12:29
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
стоп-кондишен обрабатывается в Код while ( (PIN_USI & (1<<PORT_USI_SCL)) & !(tmpUSISR & (1<<USIPF)) ); какая частота у УСИ/ТВИ?
Сообщение отредактировал alexeyv - Jan 31 2011, 12:42
|
|
|
|
|
Jan 31 2011, 14:59
|
Частый гость
 
Группа: Участник
Сообщений: 83
Регистрация: 2-12-05
Пользователь №: 11 688

|
Я думал что вот это: 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); но протеус этого вообще не переваривает (
Сообщение отредактировал AlexTech - Jan 31 2011, 15:09
|
|
|
|
|
Jan 31 2011, 17:43
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Цитата(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
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Jan 31 2011, 20:24
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Цитата(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 в Вашем случае , становится в ступор , типа " да на хрен мне мастер прислал , конец приема", когда должен вроде как записывать мне данные Соответсвенно вся шина тоже в ступоре, хрен его знает что этому мастеру нужно . И часики естествено тоже ну теперь похоже вообще понятно изложил
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Jan 31 2011, 21:17
|
Частый гость
 
Группа: Участник
Сообщений: 83
Регистрация: 2-12-05
Пользователь №: 11 688

|
Вот код мастера для тинки Код 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(); из обмена с тинкой. В протеусе ерунда полная, в железе все работает вроде, почти все... Без этого стопа, если тинку отключить, то часики перестают читаться тоже Ну да все равно, Спасибо большое )))
Сообщение отредактировал AlexTech - Jan 31 2011, 21:48
|
|
|
|
|
Jan 31 2011, 21:48
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Значит так : Даже незнаю с чего и начать. Шина I2C. Есть такие нюансы , которые при работе с этой шиной надо учитывать. STOP - вот казалось бы чего проще, но нет , если у Вас "тупорылый" slave , да не один, то необходимо отследить , а выполнился ли этот Stop. Чревато - поданая тут же команда START- пипец - шина в ступоре. Так , что посде Stop , да если ещё TWI программый , ЗАДЕРЖКА перед START
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|