Реалити-шоу «КБ13 и АЦП». День 2.

Мы снова в эфире и снова рассказываем о процессе боевых действий КБ13 против платы АЦП.

Борьба со временем.

С утра пришлось взять в руки секундомер — время снятия замеров всех 16 каналов АЦП не соответсвовало заявленным 10 мкс, а занимало где-то 60-70 мкс, что, конечно же, многовато при наших возможностях.

Оптимизация времени считывания пошла несколькими путями:

  • разгон процессора;
  • уменьшение таймингов на сигналы чипселекта, рида и пульса;
  • увеличение частоты выдачи чипселекта и рида контроллером.


Прежде всего мы уменьшили тайминги шины EBI, на которой висят АЦП — выставив их в соответствии с даташитом для AD7656:

// NCS setup time. Unit: ns.
#define NCS_RD_SETUP            6

// NCS pulse time. Unit: ns.
#define NCS_RD_PULSE            40

// NCS hold time. Unit: ns.
#define NCS_RD_HOLD             10

// NRD setup time. Unit: ns.
#define NRD_SETUP               6

// NRD pulse time. Unit: ns.
#define NRD_PULSE               40

// NRD hold time. Unit: ns.
#define NRD_HOLD                10

// Read cycle time. Unit: ns.
#define NRD_CYCLE               Max((NCS_RD_SETUP + NCS_RD_PULSE + NCS_RD_HOLD),(NRD_SETUP + NRD_PULSE + NRD_HOLD))

Далее настала очередь процессора.
Изначально инициализация системных часов происходила следующим образом:

#define FOSC0           12000000                              //!< Osc0 frequency: Hz.
#define OSC0_STARTUP    AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC  //!< Osc0 startup time: RCOsc periods.

#define APPLI_CPU_SPEED   24000000
#define APPLI_PBA_SPEED   24000000

pm_freq_param_t   pm_freq_param=
{
	.cpu_f  =       APPLI_CPU_SPEED,
	.pba_f    =     APPLI_PBA_SPEED,
	.osc0_f     =   FOSC0,
	.osc0_startup = OSC0_STARTUP
};

void init(void)
{
	pm_configure_clocks(&pm_freq_param);
	init_dbg_rs232(pm_freq_param.pba_f);
	set_cpu_hz(pm_freq_param.cpu_f);
	pm_configure_usb_clock();
}

Мы же включили PLL0 и затактировали системные часы от него, разогнав процессор тем самым до 48 МГц:

#define FOSC0           12000000                              //!< Osc0 frequency: Hz.
#define OSC0_STARTUP    AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC  //!< Osc0 startup time: RCOsc periods.

#define APPLI_CPU_SPEED   24000000
#define APPLI_PBA_SPEED   24000000

volatile avr32_pm_t* pm = &AVR32_PM;

#define  EXAMPLE_GCLK_FUNCTION   AVR32_PM_GCLK_0_1_FUNCTION
#define  EXAMPLE_GCLK_ID   0
#define  EXAMPLE_GCLK_PIN   AVR32_PM_GCLK_0_1_PIN

void local_start_pll0(volatile avr32_pm_t* pm)
{
  pm_switch_to_osc0(pm, FOSC0, OSC0_STARTUP);  // Switch main clock to Osc0.

  pm_pll_setup(pm,
               0,   // use PLL0
               7,   // MUL=7 in the formula
               1,   // DIV=1 in the formula
               0,   // Sel Osc0/PLL0 or Osc1/PLL1
               16); // lockcount in main clock for the PLL wait lock

  pm_pll_set_option(pm, 0, 1, 1, 0);

  pm_pll_enable(pm,0);

  pm_wait_for_pll0_locked(pm) ;

  pm_gc_setup(pm,
               EXAMPLE_GCLK_ID,
               1,  // Use Osc (=0) or PLL (=1), here PLL
               0,  // Sel Osc0/PLL0 or Osc1/PLL1
               0,  // disable divisor
               0); // no divisor

   pm_gc_enable(pm, EXAMPLE_GCLK_ID);

   gpio_enable_module_pin(EXAMPLE_GCLK_PIN, EXAMPLE_GCLK_FUNCTION);

   pm_cksel(pm, 1, 0, 0, 0, 0, 0);

   flashc_set_wait_state(1);

   pm_switch_to_clock(pm, AVR32_PM_MCSEL_PLL0);
 }

void init(void)
{
	local_start_pll0(pm);
}

В результате мы имеем время считывания всех 16 каналов АЦП — 10-15 мкс.

Осциллограф показал еще кое-что интересное — пауза между выдачей контроллером пар сигналов CS и READ составляет примерно 240 нс (на неразогнанном процессоре — все 500).
Завтра планируется работать в этом направлении, т.е. увеличить частоту дрыганья микроконтроллера ногой.
Пока, предварительно, идей две — либо, как посоветовал схемотехник, переводить АЦП с EBI на локальную шину, либо уменьшать время паузы редактированием установочных регистров SMC.

Похожий бред:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Protected by WP Anti Spam