Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ловля ASK по шине I2C
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
QuickWitted
До этого с шиной I2c я работал на АТ89С51 и на софте....
А тут потребовалось управлять ГОТОВЫМ девайсом (SAT тюнер)
по шине I2c вместо штатно стоявшего там проца поставил ATMega48...

Для упрощения задачи разбил её на ряд мелких и решил сначала
немного по управлять флэшкой AT24C16...

Перерыл весь интернет, нашёл несколько исходников на АСМ, и
собрал из них нечто среднее Нажмите для просмотра прикрепленного файла

Одно но во всех найденных исходниках контроль ответа АСК
от девайса был "закрыт" точкой с запятой...

Одним словом исходник работает, но не контролирует ACK...

Не подскажет ли доброуважаемый АЛЛ как прикрутить контроль?
(что я делаю не так?)
KRS
IMHO этот пример лучше не использовать.
1. лучше все переписать на С
2. использовать не константы типа 0x18 а символическое имя ( вроде twiSLA_W_ACK)
3. В примере не все состояния проверяются, например после комнады установки START кондишн, я не увидел проверки флагов ( должно быть старт или повторный старт).
4. Проверка там заокментирована потому что при посылке адреса устройства вызывается функция I2C_SEND_Byte, которая не корректно проверяет статус. Статусы после послыки адрес+чтение, адрес+запись и просто данные, надо проверять разные...

Лучше всего взять даташит на авр и там в описании twi есть замечательная таблица Status Codes for Master Transmitter Mode и там все написано что нужно делать приложению и что будет делать twi...
И примеры есть на С и асм
QuickWitted
Цитата(KRS @ Apr 3 2008, 11:55) *
Статусы после послыки адрес+чтение, адрес+запись и просто данные, надо проверять разные...


У тебя случаем готового примера этих проверок нету?
(датащит я прочту, но с готовым примером понятнее...
в енетовских исходниках [смотрел более 10] с проверками туго...)
KRS
откопал старый свой исходник
но тут функции под другие устройства заточены, но все макросы можно использовать.

Код
#define WaitTWI() while (!(TWCR & (1<<TWINT)))
#define TWIStatus() (TWSR & 0xF8)

#define twiSTART 0x08
#define twiRSTART 0x10
#define twiSLA_W_ACK 0x18
#define twiSLA_W_NAK 0x20
#define twiSLA_R_ACK 0x40
#define twiDATA_W_ACK 0x28
#define twiDATA_R_ACK 0x50
#define twiDATA_R_NAK 0x58

#define twiSET_START() TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWSTO)|(1<<TWEN)
#define twiSET_RSTART() TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
#define twiSET_STOP()  TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
#define twiSEND_DATA(DatByte)  TWDR=DatByte; TWCR = (1<<TWINT)|(1<<TWEN)
#define twiREQUEST_DATA() TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA)
#define twiREQUEST_DATA_NA() TWCR=(1<<TWINT)|(1<<TWEN)

BYTE twiWriteByte(BYTE SlaveAddr, BYTE Reg, BYTE Data);
BYTE twiWriteWord(BYTE SlaveAddr, BYTE Reg, WORD Data);
WORD twiReadByte(BYTE SlaveAddr, BYTE Reg);
WORD twiReadByte1(BYTE SlaveAddr);
DWORD twiReadWord1(BYTE SlaveAddr);
DWORD twiReadWord(BYTE SlaveAddr, BYTE Reg);
BYTE twiWriteByte1(BYTE SlaveAddr, BYTE Data);
BYTE twiWriteCfg(BYTE SlaveAddr, BYTE Reg, BYTE Len, const BYTE __flash* Data);

#define twiWriteAddr(SlaveAddr,FailLabel) {\
    BYTE Ack;\
    twiSET_START();\
    WaitTWI();\
    Ack=TWIStatus();\
    if ( !((Ack==twiSTART) || (Ack==twiRSTART)) ) goto FailLabel;\
    twiSEND_DATA(SlaveAddr);\
    Ack=twiSLA_W_ACK;\
    if ((SlaveAddr) & 1) Ack=twiSLA_R_ACK;\
    WaitTWI();\
    if (TWIStatus()!=Ack) goto FailLabel;\
}\

#define twiWriteData(Data,FailLabel) {\
    twiSEND_DATA(Data);\
    WaitTWI();\
    if (TWIStatus()!=twiDATA_W_ACK) goto FailLabel;\
}\

#define twiReadDataNa(Res,FailLabel) {\
    BYTE Ack;\
    twiREQUEST_DATA_NA();\
    WaitTWI();\
    Ack=TWIStatus();\
    Res=TWDR;\
    if (Ack!=twiDATA_R_NAK) goto FailLabel;\
}

#define twiReadData(Res,FailLabel) {\
    BYTE Ack;\
    twiREQUEST_DATA();\
    WaitTWI();\
    Ack=TWIStatus();\
    Res=TWDR;\
    if (Ack!=twiDATA_R_ACK) goto FailLabel;\
}


WORD twiReadByte(BYTE SlaveAddr, BYTE Reg)
{
    BYTE Res;
    twiWriteAddr(SlaveAddr,Fail);
    twiWriteData(Reg,Fail);
    twiWriteAddr(SlaveAddr|1,Fail);
    twiReadDataNa(Res,Fail);
    twiSET_STOP();
    return Res;
Fail:
    twiSET_STOP();
    return 0xFFFF;    
}

WORD twiReadByte1(BYTE SlaveAddr)
{
    BYTE Res;
    twiWriteAddr(SlaveAddr|1,Fail);
    twiReadData(Res,Fail);
    twiSET_STOP();
    return Res;
Fail:
    twiSET_STOP();
    return 0xFFFF;  
}

DWORD twiReadWord1(BYTE SlaveAddr)
{
    BYTE Res1,Res2;
    twiWriteAddr(SlaveAddr|1,Fail);
    twiReadData(Res1,Fail);
    twiReadData(Res2,Fail);
    twiSET_STOP();
    return (WORD)(Res2 | (Res1<<8));
Fail:
    twiSET_STOP();
    return 0xFFFFFFFF;  
}

BYTE twiWriteByte1(BYTE SlaveAddr, BYTE Data)
{
    twiWriteAddr(SlaveAddr,Fail);
    twiWriteData(Data,Fail);
    twiSET_STOP();
    return 1;
Fail:
    twiSET_STOP();
    return 0;    
}

DWORD twiReadWord(BYTE SlaveAddr, BYTE Reg)
{
    BYTE Res1,Res2;
    twiWriteAddr(SlaveAddr,Fail);
    twiWriteData(Reg,Fail);
    twiWriteAddr(SlaveAddr|1,Fail);
    twiReadData(Res1,Fail);
    twiReadDataNa(Res2,Fail);
    twiSET_STOP();
    return (WORD)(Res1 | (Res2<<8));
Fail:
    twiSET_STOP();
    return 0xFFFFFFFF;    
}

BYTE twiWriteByte(BYTE SlaveAddr, BYTE Reg, BYTE Data)
{
    twiWriteAddr(SlaveAddr,Fail);
    twiWriteData(Reg,Fail);
    twiWriteData(Data,Fail);
    twiSET_STOP();
    return 1;
Fail:
    twiSET_STOP();
    return 0;    
}

BYTE twiWriteWord(BYTE SlaveAddr, BYTE Reg, WORD Data)
{
    twiWriteAddr(SlaveAddr,Fail);
    twiWriteData(Reg,Fail);
    twiWriteData(Data,Fail);
    twiWriteData((BYTE)(Data>>8),Fail);
    twiSET_STOP();
    return 1;
Fail:
    twiSET_STOP();
    return 0;    
}

BYTE twiWriteCfg(BYTE SlaveAddr, BYTE Reg, BYTE Len, const BYTE __flash* Data)
{
    twiWriteAddr(SlaveAddr,Fail);
    twiWriteData(Reg,Fail);
    do {
      twiWriteData(*Data++,Fail);
    } while(--Len);
    twiSET_STOP();
    return 1;
Fail:
    twiSET_STOP();
    return 0;    
}
QuickWitted
Цитата(KRS @ Apr 3 2008, 11:55) *
IMHO этот пример лучше не использовать.
1. лучше все переписать на С


Я не работаю на С sad.gif

Цитата(KRS @ Apr 3 2008, 11:55) *
3. В примере не все состояния проверяются, например после комнады установки START кондишн, я не увидел проверки флагов ( должно быть старт или повторный старт).


Немогли бы вы разяснить что именно проверять? 05.gif

А за исходник на С спасибо...
вставил проверки... работает... wink.gif
Нажмите для просмотра прикрепленного файла
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.