реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> twi(i2c)-интерфейс, обеспечение надежности передачи
singlskv
сообщение Nov 23 2007, 20:19
Сообщение #16


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(namelos @ Nov 23 2007, 22:34) *
Контроллер не зависает, он из состояния interrupt не выходит, а точнее выходит, но TWIE не обнуляет.

Покажите полный код работы с i2c на мастере.

ИМХО, в ситуациях обрыва/коротыша на линиях i2c, иногда без таймаутов не
обойтись...
Это касается только мастера...
Слейву пофиг на обрыва/коротыш если обработаны все состояния внутреннего i2c автомата...
Go to the top of the page
 
+Quote Post
namelos
сообщение Nov 23 2007, 20:30
Сообщение #17


Частый гость
**

Группа: Свой
Сообщений: 77
Регистрация: 4-08-06
Пользователь №: 19 324



Код

ISR (TWI_vect)
{
    static uint8_t twi_ptr_Buf;
    switch (TWSR)
      {
        // START or Repeated START has been transmitted
        case TW_START:  case TW_REP_START:       
            twi_ptr_Buf= 0;                     // Set buffer pointer to the TWI Address location
        
        // SLA+W or Data byte has been tramsmitted and ACK received
        case TW_MT_SLA_ACK: case TW_MT_DATA_ACK:      
            
            if (twi_ptr_Buf < twi_msgSize)
          {
                TWDR = twi_Buf[twi_ptr_Buf++];
                TWCR = (1<<TWEN)|                      // TWI Interface enabled
               (1<<TWIE)|(1<<TWINT)|               // Enable TWI Interupt and clear the flag to send byte
               (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|    //
               (0<<TWWC);
                      //  
          }
            else                    // Send STOP after last byte
          {
                twi_statusReg.lastTransmitOK = TRUE;   // Set status bits to completed successfully.
                TWCR = (1<<TWEN)|                        // TWI Interface enabled
               (0<<TWIE)|(1<<TWINT)|                  // Disable TWI Interrupt and clear TWINT the flag
               (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)|    // Initiate a STOP condition.
               (0<<TWWC);                            
          }
      break;
        
        // Data byte has been received and ACK tramsmitted
        case TW_MR_DATA_ACK:      
          twi_Buf[twi_ptr_Buf++] = TWDR;
            // SLA+R has been tramsmitted and ACK received
            case TW_MR_SLA_ACK:      
      
            if (twi_ptr_Buf <(uint8_t) (twi_msgSize-1) )            // Detect the before last byte to NACK it.!!!!
          {
                TWCR = (1<<TWEN)|                             // TWI Interface enabled
               (1<<TWIE)|(1<<TWINT)|                      // Enable TWI Interupt and clear the flag to read next byte
               (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|           // Send ACK after reception
               (0<<TWWC);
                                                  
          }
            //Send NACK after next reception
            else                    
          {
                TWCR = (1<<TWEN)|                                 // TWI Interface enabled
               (1<<TWIE)|(1<<TWINT)|                      // Enable TWI Interupt and clear the flag to read next byte
               (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|           // Send NACK after reception
               (0<<TWWC);
                    
                                 //
          }    
          break;
        
        case TW_MR_DATA_NACK:     // Data byte has been received and NACK transmitted
          
            twi_Buf[twi_ptr_Buf] = TWDR;                    //here will be last byte saved
          twi_statusReg.lastReceiveOK = TRUE;          // Set status bits to completed successfully.
      
            TWCR = (1<<TWEN)|                          // TWI Interface enabled
             (0<<TWIE)|(1<<TWINT)|                  // Disable TWI Interrupt and clear the flag
             (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)|       // Initiate a STOP condition. TWSTO reset
             (0<<TWWC);
        
            __asm__ volatile("nop");
            __asm__ volatile("nop");

            TWCR = (1<<TWEN)|                          // TWI Interface enabled
             (0<<TWIE)|(0<<TWINT)|                  // Disable TWI Interrupt and clear the flag
             (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|       // Initiate a STOP condition. TWSTO reset
             (0<<TWWC);
                                    //
      break;      
        
        case TW_MR_ARB_LOST:          // Arbitration lost
      TWCR = (1<<TWEN)|                                 // TWI Interface enabled
             (1<<TWIE)|(1<<TWINT)|                      // Enable TWI Interupt and clear the flag
             (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)|           // Initiate a (RE)START condition.
             (0<<TWWC);
                                            //
      break;

        case TW_MT_SLA_NACK:      // SLA+W has been tramsmitted and NACK received
            case TW_MR_SLA_NACK:      // SLA+R has been tramsmitted and NACK received    
                case TW_MT_DATA_NACK:     // Data byte has been tramsmitted and NACK received
                        case TW_NO_INFO:          // No relevant state information available; TWINT = ”0”
                            case TW_BUS_ERROR:        // Bus error due to an illegal START or STOP condition
                                default:    
                            
                                twi_state = TWSR;      // Store TWSR and automatically sets clears noErrors bit.
                                                     // Reset TWI Interface
                          TWCR = (1<<TWEN)|                  // Enable TWI-interface and release TWI pins
                         (0<<TWIE)|(1<<TWINT)|              // Disable Interupt
                         (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)|   // No Signal requests
                         (0<<TWWC);

                    //delay 100µs
                        _delay_ms (0.1);//100
                            TWCR = (1<<TWEN)|                          // TWI Interface enabled
                     (0<<TWIE)|(0<<TWINT)|                  // Disable TWI Interrupt and clear the flag
                     (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|       // Initiate a STOP condition. TWSTO reset
                     (0<<TWWC);
    }                      

}
инt main(void)
{
for(;;)
{

    if( !(TWCR & _BV(TWIE)) )
    {
            //Check if the last opeation was OK
        if(twi_statusReg.lastReceiveOK) // Last transmission competed successfully.
            twi_get_data_message ( );        
    
        twi_start_data_transceiver( ...);
    }        
}

}


добавил 2 нопа, стал обнуляться TWIE. Потом перестал обнуляться TWIE после ERROR- добавил delay. А сейчас повисает slave, он держит SCL на нуле. Разбираюсь пока. Всем спасибо большое за интерес к моей теме.

Сообщение отредактировал namelos - Nov 23 2007, 20:34
Go to the top of the page
 
+Quote Post
bodja74
сообщение Nov 23 2007, 20:33
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Цитата(namelos @ Nov 23 2007, 22:34) *
несовсем понятно...начало transreceive пакета реализуется только в случае недействительного TWI Interrupt (TWIE =0)

Не путайте TWIE с TWINT smile.gif
В момент записи TWINT=1 ,TWINT сбрасываетя в 0 ,и дожидаемся на нем 1 как завершение выполнения команды или можем перейти на прерывание.
Цитата
Контроллер не зависает, он из состояния interrupt не выходит, а точнее выходит, но TWIE не обнуляет.

Ну прям сказки smile.gif
(0<<TWIE) и при этом ,постоянно залетает в прерывание smile.gif,скорее всего эта команда и не обрабатывается .
Go to the top of the page
 
+Quote Post
namelos
сообщение Nov 23 2007, 20:38
Сообщение #19


Частый гость
**

Группа: Свой
Сообщений: 77
Регистрация: 4-08-06
Пользователь №: 19 324



Цитата(bodja74 @ Nov 24 2007, 00:33) *
Не путайте TWIE с TWINT smile.gif
В момент записи TWINT=1 ,TWINT сбрасываетя в 0 ,и дожидаемся на нем 1 как завершение выполнения команды или можем перейти на прерывание.

Код с atmelskого сайта АN315, кстати я как раз их и не путую. С помощью TWIE я контролирую конец передачи пакета.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Nov 23 2007, 20:46
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Цитата(namelos @ Nov 23 2007, 23:38) *
Код с atmelskого сайта АN315, кстати я как раз их и не путую. С помощью TWIE я контролирую конец передачи пакета.


Ваууу!
По TWIE вы контролируете конец передачи пакета или конец выполнения команды smile.gif
Go to the top of the page
 
+Quote Post
namelos
сообщение Nov 23 2007, 20:52
Сообщение #21


Частый гость
**

Группа: Свой
Сообщений: 77
Регистрация: 4-08-06
Пользователь №: 19 324



Повторюсь, пакета данных. Если вы посмотрите на Interrupt рутину, там TWIE обнуляется при ошибке, послан весь пакет и TW_MR_DATA_NACK, что означает конец приема пакета.

Сообщение отредактировал namelos - Nov 23 2007, 20:57
Go to the top of the page
 
+Quote Post
bodja74
сообщение Nov 23 2007, 21:16
Сообщение #22


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Все ,что может быть понято неправильно ,понимается неправильно. :D

Цитата(namelos @ Nov 23 2007, 22:34) *
несовсем понятно...начало transreceive пакета реализуется только в случае недействительного TWI Interrupt (TWIE =0)
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 00:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01437 секунд с 7
ELECTRONIX ©2004-2016