| Форум РадиоКот https://radiokot.ru/forum/ |
|
| Attiny85 проблема с USI I2C https://radiokot.ru/forum/viewtopic.php?f=57&t=191089 |
Страница 1 из 1 |
| Автор: | bepis666 [ Ср ноя 29, 2023 19:54:01 ] | ||||
| Заголовок сообщения: | Attiny85 проблема с USI I2C | ||||
Прошу помощи в реализации интерфейса I2C на Attiny85 в режиме ведомого. Проблема в следующем: При срабатывании прерывания по переполнению счетчика, в регистре данных USIDR оказывается полученный байт сдвинутый влево. Код тестировал в Proteus. На скриншотах показана ячейка памяти 2F, которой соответствует регистр USIDR. На первом скриншоте отправляется 0x00, в USIDR оказывается 0x01; на втором скриншоте отправляется 0x01, в USIDR - 0x03. Думал проблема в симуляции, но нет. Тестировал в железе - то же самое. Заранее благодарю! Код: Код: // Инициализация I2C интерфейса void i2c_init() { // Настройка интерфейса USI на режим TWI USICR |= (1<<USIWM0); USICR |= (1<<USIWM1); // Настройка интерфейса на источник тактирования USICR &= ~(1<<USICLK); USICR &= ~(1<<USICS0); USICR |= (1<<USICS1); // Выставление пинов интерфейса на вход // SDA DDRB &= ~(1<<0); PORTB &= ~(1<<0); // SCL DDRB &= ~(1<<2); PORTB &= ~(1<<2); // Включение прерывания по старту и очистка флага прерывания USICR |= (1<<USISIE); USISR |= (1<<USISIF); } // Прерывание по старту ISR(USI_START_vect){ while( (PINB & (1 << PIN_SCL)) && (!(PINB & (1 << PIN_SDA))) ); // Очистка регистра статуса USISR |= (1<<USISIF); // Включение прерывания по переполнению USICR |= (1<<USIOIE); } // Прерывание по переполнению счетчика ISR(USI_OVF_vect){ uint8_t i2c_byte = USIDR; *pwm_0 = 0; if (i2c_byte>=1){ *pwm_0 = 250; } if (i2c_byte==1){ *pwm_0 = 100; } USISR |= (1<<USIOIF); // Сброс флага прерывания по переполнению USISR = 0; // Сброс счетчика } Добавлено after 5 hours 27 minutes 30 seconds: Еще заметил, что после отправки байта, регистр 2E находится в значении 0100 0010, что соответствует значению счетчика 2 и выставленному флагу срабатывания прерывания по переполнению. Такое ощущение, что в регистр USIDR попадает бит NACK, который по сути и не должен генерироваться, т.к. USIWM выставлены в 11, что значит что после срабатывания прерывания по переполнению линия SCL притягивается к нулю и в счетчик и регистр USIDR ничего писаться не должно...
|
|||||
| Автор: | Игорь_396 [ Ср ноя 29, 2023 23:17:49 ] |
| Заголовок сообщения: | Re: Attiny85 проблема с USI I2C |
В Си не разбираюсь, только начал литературу читать по нему.. В прерывании по старту заинтересовала конструкция "while( (PINB & (1 << PIN_SCL)) && (!(PINB & (1 << PIN_SDA))) );" Так понимаю, это ожидание нужных уровней на пинах? Если не ждать, а сразу писать в регистры и на выход? И еще, вспомнил.. С принудительным удержанием scl у меня какие-то непонятки были, сейчас биты USIWM1 = 1 и USIWM0 = 0, так все работает. |
|
| Автор: | bepis666 [ Сб дек 02, 2023 14:20:12 ] |
| Заголовок сообщения: | Re: Attiny85 проблема с USI I2C |
В Си не разбираюсь, только начал литературу читать по нему.. В прерывании по старту заинтересовала конструкция "while( (PINB & (1 << PIN_SCL)) && (!(PINB & (1 << PIN_SDA))) );" Так понимаю, это ожидание нужных уровней на пинах? Если не ждать, а сразу писать в регистры и на выход? И еще, вспомнил.. С принудительным удержанием scl у меня какие-то непонятки были, сейчас биты USIWM1 = 1 и USIWM0 = 0, так все работает. Попробовал, результат тот же |
|
| Автор: | Игорь_396 [ Вс дек 03, 2023 06:34:55 ] |
| Заголовок сообщения: | Re: Attiny85 проблема с USI I2C |
А в роли мастера что? Можешь хекс слейва кинуть? Прогоню в отладчике с анализатором, гляну что к чему.. |
|
| Автор: | bepis666 [ Вс дек 03, 2023 18:45:17 ] | ||
| Заголовок сообщения: | Re: Attiny85 проблема с USI I2C | ||
А в роли мастера что? Можешь хекс слейва кинуть? Прогоню в отладчике с анализатором, гляну что к чему.. Прикрепил хекс Немного изменил код что бы понимать что происходит при выполнении в железе. В зависимости от полученного байта будет изменяться скважность ШИМ на ноге PB1 Код: // Прерывание по старту ISR(USI_START_vect){ i2c_flag = 1; // Очистка регистра статуса USISR |= (1<<USISIF); // Включение прерывания по переполнению USICR |= (1<<USIOIE); USISR = 0; } // Прерывание по переполнению счетчика ISR(USI_OVF_vect){ uint8_t i2c_byte = USIDR; // Сверка адреса устройства с адресом во фрейме if (i2c_flag==1) { if (i2c_byte>1){ *pwm_0 = 250; } if (i2c_byte==0){ *pwm_0 = 128; } } USISR |= (1<<USIOIF); // Сброс флага прерывания по переполнению USISR = 0; // Сброс счетчика }
|
|||
| Автор: | Игорь_396 [ Сб дек 09, 2023 20:32:28 ] | ||||
| Заголовок сообщения: | Re: Attiny85 проблема с USI I2C | ||||
Только что добрался до отладчика. Пробуй читать USIBR. . Прилагаю два скрина, адрес посылал 0x82. (0х41+W). ЗЫ: Биты USICS в твоем хексе инициализируются USICS1=1 USICS0=1, надо USICS0=0. Тогда можно читать USIDR первой командой при входе в прерывание и там будет актуальное значение. Добавил скрин инициализации USICR.. Жесть жестяная ))) Может спецы подскажут ТС, как правильно на С написать? USICR = 1<<USISE|1<<USIWM1|1<<USIWM0|1<<USICS1 ; так наверное компактнее будет..
|
|||||
| Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|


