Перейти к содержанию
    

ADuC7021: ADC и SPI

есть ADuC7021 (ARM7TDMI).

 

у него работает АЦП

то что он напреобразовывал должно отдаваться по SPI.

 

На вход подаётся тестовый периодический сигнал (период ~20 мс).

если он то что напреобразовывал отдаёт по UART, то вроде всё нормально

 

если же включаем SPI (UART продолжает работать - собственно через него я и веду "лог" работы программы), то в оцифрованном сигнале вижу "зарубки" (нулевое значение) через каждые ~2мс. причем периодичность этих "зарубов" не зависит от скорости обмена по SPI (брались скорости и 250кГц и 1 МГц и 4МГц)

 

канал АЦП - ADC0

 

интересно также, что в обратном направлении (Ц-А пробразование буфера принятого по SPI, периодическое) - происходит без косяков - то есть работа SPI каким то макаром отражается на АЦП и никак на ЦАП.

 

может кто нибудь наведет, почему может происходить подобное?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есть ADuC7021 (ARM7TDMI).

 

у него работает АЦП

то что он напреобразовывал должно отдаваться по SPI.

 

На вход подаётся тестовый периодический сигнал (период ~20 мс).

если он то что напреобразовывал отдаёт по UART, то вроде всё нормально

 

если же включаем SPI (UART продолжает работать - собственно через него я и веду "лог" работы программы), то в оцифрованном сигнале вижу "зарубки" (нулевое значение) через каждые ~2мс. причем периодичность этих "зарубов" не зависит от скорости обмена по SPI (брались скорости и 250кГц и 1 МГц и 4МГц)

 

канал АЦП - ADC0

 

интересно также, что в обратном направлении (Ц-А пробразование буфера принятого по SPI, периодическое) - происходит без косяков - то есть работа SPI каким то макаром отражается на АЦП и никак на ЦАП.

 

может кто нибудь наведет, почему может происходить подобное?

 

 

А у вас АЦП в непрерывном режиме преобразования?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

АЦП запускается по таймеру0 каждые 125 микросекунд

 

Табл. 7. Назначение разрядов регистра ADCCON.

Разряд Описание

 

7 Разрешить преобразование. Устанавливается пользователем с целью разрешить

режим преобразования

Сбрасывается пользователем с целью отменить

режим преобразования

6 Разрешает работу вывода ADCBUSY Устанавливается пользователем с целью разрешить

работу вывода ADCBUSY

Сбрасывается пользователем с целью отменить

работу вывода ADCBUSY

5 Управление питанием АЦП: Устанавливается пользователем с целью перевести

АЦП в нормальный режим работы;

АЦП должен быть включен за время не менее 500 мкс

до момента, когда он будет работать корректно

Сбрасывается пользователем с целью перевести АЦП

в режим малого энергопотребления

4-3 Режим преобразования: 00 Однополярный вход

01 Дифференциальный вход

10 Псевдодифференциальный вход

11 Зарезервировано

2-0 Тип преобразования: 000 Разрешить преобразование по сигналу на

входе CONVSTART

001 Разрешить преобразование по сигналу от

таймера 1

010 Разрешить преобразование по сигналу от

таймера 0

011 Однократное преобразование с управлением

от программы, после

преобразования биты сбрасываются в состояние

000

100 Непрерывное преобразование с управлением

от программы

101 Преобразование по сигналу с выхода PLA

Остальные сочетания зарезервированы

 

Попробуйте перевести в режим непрерывного преобразования и/или уточните настройку режимов работы АЦП

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

сейчас вот так:

10010100010

 

fADC/2

ADC aquisition time - 2clocks

Enable start conversion

ADCBUSY disabled

ADC power up

Single ended

Conversion on Timer0

 

...

не могли бы в пояснить как работает АЦП в этом режиме

"100 Непрерывное преобразование с управлением от программы"

 

т.е. от чего запускается? автоматически после окончания предыдущего преобразования?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

сейчас вот так:

10010100010

 

fADC/2

ADC aquisition time - 2clocks

Enable start conversion

ADCBUSY disabled

ADC power up

Single ended

Conversion on Timer0

 

...

не могли бы в пояснить как работает АЦП в этом режиме

"100 Непрерывное преобразование с управлением от программы"

 

т.е. от чего запускается? автоматически после окончания предыдущего преобразования?

 

Да автоматически! Забыл спросить, а с регистром MMR что?

вот его описание:

Табл. 11. Назначение разрядов

MMR-регистра REFCON.

Разряд Описание

7–2 Зарезервированы

1 Отключение внутреннего ИОН

Устанавливается пользователем для

выключения внутреннего ИОН

и использования внешнего источника

опорного напряжения

Сбрасывается пользователем для

перевода внутреннего ИОН в рабочий

режим и использования его для работы

АЦП

0 Разрешить выход внутреннего ИОН

Устанавливается пользователем для

подключения внутреннего 2.5-вольтового

ИОН к выходу VREF. Этот выход может

использоваться внешней схемой в

качестве ИОН, но возможно понадобится

дополнительный буфер.

Сбрасывается пользователем для

отключения внутреннего ИОН от выхода

VREF.

 

 

Ваши настройки сейчас посмотрю!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

всмысле MMR регистром?

MMR - memory mapped register их там много :)

 

регистром REFCON имелось ввиду, тогда опора включена.

да и штука в том, что не вообще АЦП не работает, а в том, что не работает правильно только при постоянном обмене по SPI...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

всмысле MMR регистром?

MMR - memory mapped register их там много :)

 

регистром REFCON имелось ввиду, тогда опора включена.

да и штука в том, что не вообще АЦП не работает, а в том, что не работает правильно только при постоянном обмене по SPI...

 

Будьте добры поделитесь кусочком кода по работе с АЦП.

(Он в прерывании? - пользуетесь ли регистром ADCRST?)

Плохо представляю как это у вас работает. У меня всё нормально, правда с 7024.

Изменено пользователем Paramon

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

День добрый!

Подниму тему ибо уже неделю бьюсь и не могу победить. Тоже ADuc7021, тоже проблема с SPI. Причем уже передавать пытаюсь банальный алфавит, но на приемной стороне его нет, а только нули, нули... Это проверено осциллографом. Вот код:

  // SPISTA (p.70)
#define SPIRX_OVF   (SPISTA & (1<<5))
#define SPIRX_IRQ   (SPISTA & (1<<4))
#define SPIRX_FULL  (SPISTA & (1<<3))
#define SPITX_UDF   (SPISTA & (1<<2))
#define SPITX_IRQ   (SPISTA & (1<<1))
#define SPITX_EMPTY (!(SPISTA & (1)))

// SPICON  (p.70)
#define SPI_CONTINUOUS_TX   (1UL << 12)
#define SPI_LOOPBACK        (1UL << 11)
#define SPI_SO_EN           (1UL << 10)
#define SPI_SLAVE_SELECT_EN (1UL << 9)
#define SPI_RXOVF_OVERWRITE (1UL << 8)
#define SPI_TXUDF_SENDZERO  (1UL << 7)
#define SPI_TXWRITE_TRANS   (1UL << 6)
#define SPI_LSB_FIRST       (1UL << 5)
#define SPI_CLK_IDLEHIGH    (1UL << 3)
#define SPI_PHASE           (1UL << 2)
#define SPI_MASTER_MODE     (1UL << 1)
#define SPI_ENABLE          (1UL << 0)

#define SPI_BITRATE     1000000LL
#define SPI_MODE  (SPI_TXWRITE_TRANS | SPI_SO_EN | SPI_ENABLE \
                   | SPI_TXUDF_SENDZERO | SPI_CONTINUOUS_TX)

#ifndef SPI_BITRATE
#define SPI_BITRATE  100000LL
#endif

#define SPI_DIVISOR (((41779200LL/2)/SPI_BITRATE)-1)

#if (SPI_DIVISOR >= 0xFE)
#error "Bad SPI_BITRATE value! Look p.69 datasheet."
#endif

#ifndef SPI_MODE
#error "SPI_MODE not defined!"
#endif

uint8_t spidata[SPI_N];     // буфер выходных данных SPI

void SPI_Init(void)
{
  SPICON = SPI_MODE;
  SPIDIV = SPI_DIVISOR;
#if (SPI_MODE&SPI_MASTER_MODE)
  dir_out(SPI_SCK);
  dir_out(SPI_MOSI);
  dir_in(SPI_MISO);
  GP1CON &= ~(0x0FFF0000); GP1CON |= 0x02220000; // выбрали функцию GPIO как SPI
#else // (SPI_MODE&SPI_MASTER_MODE)
  dir_in(SPI_SCK);
  dir_in(SPI_MOSI);
  dir_out(SPI_MISO);
  dir_in(SPI_CS);  
  GP1CON &= ~(0xFFFF0000); GP1CON |= 0x22220000; // выбрали функцию GPIO как SPI
#endif //(SPI_MODE&SPI_MASTER_MODE)
}

__inline void SPI_StartIRQTX(void)
{
  spitxcount = 0;
  SPITX = spidata[spitxcount++];
  IRQEN = SPI_SLAVE_BIT;
  on(Req);      // сигнал что данные готовы - когда мастер его видит - он выставляет SlaveSelect и читает данные.
}

void SPI_Ready_ISR(void)
{
  SPITX = spidata[spitxcount++];
  if(spitxcount>=SPI_N)
  {
    IRQCLR = SPI_SLAVE_BIT; 
    off(Req);
    if(AdcBufRdy_flag) ADC_Start();
  }
}

void main(void){
...
SPI_Init();
...
while(1)    // вечный цикл
  {
      while(spitxcount < SPI_N);  // Ждем окончания передачи предыдущих байт..

spidata[0] = 'A'; spidata[1] = 'B'; spidata[2] = 'C'; spidata[3] = 'D'; 
spidata[4] = 'E'; spidata[5] = 'F'; spidata[6] = 'G'; spidata[7] = 'H'; 

      SPI_StartIRQTX();   // запускаем передачу данных на фоне
  }
}

Если убрать из режима SPI_TXUDF_SENDZERO (передача нуля если передающий регистр не готов), то шлет не нули а всякую чушь. Тоесть на лицо Underflow (передающий регистр не готов). А почему оно так - непойму.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разобрался. Проблема была в мастере. Я щелкал SlaveSelect после каждого байта, а когда стоит флаг SPI_CONTINUOUS_TX, этого делать не надо. Кроме того, не было предусмотрено механизма синхронизации между мастером и слейвом, и если терялся хоть один байт, то вся посылка сдвигалась. А терялись они именно в режиме отладки, когда я JTAG-ом просматривал регистры после приема каждого байта. При непрерывной работе таких потерь небыло, но я все-же ввел синхронизацию - если слейв не передал еще все данные, но видит что мастер убрал чипселект, то он сбрасывает свой буфер и готовится к новой передаче. И еще были проблемы в основной программе (в рассчетах), из-за которых также проскакивали левые числа.

 

Вот так вот. Бьешься неделю головой о стену, а потом напишешь на форум и тут-же тебе самому решение в голову придет. =) Так и телепатом стать не долго.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...