示例#1
0
/**
 * \internal
 * \brief Configure the ADC Module.
 *
 * \param adc  Base address of the ADC
 * \param config   Configuration for the ADC
 */
static void adc_set_config(Adc *const adc, struct adc_config *config)
{
	uint32_t reg = 0;

	reg =  (config->useq ? ADC_MR_USEQ_REG_ORDER : 0) |
			ADC_MR_PRESCAL(config->mck /
			(2 * config->adc_clock) - 1) |
			ADC_MR_TRACKTIM(config->tracktim) |
			ADC_MR_TRANSFER(config->transfer) |
			(config->startup_time);

	adc->ADC_MR = reg;

	adc->ADC_EMR = (config->tag ? ADC_EMR_TAG : 0) |
			(config->aste ? ADC_EMR_ASTE_SINGLE_TRIG_AVERAGE : 0);

	if (ADC_8_BITS == config->resolution ||
			ADC_10_BITS == config->resolution) {
		adc->ADC_MR |= config->resolution;
		adc->ADC_EMR &= ~ADC_EMR_OSR_Msk;
	} else {
		adc->ADC_MR &= ~ADC_MR_LOWRES;
		adc->ADC_EMR |= config->resolution;
	}
}
示例#2
0
文件: main.c 项目: nandojve/embedded
void adcInit(void)
{
   //Enable PIO peripheral clock
   PMC->PMC_PCER0 = (1 << ID_PIOA);
   //Enable ADC peripheral clock
   PMC->PMC_PCER1 = (1 << (ID_ADC - 32));

   //Configure PA3 as an input
   PIOA->PIO_IDR = PIO_PA3;
   PIOA->PIO_PER = PIO_PA3;
   PIOA->PIO_ODR = PIO_PA3;

   //Reset ADC module
   ADC->ADC_CR = ADC_CR_SWRST;

   //Configure ADC parameters
   ADC->ADC_MR = ADC_MR_USEQ_NUM_ORDER |
      ADC_MR_TRACKTIM(2) |
      ADC_MR_ANACH_NONE |
      ADC_MR_SETTLING_AST3 |
      ADC_MR_STARTUP_SUT768 |
      ADC_MR_PRESCAL(7) |
      ADC_MR_FREERUN_OFF |
      ADC_MR_FWUP_OFF |
      ADC_MR_SLEEP_NORMAL |
      ADC_MR_TRGSEL_ADC_TRIG0 |
      ADC_MR_TRGEN_DIS;

   //Enable channel 1
   ADC->ADC_CHER = ADC_CHER_CH1;
}
示例#3
0
void adc_init()
{
  PMC_EnablePeripheral(ID_ADC);
  ADC->ADC_CR = ADC_CR_SWRST;
  ADC->ADC_MR = ADC_MR_TRANSFER(1) | 
                ADC_MR_TRACKTIM(1) |
                ADC_MR_SETTLING(3) |
                ADC_MR_PRESCAL(4)  |   // adc clock = 64 MHz / ((4+1)*2) = 6.4
                ADC_MR_FREERUN     |
                ADC_MR_STARTUP_SUT512;
  ADC->ADC_CHER = (1 << ADC_CH_INPUT_VOLTAGE)    |
                  (1 << ADC_CH_TEMPERATURE)      |
                  (1 << ADC_CH_PHALANGE_CURRENT);
  ADC->ADC_IDR = 0xffffffff;
  ADC->ADC_ACR = ADC_ACR_TSON; // turn on temperature sensor
  ADC->ADC_CR = ADC_CR_START; // start a conversion
  while (!(ADC->ADC_ISR & ADC_ISR_DRDY)) { }
  ADC->ADC_LCDR;
  ADC->ADC_CR = ADC_CR_START; // start another conversion
  while (!(ADC->ADC_ISR & ADC_ISR_DRDY)) { }
  ADC->ADC_LCDR;
  ADC->ADC_IER = ADC_IER_DRDY; // fire ADC interrupt on any conversion complete
  for (int i = 0; i < 3; i++)
    g_adc_data[i] = 0x42 + i;
  NVIC_SetPriority(ADC_IRQn, 11); // really low priority...
  NVIC_EnableIRQ(ADC_IRQn);
}
示例#4
0
// Initialize ADC channels
void HAL::analogStart(void)
{

#if MOTHERBOARD == 500 || MOTHERBOARD == 501
  PIO_Configure(
    g_APinDescription[58].pPort,
    g_APinDescription[58].ulPinType,
    g_APinDescription[58].ulPin,
    g_APinDescription[58].ulPinConfiguration);
  PIO_Configure(
    g_APinDescription[59].pPort,
    g_APinDescription[59].ulPinType,
    g_APinDescription[59].ulPin,
    g_APinDescription[59].ulPinConfiguration);
#endif // (MOTHERBOARD==500) || (MOTHERBOARD==501)

  // ensure we can write to ADC registers
  ADC->ADC_WPMR = 0x41444300u; //ADC_WPMR_WPKEY(0);
  pmc_enable_periph_clk(ID_ADC);  // enable adc clock

  for (int i = 0; i < ANALOG_INPUTS; i++)
  {
    osAnalogInputValues[i] = 0;
    adcSamplesMin[i] = 100000;
    adcSamplesMax[i] = 0;
    adcEnable |= (0x1u << osAnalogInputChannels[i]);
    osAnalogSamplesSum[i] = 2048 * ANALOG_INPUT_MEDIAN;
    for (int j = 0; j < ANALOG_INPUT_MEDIAN; j++)
      osAnalogSamples[i][j] = 2048; // we want to prevent early error from bad starting values
  }
  // enable channels
  ADC->ADC_CHER = adcEnable;
  ADC->ADC_CHDR = !adcEnable;

  // Initialize ADC mode register (some of the following params are not used here)
  // HW trigger disabled, use external Trigger, 12 bit resolution
  // core and ref voltage stays on, normal sleep mode, normal not free-run mode
  // startup time 16 clocks, settling time 17 clocks, no changes on channel switch
  // convert channels in numeric order
  // set prescaler rate  MCK/((PRESCALE+1) * 2)
  // set tracking time  (TRACKTIM+1) * clock periods
  // set transfer period  (TRANSFER * 2 + 3)
  ADC->ADC_MR = ADC_MR_TRGEN_DIS | ADC_MR_TRGSEL_ADC_TRIG0 | ADC_MR_LOWRES_BITS_12 |
                ADC_MR_SLEEP_NORMAL | ADC_MR_FWUP_OFF | ADC_MR_FREERUN_OFF |
                ADC_MR_STARTUP_SUT64 | ADC_MR_SETTLING_AST17 | ADC_MR_ANACH_NONE |
                ADC_MR_USEQ_NUM_ORDER |
                ADC_MR_PRESCAL(AD_PRESCALE_FACTOR) |
                ADC_MR_TRACKTIM(AD_TRACKING_CYCLES) |
                ADC_MR_TRANSFER(AD_TRANSFER_CYCLES);

  ADC->ADC_IER = 0;             // no ADC interrupts
  ADC->ADC_CGR = 0;             // Gain = 1
  ADC->ADC_COR = 0;             // Single-ended, no offset

  // start first conversion
  ADC->ADC_CR = ADC_CR_START;
}
示例#5
0
// Initialize ADC channels
void HAL::analogStart(void)
{
  uint32_t  adcEnable = 0;

  // ensure we can write to ADC registers
  ADC->ADC_WPMR = ADC_WPMR_WPKEY(0);
  pmc_enable_periph_clk(ID_ADC);  // enable adc clock

  for(int i=0; i<ANALOG_INPUTS; i++)
  {
      osAnalogInputCounter[i] = 0;
      osAnalogInputValues[i] = 0;

  // osAnalogInputChannels
      //adcEnable |= (0x1u << adcChannel[i]);
      adcEnable |= (0x1u << osAnalogInputChannels[i]);
  }

  // enable channels
  ADC->ADC_CHER = adcEnable;
  ADC->ADC_CHDR = !adcEnable;

  // Initialize ADC mode register (some of the following params are not used here)
  // HW trigger disabled, use external Trigger, 12 bit resolution
  // core and ref voltage stays on, normal sleep mode, normal not free-run mode
  // startup time 16 clocks, settling time 17 clocks, no changes on channel switch
  // convert channels in numeric order
  // set prescaler rate  MCK/((PRESCALE+1) * 2)
  // set tracking time  (TRACKTIM+1) * clock periods
  // set transfer period  (TRANSFER * 2 + 3) 
  ADC->ADC_MR = ADC_MR_TRGEN_DIS | ADC_MR_TRGSEL_ADC_TRIG0 | ADC_MR_LOWRES_BITS_10 |
            ADC_MR_SLEEP_NORMAL | ADC_MR_FWUP_OFF | ADC_MR_FREERUN_OFF |
            ADC_MR_STARTUP_SUT64 | ADC_MR_SETTLING_AST17 | ADC_MR_ANACH_NONE |
            ADC_MR_USEQ_NUM_ORDER |
            ADC_MR_PRESCAL(AD_PRESCALE_FACTOR) |
            ADC_MR_TRACKTIM(AD_TRACKING_CYCLES) |
            ADC_MR_TRANSFER(AD_TRANSFER_CYCLES);

  ADC->ADC_IER = 0;             // no ADC interrupts
  ADC->ADC_CGR = 0;             // Gain = 1
  ADC->ADC_COR = 0;             // Single-ended, no offset
  
  // start first conversion
  ADC->ADC_CR = ADC_CR_START;
}
示例#6
0
文件: adc2.c 项目: AndreyMostovov/asf
/**
 * \internal
 * \brief Configure the ADC Module.
 *
 * \param adc  Base address of the ADC
 * \param config   Configuration for the ADC
 */
static void adc_set_config(Adc *const adc, struct adc_config *config)
{
	uint32_t reg = 0;

	reg =  (config->useq ? ADC_MR_USEQ_REG_ORDER : 0) |
			ADC_MR_PRESCAL(config->mck /
			(2 * config->adc_clock) - 1) |
			ADC_MR_TRACKTIM(config->tracktim) |
			ADC_MR_TRANSFER(config->transfer) |
			(config->startup_time);

	adc->ADC_MR = reg;

	adc->ADC_EMR = (config->tag ? ADC_EMR_TAG : 0) |
			(config->aste ? ADC_EMR_ASTE_SINGLE_TRIG_AVERAGE : 0);

	adc_set_resolution(adc, config->resolution);
}
示例#7
0
文件: adc.c 项目: peterliu2/FreeRTOS
/**
 * Set ADC tracking time
 * \param pAdc  Pointer to an Adc instance.
 * \param dwNs  Tracking time in nS.
 */
void ADC_SetTrackingTime( Adc *pAdc, uint32_t dwNs )
{
    uint32_t dwShtim;
    uint32_t dwMr;

    if (dwAdcClock == 0) return;
    /* Formula for SHTIM is:
       SHTIM = (time x ADCCLK) / (1000000000) - 1
       Since 1 billion is close to the maximum value for an integer, we first
       divide ADCCLK by 1000 to avoid an overflow */
    dwShtim = (dwNs * (dwAdcClock / 1000)) / 100000;
    if (dwShtim % 10) dwShtim /= 10;
    else {
        dwShtim /= 10;
        if (dwShtim) dwShtim --;
    }
    dwMr  = ADC_MR_TRACKTIM(dwShtim);
    dwMr |= pAdc->ADC_MR & ~ADC_MR_TRACKTIM_Msk;
    pAdc->ADC_MR = dwMr;
}
示例#8
0
文件: adc.c 项目: bgamari/libmanyuc
// Initializes de ADC.  To be used only once.
static void ADC_Init() {

    // Power up ADC
    PMC->PMC_PCER0 |= ADC_POWER_BITMASK;

    // Reset the controller
    ADC->ADC_CR = ADC_CR_SWRST;

    // Reset the Control Register
    // This sets:
    // * Hardware triggers are disabled. Only software triggers.
    // * No trigger selected.
    // * High resolution selected.
    // * No sleep mode, no fast wake up, no free run.
    // * The clock divider to 4 (12 MHz).
    // * No analog change
    // * No sequence
    ADC->ADC_MR = ADC_MR_PRESCAL(1) | ADC_MR_STARTUP(8) |
                  ADC_MR_TRANSFER(1) | ADC_MR_TRACKTIM(0) | ADC_MR_SETTLING(3);
}
示例#9
0
文件: drivers.cpp 项目: bratkov/tmos
ADC_DRIVER_DATA_STRU adc_driver_data;

const ADC_DRIVER_INFO adc_driver =
{
	{
		DRIVER_INFO_STUB,
		(DRV_ISR)ADC_ISR,
		(DRV_DCR)ADC_DCR,
		(DRV_DSR)ADC_DSR,
		ADC_IRQn,
		DRV_PRIORITY_KERNEL,
		ID_ADC
	},
	ADC,
	&adc_driver_data,
	ADC_MR_TRANSFER(1) | ADC_MR_TRACKTIM(7) | ADC_MR_SETTLING(3) | ADC_MR_STARTUP_SUT96//CFG_ADC_MR
};

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// 		(30) DACC DRIVER
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DACC_DRIVER_DATA_STRU dacc_driver_data;

const DACC_DRIVER_INFO dacc_driver =
{
	{
		DRIVER_INFO_STUB,
		(DRV_ISR)DACC_ISR,
		(DRV_DCR)DACC_DCR,
		(DRV_DSR)DACC_DSR,
		DACC_IRQn,
示例#10
0
void ADCSampler::begin(unsigned int samplingRate)
{
  this->sampleingRate = sampleingRate;
  // Turning devices Timer on.
  pmc_enable_periph_clk(ID_TC0); 


  // Configure timer
  TC_Configure(TC0, 0, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET | TC_CMR_ASWTRG_CLEAR | TC_CMR_TCCLKS_TIMER_CLOCK1);

  // It is good to have the timer 0 on PIN2, good for Debugging 
  //int result = PIO_Configure( PIOB, PIO_PERIPH_B, PIO_PB25B_TIOA0, PIO_DEFAULT);

  // Configure ADC pin A7
  //  the below code is taken from adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);

  ADC->ADC_CR = ADC_CR_SWRST;                            // Reset the controller.
  ADC->ADC_MR = 0;                                       // Reset Mode Register.
  ADC->ADC_PTCR = (ADC_PTCR_RXTDIS | ADC_PTCR_TXTDIS);   // Reset PDC transfer.
  ADC->ADC_MR |= ADC_MR_PRESCAL(3);                      // ADC clock = MSCK/((PRESCAL+1)*2), 13 -> 750000 Sps
  ADC->ADC_MR |= ADC_MR_STARTUP_SUT0;                    // What is this by the way?
  ADC->ADC_MR |= ADC_MR_TRACKTIM(15);
  ADC->ADC_MR |= ADC_MR_TRANSFER(1);
  ADC->ADC_MR |= ADC_MR_TRGEN_EN;                         // Hardware trigger selected by TRGSEL field is enabled. Включен аппаратный триггер, выбранный по полю TRGSEL.
  ADC->ADC_MR |= ADC_MR_TRGSEL_ADC_TRIG1;                 // selecting TIOA0 as trigger.
  ADC->ADC_MR |= ADC_MR_LOWRES_BITS_12;                   // brief (ADC_MR) 12-bit resolution 
  //ADC->ADC_ACR |= ADC_ACR_TSON;                         // Включить датчик температуры    
 
  ADC->ADC_CHER = ADC_CHANNELS;                           // Записать контролируемые входа
  ADC->ADC_CHDR = ADC_CHANNELS_DIS;                       // Отключить не используемые входа
  ADC->ADC_EMR = ADC_EMR_CMPMODE_IN                       // Генерирует событие, когда преобразованные данные пересекают окно сравнения.
	//  | ADC_EMR_CMPSEL(4)                               // Compare channel 4 = A3
	  | ADC_EMR_CMPALL                                    // Compare ALL channel
	  | ADC_EMR_CMPFILTER(0);                             // Количество последовательных событий сравнения, необходимых для повышения флага = CMPFILTER + 1
														  // При запрограммированном значении 0 флаг увеличивается, как только происходит событие.

  ADC->ADC_CWR = ADC_CWR_LOWTHRES(_compare_Low) | ADC_CWR_HIGHTHRES(_compare_High); // Установить высокий и низкий порог компаратора АЦП

  //ADC->ADC_SEQR1 = 0x01234567;                            // использовать A0 до A7 в порядке в массив
  //ADC->ADC_SEQR2 = 0x00dcba00;                            // использовать для А8 А11 следующие действия по порядку в массив  

  /* Interupts */
  ADC->ADC_IDR = ~ADC_IDR_ENDRX;                        // сбросить регистры прерывания по готовности данных.
  ADC->ADC_IDR = ~ADC_IDR_COMPE;                        // сбросить регистры копаратора.
  ADC->ADC_IER =  ADC_IER_ENDRX;                        // Включить прерывание по готовности данных.
 // ADC->ADC_IER =  ADC_IER_COMPE;                        // Прерывание по совпадению сравнения компаратором
  ADC->ADC_ISR = ~ADC_ISR_COMPE;                        // ADC Interrupt Status Register Обнулить ошибку сравнения с момента последнего чтения ADC_ISR.
  /* Waiting for ENDRX as end of the transfer is set
    when the current DMA transfer is done (RCR = 0), i.e. it doesn't include the
    next DMA transfer.

    If we trigger on RXBUFF This flag is set if there is no more DMA transfer in
    progress (RCR = RNCR = 0). Hence we may miss samples.

	Ожидание окончания ENDRX в конце передачи
	когда выполняется текущая передача DMA (RCR = 0), то есть она не включает следующая передача DMA.
    Если мы запускаем RXBUFF, этот флаг устанавливается, если больше нет передачи DMA в прогресс (RCR = RNCR = 0). 
	Следовательно, мы можем пропустить образцы.
  */

  
  unsigned int cycles = 42000000 / samplingRate;

  /*  timing of ADC */
  TC_SetRC(TC0, 0, cycles);                             // TIOA0 goes HIGH on RC.
  TC_SetRA(TC0, 0, cycles / 2);                         // TIOA0 goes LOW  on RA.

  // We have to reinitalise just in case the Sampler is stopped and restarted...
  // Мы должны приступить к реинициализировать на случай, если Sampler остановлен и перезапущен ...
  dataReady = false;
  dataHigh = false;                       // Признак срабатывания компаратора
  adcDMAIndex = 0;
  adcTransferIndex = 0;
  for (int i = 0; i < NUMBER_OF_BUFFERS; i++)
  {
    memset((void *)adcBuffer[i], 0, BUFFER_SIZE);
  }

  ADC->ADC_RPR  = (unsigned long) adcBuffer[adcDMAIndex];         // DMA buffer
  ADC->ADC_RCR  = (unsigned int)  BUFFER_SIZE;                    // ADC works in half-word mode.
  ADC->ADC_RNPR = (unsigned long) adcBuffer[(adcDMAIndex + 1)];   // next DMA buffer
  ADC->ADC_RNCR = (unsigned int)  BUFFER_SIZE;

  // Enable interrupts
  NVIC_SetPriorityGrouping(NVIC_PriorityGroup_1);
  NVIC_DisableIRQ(ADC_IRQn);
  NVIC_ClearPendingIRQ(ADC_IRQn);  
  NVIC_SetPriority(ADC_IRQn, 6);  
  NVIC_EnableIRQ(ADC_IRQn);
  ADC->ADC_PTCR  =  ADC_PTCR_RXTEN;                               // Enable receiving data.
  ADC->ADC_CR   |=  ADC_CR_START;                                 // start waiting for trigger.

  // Start timer
  TC0->TC_CHANNEL[0].TC_SR;
  TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN;
  TC_Start(TC0, 0);
}