|
USI типа I2C на Tiny45, просто не работает |
|
|
|
Feb 22 2010, 19:39
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата Не получается прочитать байт от Тини, хоть тресни  А передать байт в тиню? Там же только запись, в моём примере. И это точно работало у меня  А другие устройства на i2c - перестали зависать? Возможно я не всё исправил, тогда надо ждать MTh, он это (неответ) вроде поборол.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Feb 22 2010, 19:52
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Ни привета, ни ответа. В слейве даже по условию Код if( USI_TWI_statusReg.dataInRxBuf ) { PORTB |= (1 << LED); ........ ничего не горит. Со стороны Меги вызываю Код void ReadSensor() { I2c_StartWait(SENSOR_ADDR | W); // slave address, write to sensor I2c_Write(TWI_CMD_MASTER_READ); I2c_RepStart(SENSOR_ADDR | R); // slave address + read bit, read sensor Value = (unsigned long)I2c_Read(I2C_ACK) << 24; Value |= (unsigned long)I2c_Read(I2C_ACK) << 16; Value |= (unsigned long)I2c_Read(I2C_ACK) << 8; Value |= (unsigned long)I2c_Read(I2C_NACK) << 0; I2c_Stop(); }
|
|
|
|
|
Feb 23 2010, 08:41
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Нашел одну ошибку: адрес слейв устройства в тини нужно инициализировать сдвинутым на 1 вправо. Т.е. из Меги передаю адрес 0х10, а в Тини TWI_SlaveAdress = 0x08. После этого начал зажигаться светодиод по условию, "буфер не пуст" и ЖКИ индикатор вроде как работает. "Вроде как" значит, что по включению питания на ЖКИ мусор и зависание, а после ресета по крайней мере проходит процедура инициализации ЖКИ. Но все-равно нет ответа от Тини  . Короче, в топку этот недоинтерфейс USI в режиме I2C. Буду пробовать трехпроводный SPI. Надеюсь, что с ним не будет таких проблем...
|
|
|
|
|
Feb 23 2010, 15:22
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(alux @ Feb 23 2010, 11:41)  Нашел одну ошибку... Разберитесь с адресацией (и с R\W заодно). Обычно предлагается два подхода. 1. Адрес отделяется от признака R\W; адрес - 7 бит. При приёме вы вручную выделяете сташие 7 бит принятого байта (сдвиг на 1 вправо, отбрасываем R\W) - это и будет адрес. При передаче сдвигаете адрес на 1 влево, добавляете R\W, и отправляете байт. Микросхема "пишется" и "читается" по одному и тому же адресу. В AVR312 именно так. Код проверки адреса: Код (( USIDR>>1 ) == TWI_slaveAddress 2. Адрес связан с R\W, микросхема "пишется" по одному адресу, а "читается" по другому; адрес - 8 бит. Обычно из двух этих адресов легко видно, что старшие 7 бит у них одинаковы, а младший бит адреса для "чтения" равен 1, - т.е. это просто R\W, и легко свести обмен к предыдущему подходу. Похоже, именно так у вас master реализован. Согласуйте подход в адресации, и должно завестись...
|
|
|
|
|
Feb 24 2010, 09:28
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(SysRq @ Feb 23 2010, 19:22)  Разберитесь с адресацией (и с R\W заодно). Повторю еще раз. Со стороны Меги : Код #define SENSOR_ADDR 0x10
I2c_StartWait(SENSOR_ADDR | W); // slave address, write to sensor I2c_Write(TWI_CMD_MASTER_READ); I2c_RepStart(SENSOR_ADDR | R); // slave address + read bit, read sensor Со стороны Тини: Код TWI_slaveAddress = 0x08; ............ case USI_SLAVE_CHECK_ADDRESS: if ( ( USIDR == 0 ) || ( ( USIDR >> 1 ) == slaveAddress) ) { if ( USIDR & 0x01 ) { overflowState = USI_SLAVE_SEND_DATA; } else { overflowState = USI_SLAVE_REQUEST_DATA; } SET_USI_TO_SEND_ACK( ); } ....... И где я не прав?
|
|
|
|
|
Feb 25 2010, 13:53
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Попробовал использовать USI (Tiny45) в режиме SPI (Slave). Все нормально запустилось. Отправляю от Тини число, на Меге это число принимаю и вывожу на ЖКИ. Но теперь необходимо поменять устройства ролями: Тини должен быть мастером, а Мега - подчиненным. Соответственно на Тини USCK настроил на выход, а у Меги, соответственно SCK, на вход. Кроме этого на Меге вывод SS настроен на вход и притянут перемычкой на землю. Функция передачи байта от Тини: Код unsigned char send_byte(unsigned char val) { USIDR = val; USISR = (1<<USIOIF); do { USICR = (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC); } while ((USISR & (1<<USIOIF)) == 0); return USIDR; }
void main() { SETBIT(DDRB, USCK); SETBIT(PORTB, USCK); SETBIT(DDRB, DO); CLRBIT(PORTB, DO); CLRBIT(DDRB, DI); SETBIT(PORTB, DI); for(;;) { SendByte(0x11); delay_ms(100); } } На Меге функция инициализации аппаратного SPI: Код // select clock phase negative-going in middle of data SPCR |= (1 << CPOL0); // data is sampled on the trailing (last) edge of SCK. SPI Mode - 3 SPCR |= (1 << CPHA0); // Data order MSB first SPCR &= ~(1 << DORD0); // enable SPI SPCR |= (1 << SPE0); // clear status SPSR = SPSR; SpiTransferComplete = true;
// enable SPI interrupt #ifdef SPI_USEINT SPCR |= (1 << SPIE0); #endif } В результате получаю число 255!!! Пробовал для Тини использовать программный SPI: Код void SendByte(unsigned char Data) { unsigned char BitCount = 8;
do { // Send bit to Slave, MSB first if(Data & 0x80) { SETBIT(PORTB, DO); } else { CLRBIT(PORTB, DO); } // Toggle SCK pin to send current bit CLRBIT(PORTB, USCK); SETBIT(PORTB, USCK); // Get next bit to send Data <<= 1; } while(--BitCount);
} Результат - тот же. В чем может быть проблема? Уже все перепробовал
|
|
|
|
|
Feb 26 2010, 22:57
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(alux @ Feb 24 2010, 12:28)  И где я не прав? Да не красиво как-то -- Цитата(alux @ Feb 25 2010, 16:53)  Код // clear status SPSR = SPSR; Так SPIF не сбросится, он read only. Сброс: Цитата SPIF is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively, the SPIF bit is cleared by first reading the SPI Status Register with SPIF set, then accessing the SPI Data Register (SPDR).
|
|
|
|
|
Feb 27 2010, 14:39
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
SPIF = SPIF; в данном случае ни при чем. Проблема в том, что со стороны Меги MISO и MOSI перепутаны местами... Сбило с толку то, что когда Мега был Мастером, а Тини Слейвом, то все работало. Теперь, ничего не меняя в проводах, изменив только статусы мастера и слейва местами, и, соответственно, бит MSTR => 0 у Меги, MOSI у Меги должен быть входом, а MISO, соответственно, выходом!
PS. А вообще, логично было бы назвать вывод MISO - DI , MOSI - DO у Тини. Чем руководствовались Атмел, не понятно...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|