Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: MCP3208 + mega1284
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
athlon64
Процессор ATmega 1284P, напряжение питания 3.3В, кварц на 12.8 МГц. MCP3208 подключена через 2 оптопары ADUM1200.
Раз в милисекунду инициируется чтение из АЦП аппаратным SPI. Частота работы SPI = 800 КГц
Проблема в том что устройство зависает в произвольные моменты времени, бывает через минуту после включения, бывает через 20.
При выключенном SPI зависаний не наблюдается.

Инициализация SPI:
Код
  SPCR = BIT(SPE) | BIT(SPIE) | BIT(MSTR) | BIT(SPR0);                //16 // 800 КГц


Старт чтения (в обработчике прервания таймера, раз в 1 мсек):
Код
  Buf2SPI[1] = (ChanSPI1<<6);
  PORTB &= ~BIT(SS);        // Выставить /CS1.
  if (ChanSPI1 & BIT(2))     // START и первый байт выдаем.
    SPDR=0x05;
  else
    SPDR=0x04;
  PtrByteSPI=0;


Обработчик прерывания от SPI:
Код
  #pragma vector=SPI_STC_vect
__interrupt void IRQ_SPI()
{
  unsigned int val;
  char i;

  BufFromSPI[PtrByteSPI++] = SPDR;        // Пришло.
  
  if (PtrByteSPI < 3)    // Принят/послан не последний байт. 0,1,2
    SPDR = Buf2SPI[PtrByteSPI];        // передаем.
  else                                // Принят/послан последний байт.
  {
    PORTB &= ~BIT(MOSI);        // Снять MOSI.
    PORTB |= BIT(SS);    // Снять /CS.

    val = BufFromSPI[2] + ((BufFromSPI[1]&0x0F)<<8);
    SumBuf_SPI_ADC[(ChanSPI1&0x07)>>1] += val;

    ChanSPI1 += 2;
    
    if (ChanSPI1 == 0x80) // 16 раз по 4 каналов прошли.
    {
      for (i=0; i<4; i++) // осреднение.
      {
        Buf2Kan[i] = SumBuf_SPI_ADC[i]>>6; // для 10 бит АЦП
        SumBuf_SPI_ADC[i] = 0;
      }
      ChanSPI1 = 0;
    }
  }
}


Данные из АЦП принимаются правильные.
Прбовал снижать частоту SPI до 200 КГц - не помогает
evg123
Наш директор в таких случ. говорит - "проблема может быть в чём угодно". Надо пытаться её локализовать. Например, оставить SPI-прерывание, но закоментировать весь код внутри. А какой нибудь пустой ногой - моргать светодиодом. Если проц зависнет - значит причина не в АЦП. Если не зависнет - значит в АЦП. Пусть, теперь оказалось, что проц. завис - тогда вообще исключить прерывание от SPI и попробовать ещё раз. И т.д. пока не добъётесь устойчивой работы. Потом идите назад от устойчивой работы к исходному коду. Рассуждениями ошибку найти невозможно, надо пробовать, высказывать предположения и проверять их.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.