roboforum.ru

Технический форум по робототехнике.

 

I2C - помогите кто знает...

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

I2C - помогите кто знает...

Сообщение -= Александр =- » 19 авг 2005, 04:50

в общем дело вот в чем: как работать со всякими EEPROMами по I2C ясно. Но вот приспичило мне повесить туда-же еще один вспомогательный контроллер - как мне его сделать слейвом?
Аватара пользователя
-= Александр =-
Мастер Самоделкин
 
Сообщения: 3664
Зарегистрирован: 11 окт 2004, 19:20
Откуда: Россия, СПб
прог. языки: C++, VB, asm
ФИО: Курмис Александр Андреевич

Сообщение ASin » 19 авг 2005, 14:11

Запрограммировать как слейва и прицепить к шине. А что за контроллер?
ASin
 
Сообщения: 155
Зарегистрирован: 18 дек 2004, 03:14
Откуда: Москва

Сообщение testers » 20 авг 2005, 21:33

встречный вопрос: помогите чайнику в и2к, вообще, как :shock:
Аватара пользователя
testers
 
Сообщения: 97
Зарегистрирован: 27 июл 2005, 19:29
Откуда: Москва

Сообщение -= Александр =- » 22 авг 2005, 01:24

Кстати все ли I2Cшные контроллеры умеют быть слэйвами?
Аватара пользователя
-= Александр =-
Мастер Самоделкин
 
Сообщения: 3664
Зарегистрирован: 11 окт 2004, 19:20
Откуда: Россия, СПб
прог. языки: C++, VB, asm
ФИО: Курмис Александр Андреевич

Сообщение ASin » 22 авг 2005, 17:15

AFAIK да.
ASin
 
Сообщения: 155
Зарегистрирован: 18 дек 2004, 03:14
Откуда: Москва

Сообщение NeoLP » 23 авг 2005, 08:00

конечно не все, хотя у AVRов все хорошо получается, я, например, связывал большой ARM и маленькую Maga8 и мега работает слэйвом
Аватара пользователя
NeoLP
 
Сообщения: 62
Зарегистрирован: 01 авг 2005, 12:44
Откуда: Novosibirsk

Сообщение -= Александр =- » 23 авг 2005, 16:16

Сорри за оффтоп, но давно пытаюсь понять: через что прошиваются атмеловские ARMы?

А по поводу Меги - можно кусок кода про инициализацию и обмен глянуть. Инициализацию мастером-то я уже откуда-то вытащил...
Аватара пользователя
-= Александр =-
Мастер Самоделкин
 
Сообщения: 3664
Зарегистрирован: 11 окт 2004, 19:20
Откуда: Россия, СПб
прог. языки: C++, VB, asm
ФИО: Курмис Александр Андреевич

Сообщение slava » 23 авг 2005, 16:38

slava
 
Сообщения: 188
Зарегистрирован: 12 апр 2005, 11:47
Откуда: Москва

Сообщение NeoLP » 24 авг 2005, 06:01

Хорошо, вот инициализация (прошу прощения за стиль)

Код: Выделить всёРазвернуть
#define I2CAVRADDR 0x34
#define i2cFreq 100000
#define twps 0 // 0,1,2,3
#define twpsexp 1 // 1,4,16,64
char i2cinit()
   {
   DDRC=(DDRD & ~0x30); // sda and scl are input
   PORTC=(PORTD&~0x30);   // pullup off

   TWBR=((WorkFreq/i2cFreq-16)/2)/twpsexp;
   TWCR=(1<<TWIE)|(1<<TWEN)|(1<<TWEA);
   TWSR=twps;
      
   TWAR=(I2CAVRADDR<<1)|1;
   return 0;
   }


А вот это обработчик прерывания от I2C

Код: Выделить всёРазвернуть
#define eeprom ((volatile __eeprom char*)0)

char dtcnt;
unsigned short address_;
unsigned short tmpbuf;
char data[16];
#pragma vector=TWI_vect
__interrupt void TWIint()
 {
   switch (TWSR&0xF8)
      {
   // slave receiver mode
      case 0x60: // slave address has been received
      case 0x68: // slave address has been received after arbitration lost
      case 0x70: // general call address has been received
      case 0x78: // general call address has been received after arbitration lost
         TWCR=(1<<TWIE)|(1<<TWEN)|(1<<TWINT)|(1<<TWEA); // wait for data
         dtcnt=0;
         break;
      case 0x80: // Previously addressed with own SLA+W; data has been received; ACK has been returned
      case 0x90: // Previously addressed with general call; data has been received; ACK has been returned
         if (dtcnt==0) { address_=TWDR; dtcnt++; }
         else if (dtcnt==1) { address_=(address_<<8) | TWDR; dtcnt++; }
         else
            {
            char d=TWDR;
            if (address_==2)                  { start_key_pressed=d; }
            else if (address_==3)            { key_pressed=d; }
            else if (address_==20)         { sndfrq=d; sndvol=0; }
            else if (address_==21)         { sndvol=d; }
            else if (address_<32)         { ; }
            else if (address_<32+16)   { data[address_-32]=d; }
            else if (address_<512)      { eeprom[address_]=d; }
            else                                  { ; }

            if (address_==20)      { UpdSound(); }
            else if (address_==21)      { UpdSound(); }
            address_++;
            }
         TWCR=(1<<TWIE)|(1<<TWEN)|(1<<TWINT)|(1<<TWEA); // wait for data
         break;
      case 0x88: // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned
      case 0x98: // Previously addressed with general call; data has been received; NOT ACK has been returned
      case 0xA0: // A STOP condition or repeated START condition has been received while still addressed as slave
         TWCR=(1<<TWIE)|(1<<TWEN)|(1<<TWINT)|(1<<TWEA); // wait for new address
         break;
   // slave transmitter mode
      case 0xA8: // Own SLA+R has been received; ACK has been returned
      case 0xB0: // Arbitration lost in SLA+R/W as master; own SLA+R has been received; ACK has been returned
      case 0xB8: // Data byte in TWDR has been transmitted; ACK has been received
         {
         char d=0x5A;
         if (address_==0)                  { d=1; } // bios ID
         else if (address_==1)            { d=2; } // bios ver
         else if (address_==2)            { d=start_key_pressed; }
         else if (address_<32)            { d=0xA5; } // reserved
         else if (address_<32+16)      { d=data[address_-32]; }
         else if (address_<512)         { d=eeprom[address_]; } // eeprom except first 32 bytes
         else                                     { d=0x5A; }
         TWDR=d;
         address_++;
         }
         TWCR=(1<<TWIE)|(1<<TWEN)|(1<<TWINT)|(1<<TWEA); // not last byte will be transmitted
//         TWCR=(1<<TWIE)|(1<<TWEN)|(1<<TWINT); // last byte will be transmitted
         break;
      case 0xC0: // Data byte in TWDR has been transmitted; NOT ACK has been received
      case 0xC8: // Last data byte in TWDR has been transmitted (TWEA = ?0?); ACK has been received
         TWCR=(1<<TWIE)|(1<<TWEN)|(1<<TWINT)|(1<<TWEA); // Switched to the not addressed slave mode own SLA will be recognized;
         break;
      // miscellanenous states
      case 0x00: // Bus error due to an illegal START or STOP condition
         TWCR=(1<<TWIE)|(1<<TWEN)|(1<<TWINT)|(1<<TWEA)|(1<<TWSTO); // send a normal stop
         break;
      case 0xF8: // No relevant state information available; TWINT = ?0?
         break; // do nothing
      }
 }


Там, конечно, немного лигики осталось за бортом, но, в целом, это хорошо работает.
Аватара пользователя
NeoLP
 
Сообщения: 62
Зарегистрирован: 01 авг 2005, 12:44
Откуда: Novosibirsk

Сообщение NeoLP » 24 авг 2005, 06:04

А по поводу прошивки арма... я использую AT91RM9200, так у него есть ром в который зашит загрузчик из внешней флешки и загрузчик по последовательному порту, так что, просто подключаю к COM1 и заливаю... А все эти JTAGи, дорого, а толку мало...
Аватара пользователя
NeoLP
 
Сообщения: 62
Зарегистрирован: 01 авг 2005, 12:44
Откуда: Novosibirsk


Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Mail.ru counter