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

Очень напрягает пошаговая отладка Xmega128a1 на один шаг приходится до 5 секунд времени. Жесть!!!

Хотел узнать у всех так?

 

Отключите disasm.

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


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

Попался сборник статей сотрудников ЭФО:

ftp://ftp.efo.ru/pub/efo/Efo_publish-2008-IIsogl.pdf

Среди прочих там есть три статьи по XMEGA. В общем-то они представляют собой перекомпилированные атмеловские даташиты.

Но написаны на нормальном техническом русском языке. Я думаю многим будут полезны для начального ознакомления.

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


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

Так на ЭФФО прямо раздел есть и про Х-мега 3 (тры) полезных статьи

http://www.efo.ru/cgi-bin/pdf/pdf.pl?login...e=he19o0y5eF7QA

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


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

Так на ЭФФО прямо раздел есть и про Х-мега 3 (тры) полезных статьи

 

Да, это те же самые статьи. Но для их скачивания нужна регистрация. Я такие скачивания недолюбливаю.

Одна из причин в том, что запрашивающий не всегда следит за конфедициальностью предоставленных данных.

Ваша ссылка тому яркая иллюстрация - по ней под Вашим логином можно скачать любую статью, при этом на странице видны Ваши регистрационные данные, в частности e-mail как подарок для спамеров :( . Впрочем здесь есть и Ваш недосмотр...

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


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

Народ привет. Может не в тему, но меня мучит вот что. Значит девайс хмега128а1.

Значит первый вопрос: при определении вот таким кодом

void adc_init(void)
{
    // ADC_CalibrationValues_Set(&ADCA);  /* откалибруем ADC A. */
     offset = ADC_Offset_Get(&ADCA); /* Получим смещение для ADC A. */
         ADC_ConvMode_and_Resolution_Config(&ADCA, false, ADC_RESOLUTION_8BIT_gc); /* Сконфигурим ADC A для беззнакового преобразования 8 бит*/
     ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV128_gc);/* Частота преобразования CPUFREQ/128. */
     ADC_Referance_Config(&ADCA, ADC_REFSEL_INT1V_gc);/* установим опорное напряжение ADC A to be VCC 1 V.*/
        /* Настроим каналы 0, 1, 2 and 3 на  single ended input. */
    
    // ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0,ADC_CH_INPUTMODE_SINGLEENDED_gc,ADC_CH_GAINFAC_1X_gc);
        // ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH1,ADC_CH_INPUTMODE_SINGLEENDED_gc,ADC_CH_GAINFAC_1X_gc);
         //ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH2,ADC_CH_INPUTMODE_SINGLEENDED_gc,ADC_CH_GAINFAC_1X_gc);
         ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH3,ADC_CH_INPUTMODE_SINGLEENDED_gc,ADC_CH_GAINFAC_1X_gc);

    /* Настроим входы на ADC A ножки   4, 5, 6 and 7. */
    //ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXPOS_PIN4_gc, ADC_CH_MUXNEG_PIN0_gc);
    //ADC_Ch_InputMux_Config(&ADCA.CH1, ADC_CH_MUXPOS_PIN5_gc, ADC_CH_MUXNEG_PIN0_gc);
    //ADC_Ch_InputMux_Config(&ADCA.CH2, ADC_CH_MUXPOS_PIN6_gc, ADC_CH_MUXNEG_PIN0_gc);
    ADC_Ch_InputMux_Config(&ADCA.CH3, ADC_CH_MUXPOS_PIN7_gc, ADC_CH_MUXNEG_PIN0_gc);

    /* настроим sweep всех 4х каналов. */
    ADC_SweepChannels_Config(&ADCA, ADC_SWEEP_0123_gc);
    ADC_Enable(&ADCA);
    ADC_Wait_32MHz(&ADCA);
    ADC_FreeRunning_Enable(&ADCA);

}

Собственно при настройке канала на ногу ADC_CH_MUXPOS_PIN7_gc почему то опрашивается нога рядом, так и не понял почему.

Если кто нибудь работал с ацп, объясните, как заставить работать заремаренную верхнюю строчку. Компилер кроет матом, говорит не найти подпрограммы, хотя в оригинале(апноуте) все компилится нормально.

Второй вопрос, подскажите как настраивать каналы, не врубаюсь.

третий вопрос, как заставить работать одиночное преобразование.

Но главное не пойму почему канал опрашивается не тот.

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


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

Ответ на второй вопрос по АЦП: я вот такой код написал (на основе даташита):

//Инициализация АЦП - канал CH0
void init_ADC (void)
{
  // Конфигурируем канал CH0 на работу в несимметричном включении 
  ADCA.CH0.MUXCTRL|=ADC_CH_INPUTMODE_SINGLEENDED_gc;
  // В несимметричном режиме подключением к положительному входу АЦП линию 1 порта PORTA
  ADCA.CH0.MUXCTRL|=ADC_CH_MUXPOS_PIN1_gc;
  // Подключаем внешний источник опорного напряжения
  ADCA.REFCTRL|=0x20; 
  // Устанавливаем частоту тактирования АЦП: тактовая частота делиться на число N
  // при N=32, F=29,491200 МГц -  частота тактирования - 921,6 кГц
  ADCA.PRESCALER|=ADC_PRESCALER_DIV32_gc;
  // Разрешаем работу АЦП
  ADCA.CTRLA|=ADC_ENABLE_bm;
}

// Измерение на АЦП канал CH0;
unsigned int adc_rez (void)
{
  unsigned int ADC_result;
  ADCA.CTRLA|=ADC_CH0START_bm; // запускаем одиночное преобразование
  do{}while((ADCA.INTFLAGS&ADC_CH0IF_bm)==0x00); // Ждет флага CH0IF об окончании преобразования
  ADCA.INTFLAGS=ADC_CH0IF_bm; // сбрасываем флаг CH0IF записью в него "1"
  ADC_result=ADCA.CH0RES.i; // считываем результат преобразования в канале CH0
  return ADC_result; // Возвращение результата преобразования 
}

// Функция измерения напряжения - 30 измерений  
unsigned int usmer (void)
{
     unsigned int j,F;
     double value=0, temp;
     init_ADC();
     for (j=1; j<31; j++)
      {
       F=adc_rez();
       value=value+F;
      }
      temp=(value/30);
      F=(unsigned int)(temp);
      return F;
}

Как видно - работает в единичном преобразовании, функции легко переделать по любой вывод (добавляем переменную в вызов функции). А вот насчет - калибровки - пока не знаю (нашел по даташитам что калибровка АЦП происходит при производстве и дальше можно зашивать значения при программировании (и они не изменяются пока программатором не сотрешь) - так что пока разбираюсь что и как калибровать и надо ли на 12 -бит это делать?? (тем более внутренний ИОН всего 1 %).

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

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


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

Вроде как разобрался, спасибо..

 

Что самое обидное нет толкового описания. Смотрел на гаве описалово на русском, но оно противоречит по регистрам даташита, иар тоже разницу в названиях регистров имеет, вот и спрашиваю.

У меня ацп врет в районе 10ти значений, что вполне приемлимо при 12ти битном преобразовании при своем внутреннем опорном. А вот 8ми битное не понравилось совсем. Очень шумно.

По схеме все расключено в порядке, осциллом смотрел AVCC, более менее в поряде.

Изменено пользователем ведущий_специалист

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


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

Интересно, с какой ноги сигнал снимать? Я совсем запутался.

К примеру CH0, его ведь нужно определить на какую либо ножку ацп физически, или по умолчанию как то разводится внутри проца?

Что самое обидное нет толкового описания. Смотрел на гаве описалово на русском, но оно противоречит по регистрам даташита, иар тоже разницу в названиях регистров имеет, вот и спрашиваю.

У меня ацп врет в районе 10ти значений, что вполне приемлимо при 12ти битном преобразовании при своем внутреннем опорном. А вот 8ми битное не понравилось совсем. Очень шумно.

По схеме все расключено в порядке, осциллом смотрел AVCC, более менее в поряде.

 

Вот этой командой ADCA.CH0.MUXCTRL|=ADC_CH_MUXPOS_PIN1_gc; - т.е. получаем измерение напряженя на 1 ножке порта А.

Вот *.h файл с ICC AVR 7.22B (они очень близко написали к Atmel) - вобщем все понятно - каждое ADC_CH_MUXPOS_PIN*_gc соотвествует своей ножке * порта А или B (задаеться в начале).

(причем если надо использовать разные ножки- то лучше передовать число (понятнее вроде будет). -

#define ADC_MUXPOS_PIN0_gc (0x00<<4) /* Input pin 0 */
#define ADC_MUXPOS_PIN1_gc (0x01<<4) /* Input pin 1 */
#define ADC_MUXPOS_PIN2_gc (0x02<<4) /* Input pin 2 */
#define ADC_MUXPOS_PIN3_gc (0x03<<4) /* Input pin 3 */
#define ADC_MUXPOS_PIN4_gc (0x04<<4) /* Input pin 4 */
#define ADC_MUXPOS_PIN5_gc (0x05<<4) /* Input pin 5 */
#define ADC_MUXPOS_PIN6_gc (0x06<<4) /* Input pin 6 */
#define ADC_MUXPOS_PIN7_gc (0x07<<4) /* Input pin 7 */

 

Если кто знает, вот с чем помочь: написал код и как его прогнать (так чтоб не часы ждать) в AVR Studio, т.е. надо убедиться что работает (пока макетки нет)? причем Tmax от 100 до 10000

// Прерывание по окончанию счета
#pragma interrupt_handler iv_TCE0_OVF_isr:48
void iv_TCE0_OVF_isr(void) 
{
TCE0.CTRLA=0x00; // stop Timer 1 порта Е
TCE0.CNT.i=0xFF8C;   // установка значения для счета 115 значений - 0x73
T=T+1;
TCE0.CTRLA|=0x06; //start Timer 1 порта Е
}

//TIMER0 initialize - prescale: 256, actual value: 1.001739130435 мс
// Тактовая частота таймера 29491200 Гц
void timerE0_init(void)
{
TCE0.CTRLA=0x00; // stop Timer 1 порта Е
TCE0.CNT.i=0xFF8C;   // установка значения для счета 115  значений - 0x73
TCE0.INTCTRLA = 0x01; // Разрешение прерывания по переполнению - уровень низкий.
TCE0.CTRLA|=0x06; //start Timer 1 порта Е
}

//Функция задежки управляемая от таймера-счетчика
void delayT (unsigned int Tmax)
{
  T=0;
  timerE0_init();
  while (T<Tmax)
  {
   NOP();
  }
  TCE0.CTRLA=0x00; // stop Timer 1 порта Е
}

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

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


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

как его прогнать (так чтоб не часы ждать) в AVR Studio, т.е. надо убедиться что работает (пока макетки нет)? причем Tmax от 100 до 10000

А чего тут отлаживать? работу nop()? Если в прерывание заходит - значит работает.

Только вот не пойму, зачем столько мороки с таймером в прерывании. Во-первых останавливать таймер при смене CNT не обязательно. А во-вторых в данном случае логичнее было бы использовать Period Register

Тогда

void iv_TCE0_OVF_isr(void) 
{
TCE0.CTRLA=0x00; // stop Timer 1 порта Е
TCE0.CNT.i=0xFF8C;   // установка значения для счета 115 значений - 0x73
T=T+1;
TCE0.CTRLA|=0x06; //start Timer 1 порта Е
}

Превращается в

T++;

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


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

Запустил АЦП - есть смещение на 100 мВ+ шумы, рещил запустить калибровку. Просьба помочь разобраться:

Файлы для калибровки по даташитам Atmel:

// Из файла adc_driver.с от Atmel
void ADC_CalibrationValues_Load(ADC_t * adc)
{
    if(&ADCA == adc){
         /* Get ADCACAL0 from production signature . */
        adc->CALL = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCACAL0_offset );
        adc->CALH = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCACAL1_offset );
    }else {
        /* Get ADCBCAL0 from production signature  */
        adc->CALL = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCBCAL0_offset );
        adc->CALH = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCACAL1_offset );
    }
}

uint8_t SP_ReadCalibrationByte( uint8_t index )
{
    uint8_t result;
    /* Load the NVM Command register to read the calibration row. */
    NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
    result = pgm_read_byte(index);
    /* Clean up NVM Command register. */
    NVM_CMD = NVM_CMD_NO_OPERATION_gc;
    return result;
}

#define PROD_SIGNATURES_START 0x0000  
#define pgm_read_byte(x) *(x)

Написал собственную для ICCAVR:

// Функция калибровки АЦП порта А
void ADC_CalibrationValues_Load(void)
{
      unsigned char ADCACAL0_offset, ADCACAL1_offset;
      unsigned int value;
    /* Load the NVM Command register to read the calibration row. */
    NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
     ADCACAL0_offset = (*(volatile unsigned char *)0x20); // младший калибровочный байт
    /* Clean up NVM Command register. */
    NVM.CMD = NVM_CMD_NO_OPERATION_gc;
    /* Load the NVM Command register to read the calibration row. */
    NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
     ADCACAL1_offset = (*(volatile unsigned char *)0x21); // старший калибровочный байт
    /* Clean up NVM Command register. */
    NVM.CMD = NVM_CMD_NO_OPERATION_gc;
     value= (ADCACAL1_offset<<8)+ADCACAL0_offset;
     ADCA.CAL.i = value; // установка данных в регистр калибровка АЦП
}

 

1. Зачем надо писать (*(volatile unsigned char *)0x20)?? (только просьба просто объяснить).

2. Надо ли после считывания младшего калибровочного байта писать в NVM Command register или можно подрят считать оба байта?

3. Просьба - может кто уже разобрался с структурой из файла xmstructs.h мы можем сразу получить доступ ко всем калибровочным данным? Если да - то как это сделать (примеров с этой структорой нет).

#ifndef ___xmstructs_h
#define ___xmstructs_h
*
*
*
/* NVM signature row registers */
typedef struct NVM_SIG_struct
    { unsigned char RCOSC2MCAL;
      unsigned char reserved_0x01;
      unsigned char RCOSC32KCAL;
      unsigned char RCOSC32MCAL;
      unsigned char reserved_0x04;
      unsigned char reserved_0x05;
      unsigned char reserved_0x06;
      unsigned char reserved_0x07;
      unsigned char LOTNUMBYTE0;
      unsigned char LOTNUMBYTE1;
      unsigned char LOTNUMBYTE2;
      unsigned char LOTNUMBYTE3;
      unsigned char LOTNUMBYTE4;
      unsigned char LOTNUMBYTE5;
      unsigned char reserved_0x0E;
      unsigned char reserved_0x0F;
      unsigned char WAFERNUM;
      unsigned char reserved_0x11;
      unsigned char WAFERX0; // jph
      unsigned char WAFERX1; // jph
      unsigned char WAFERY0; // jph
      unsigned char WAFERY1; // jph
      unsigned char reserved_0x16;
      unsigned char reserved_0x17;
      unsigned char reserved_0x18;
      unsigned char reserved_0x19;
      unsigned char reserved_0x1A;
      unsigned char reserved_0x1B;
      unsigned char reserved_0x1C;
      unsigned char reserved_0x1D;
      unsigned char reserved_0x1E;
      unsigned char reserved_0x1F;
      unsigned char ADCACAL0;
      unsigned char ADCACAL1;
      unsigned char ADCACAL2;
      unsigned char ADCACAL3;
      unsigned char ADCBCAL0;
      unsigned char ADCBCAL1;
      unsigned char ADCBCAL2;
      unsigned char ADCBCAL3;
      unsigned char reserved_0x28;
      unsigned char reserved_0x29;
      unsigned char reserved_0x2A;
      unsigned char reserved_0x2B;
      unsigned char reserved_0x2C;
      unsigned char reserved_0x2D;
      unsigned char TEMPSENSE0;
      unsigned char TEMPSENSE1;
      unsigned char DACACAL0;
      unsigned char DACACAL1;
      unsigned char DACBCAL0;
      unsigned char DACBCAL1;
    } NVM_SIG_t;

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


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

решил наваять макетку для Хмеги128А1 и что-то терюсь где искать распиновку периферии.. уарты там и прочее как по портам раскидано? иль я туплю ?)

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


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

решил наваять макетку для Хмеги128А1 и что-то терюсь где искать распиновку периферии.. уарты там и прочее как по портам раскидано? иль я туплю ?)

См. раздел 29.2 Alternate Pin Functions в ATxmega64A1/128A1/192A1/256A1/384A1 Preliminary (rev.I). Там в виде таблицы все сведено

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


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

Всем привет! Тут поднимали тему про АЦП Xmega. Может кто-то тоже сталкивался с подобной проблемой:

Я пыталась добиться точного измерения на 12-битном разрешении. Все настроила, сделала калибровку (переписала калибровочные значения в регистры CAL).В бесконечном цикле запускаю функцию:

 

void ADC__read(ADC_t * adc, int countOfMeasure, countOfMeasure)

{

ADC_Enable(adc);

ADC_Wait_8MHz(adc);

 

// запуск преобразования на канале CH3

ADC_Ch_Conversion_Start(&adc->CH3);

 

// ожидание завершения преобразования

do{} while(!ADC_Ch_Conversion_Complete(&adc->CH3));

 

adc->INTFLAGS=ADC_CH3IF_bm;

 

// считываем результат преобразования с канала CH3

ADC_result[countOfMeasure]=ADC_ResultCh_GetWord(&adc->CH3, 0);

 

ADC_Disable(adc);

}

 

Полученные значения в массиве ADC_result[countOfMeasure] сильно нестабильны, разница между соседними отсчетами достигает 40 единиц. Даже не понятно какое из значений использовать.

 

Может это нормально для XMEga, но все-таки хотелось большей точности от 12-разрядного АЦП

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


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

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...