示例#1
0
文件: TaskAD.c 项目: bjarntoft/Hover
void GetSensorValue(void)
{
	totalFR = totalFR + adc_get_channel_value(ADC,ADC_CHANNEL_7) * (3.3/2.55);
	totalFL = totalFL + adc_get_channel_value(ADC,ADC_CHANNEL_6) * (3.3/2.55);
	totalBR = totalBR + adc_get_channel_value(ADC,ADC_CHANNEL_5) * (3.3/2.55);
	totalBL = totalBL + adc_get_channel_value(ADC,ADC_CHANNEL_4) * (3.3/2.55);
	
	count++;

	if(count==avg_sensor_read)
	{
		uint32_t sensorValueFR = totalFR/avg_sensor_read;
		uint32_t sensorValueFL = totalFL/avg_sensor_read;
		uint32_t sensorValueBR = totalBR/avg_sensor_read;
		uint32_t sensorValueBL = totalBL/avg_sensor_read;
		totalFR = 0;
		totalFL = 0;
		totalBR = 0;
		totalBL = 0;
		count = 0;
		
		sensor_diff_f = sensorValueFL-sensorValueFR;
		sensor_diff_b = sensorValueBL-sensorValueBR;
		
		//printf("högerfram: %d \n", sensorValuefr);
		//printf("vänsterfram: %d \n", sensorvaluefl);
		//printf("högerbak: %d \n", sensorvaluebr);
		//printf("vänsterbak: %d \n", sensorvaluebl);
		//printf("Differens fram: %d \n", sensor_diff_f);
		//printf("Differens bak: %d \n", sensor_diff_b);
	}
}
示例#2
0
// Start converting the enabled channels
void AnalogInStartConversion(uint32_t channels)
{
#if SAM3XA || SAM4S
	// Clear out any existing conversion complete bits in the status register
	for (uint32_t chan = 0; chan < 16; ++chan)
	{
		if ((adc_get_status(ADC) & (1 << chan)) != 0)
		{
			(void)adc_get_channel_value(ADC, static_cast<adc_channel_num_t>(chan));
		}
	}
	adc_start(ADC);
#elif SAM4E
	channels &= activeChannels;
	if ((channels & 0x0000FFFF) != 0)
	{
		StartConversion(AFEC0);
	}
	if ((channels & 0xFFFF0000) != 0)
	{
		StartConversion(AFEC1);
	}
#elif SAME70
	channels &= activeChannels;
	if ((channels & 0x000003FF) != 0)
	{
		StartConversion(AFEC0);
	}
	if ((channels & 0x003FF800) != 0)
	{
		StartConversion(AFEC1);
	}
#endif
}
示例#3
0
/**
 * \brief ADC interrupt handler.
 * Entramos aqui quando a conversao for concluida.
 */
void ADC_Handler(void)
{
	uint32_t tempValue;
	uint32_t status ;

	status = adc_get_status(ADC);
	
	/* Checa se a interrupção é devido ao canal 5 */
	if ((status & ADC_ISR_EOC5)) {
		tempValue = adc_get_channel_value(ADC, ADC_POT_CHANNEL);
		if ((tempValue > adc_value_old + 2) || (tempValue < adc_value_old - 2))
		{
			if (isAmp){
				amplitude = tempValue;
				atualiza_amp(amplitude);
			} else {
				frequencia = tempValue;
				tc_stop(TC0,0);
				configure_tc((frequencia*32768/2000)/4095);
				atualiza_freq(frequencia);
			}
		}
		adc_value_old = tempValue;
	}
	
}
示例#4
0
 /***************************************************************************
 Reads the Analog 0 pin on Due.
 Retun values for the x-axis of the joystick.
 ***************************************************************************/
 uint32_t ReadAnalog0(void)
 {
	 uint32_t xAngle;
	 adc_start(ADC);
	 xAngle = adc_get_channel_value(ADC,ADC_CHANNEL_7);
	 return xAngle;
 }
示例#5
0
/**
* \brief ADC interrupt handler.
*/
void ADC_Handler(void)
{
	uint32_t tmp;
	uint32_t status ;

	status = adc_get_status(ADC);
	
	/* Checa se a interrupção é devido ao canal 5 */
	static float rad_antes = 0;
	if ((status & ADC_ISR_EOC5)) {
		tmp = adc_get_channel_value(ADC, ADC_POT_CHANNEL);

			ili93xx_set_foreground_color(COLOR_WHITE);
			ili93xx_draw_filled_rectangle(9, 39, ILI93XX_LCD_WIDTH,55);
			v=3.3*((float)tmp)/4095.0;
			rad=2*pi*((float)tmp)/4095.0;
			ili93xx_draw_line(120,160,120+54*arm_cos_f32(rad_antes),160+54*arm_sin_f32(rad_antes));
			ili93xx_set_foreground_color(COLOR_BLACK);
			sprintf(vet, "Tensao: %f", v);
			ili93xx_draw_string(10, 40, vet);
			ili93xx_draw_line(120,160,120+54*arm_cos_f32(rad),160+54*arm_sin_f32(rad));
			rad_antes = rad;

	}
	

	
}
示例#6
0
 /****************************************************************************
 Reads the Analog 1 pin on Due.
 Retun values for the y-axis of the joystick.
 ****************************************************************************/
 uint32_t ReadAnalog1(void)
 {
	 uint32_t yAngle;
	 adc_start(ADC);
	 yAngle = adc_get_channel_value(ADC,ADC_CHANNEL_6);
	 return yAngle;
 }
示例#7
0
 /****************************************************************************
 Reads the Analog 2 pin on Due.
 Retun values for the IR sensor.
 ****************************************************************************/
 uint32_t ReadAnalog2(void)
 {
	 uint32_t IRSensorer;
	 adc_start(ADC);
	 IRSensorer = adc_get_channel_value(ADC,ADC_CHANNEL_5);
	 return IRSensorer;
 }
示例#8
0
/**
*  Interrupt handler for TC0 interrupt.
*/
void ADC_Handler(void)
{
	uint32_t tmp;
	uint32_t status ;

	status = adc_get_status(ADC);
	max_digital = adc_get_channel_value(ADC, ADC_POT_CHANNEL);
}
示例#9
0
// 40kHz sampler.
//
// Runs at too high a priority to call FreeRTOS routines.
// This routine executes each (approximately) 2000 cycles. It is important that
// it is not slow.
void PWM_Handler(void) {
	// Read status to indicate that interrupt has been handled
	uint32_t isr = PWM->PWM_ISR1;
	if (isr != (1 << 2)) { // Must be interrupt two
		fatalBlink(1, 6);
	}
	
	if (mode == AM_ADC) {
		// Temporary code - read ADC, calculate result.
		// TODO: replace with DMA.
		// TODO: handle fading.
		uint32_t data0 = adc_get_channel_value(ADC, 0);
		uint32_t data1 = adc_get_channel_value(ADC, 1);
		uint32_t sum = data0 + data1; // sum is a 13 bit value
	
		// Calculate output value for DACC
		dacc_write_conversion_data(DACC, sum / 2);
	
		// Calculate duty cycle value for PWM Channel 2.
		// Calculated value must be between 0 and US_PERIOD-1, non inclusive.
	
		int32_t duty = ((US_PERIOD - 2) * sum / 8192) + 1;
		// For testing with silence
		// int32_t duty = US_PERIOD / 2;
		PWM->PWM_CH_NUM[2].PWM_CDTYUPD = duty;	
	} else if (mode == AM_HZ) {
		
		// Get TIOA value from status register
		bool mtioa = TC0->TC_CHANNEL[0].TC_SR & TC_SR_MTIOA;
		
		// Write to DACC
		int16_t dDelta = 2046 * audioVolume / 255;
		if (!mtioa) {
			dDelta = -dDelta;
		}
		dacc_write_conversion_data(DACC, dDelta + 2048);
		
		// Set PWM
		int16_t pDelta = (US_PERIOD - 2) / 2 * audioVolume / 255;
		if (!mtioa) {
			pDelta = -pDelta;
		}
		PWM->PWM_CH_NUM[2].PWM_CDTYUPD = pDelta + (US_PERIOD / 2);
	}
}
示例#10
0
/**
 * \brief ADC interrupt handler.
 * Entramos aqui quando a conversao for concluida.
 */
void ADC_Handler(void)
{
	uint32_t resistencia;
	
	if ((adc_get_status(ADC) & ADC_ISR_RXBUFF) == ADC_ISR_RXBUFF) {

		resistencia = adc_get_channel_value(ADC, ADC_POT_CHANNEL);
	}
}
示例#11
0
uint32_t analogRead(void)
{
	adc_start(ADC);
	//delay_us(100);
	//delayMicroseconds(100);
	
	return adc_get_channel_value(ADC,ADC_CHANNEL_7);
	/* Replace with actual value read from A/D input*/
}
示例#12
0
// Read the most recent 12-bit result from a channel
uint16_t AnalogInReadChannel(AnalogChannelNumber channel)
{
	if ((unsigned int)channel < numChannels)
	{
#if SAM3XA || SAM4S
		return adc_get_channel_value(ADC, GetAdcChannel(channel));
#elif SAM4E || SAME70
		return afec_channel_get_value(GetAfec(channel), GetAfecChannel(channel));
#endif
	}
	return 0;
}
示例#13
0
/** Display current information,including
 * voltage on potentiometer, thresholds and comparison mode.
 */
static void display_info(void)
{
	uint32_t ul_adc_value = adc_get_channel_value(ADC, ADC_CHANNEL_POTENTIOMETER);
	float f_low_threshold = (float)gs_us_low_threshold * VOLT_REF / MAX_DIGITAL;
	float f_high_threshold = (float)gs_us_high_threshold * VOLT_REF / MAX_DIGITAL;
	uint32_t ul_low_threshold = f_to_int(f_low_threshold);
	uint32_t ul_high_threshold = f_to_int(f_high_threshold);

	printf("-I- Thresholds: %u mv - %u mv.\n\r", ul_low_threshold, ul_high_threshold);
	printf("-I- Voltage on potentiometer: %u mv.\n\r",
			(unsigned int)(ul_adc_value * VOLT_REF / MAX_DIGITAL));
	printf("-I- Comparison mode is %u\n\r.",
			(unsigned int)(ADC->ADC_EMR & ADC_EMR_CMPMODE_Msk));
}
示例#14
0
文件: demo.c 项目: thegeek82000/asf
/**
 * \brief Handler for ADC interrupt.
 */
void ADC_Handler(void)
{
	uint32_t low_threshold;
	uint32_t high_threshold;
	uint32_t status = adc_get_status(ADC);

	/* Read the status to ack the IT */
	if ((status & ADC_ISR_COMPE) == ADC_ISR_COMPE) {
		/* Get the potentiometer initial value */
		pontentiometer_value = adc_get_channel_value( ADC,
				ADC_CHANNEL_POTENTIOMETER );

		/* Set Window threshold according to the initial values */
		low_threshold = pontentiometer_value -
				(NB_INTERVALS * (0x1000 / 256));
		if (low_threshold > 0xf0000000) {
			low_threshold = 0;
		}

		high_threshold = pontentiometer_value +
				(NB_INTERVALS * (0x1000 / 256));
		if (high_threshold >= 0x1000) {
			high_threshold = 0x1000 - 1;
		}

		/* Normalize the value 0 -> 255 */
		pontentiometer_value
			= pontentiometer_value*100 + 1;
		ppt_delay_clapse_counter = 0;

		/* Setup Threshold*/
		adc_set_comparison_window( ADC, low_threshold,
				high_threshold);

		/* Compare mode, in the window. */
		adc_enable_interrupt(ADC, ADC_IER_COMPE);
	}

	if (status & ADC_ISR_ENDRX) {
		/* Start next buffer */
		ADC->ADC_RNPR = (uint32_t)
				frame_buffer[(adc_buf_ndx + 2) % AUDIO_NB_BUFFER];
		ADC->ADC_RNCR = AUDIO_FRAME_SIZE;

		adc_buf_ndx = (adc_buf_ndx + 1) % AUDIO_NB_BUFFER;
		adc_nb_samples += AUDIO_FRAME_SIZE;
	}
}
示例#15
0
/**
* \brief ADC interrupt handler.
*/
void ADC_Handler(void)
{
	uint32_t tmp;
	uint32_t status ;

	status = adc_get_status(ADC);
	
	/* Checa se a interrupção é devido ao canal 5 */
	if ((status & ADC_ISR_EOC5)) {
		tmp = adc_get_channel_value(ADC, ADC_POT_CHANNEL);
		if(tmp != adc_value_old)
		{
			adc_value_old = tmp;
			adc_value_new = 1;
		}
	}
}
示例#16
0
void ADC_Handler(void)
{
	uint32_t ul_mode;
	uint16_t us_adc;

	/* Disable Compare Interrupt. */
	adc_disable_interrupt(ADC, ADC_IDR_COMPE);

	if ((adc_get_status(ADC) & ADC_ISR_COMPE) == ADC_ISR_COMPE) {
		ul_mode = adc_get_comparison_mode(ADC);
		us_adc = adc_get_channel_value(ADC, ADC_CHANNEL_POTENTIOMETER);

		switch (ul_mode) {
		case 0:
			printf("-ISR-:Potentiometer voltage %d mv is below the low "
				"threshold:%d mv!\n\r", us_adc * VOLT_REF / MAX_DIGITAL,
				gs_us_low_threshold * VOLT_REF / MAX_DIGITAL);
			break;

		case 1:
			printf("-ISR-:Potentiometer voltage %d mv is above the high "
				"threshold:%d mv!\n\r", us_adc * VOLT_REF / MAX_DIGITAL,
				gs_us_high_threshold * VOLT_REF / MAX_DIGITAL);
			break;

		case 2:
			printf("-ISR-:Potentiometer voltage %d mv is in the comparison "
				"window:%d-%d mv!\n\r", us_adc * VOLT_REF / MAX_DIGITAL,
				gs_us_low_threshold * VOLT_REF / MAX_DIGITAL, gs_us_high_threshold * VOLT_REF / MAX_DIGITAL);
			break;

		case 3:
			printf("-ISR-:Potentiometer voltage %d mv is out of the comparison"
				" window:%d-%d mv!\n\r", us_adc * VOLT_REF / MAX_DIGITAL,
				gs_us_low_threshold * VOLT_REF / MAX_DIGITAL, gs_us_high_threshold * VOLT_REF / MAX_DIGITAL);
			break;
		}
	}
}
示例#17
0
文件: demo.c 项目: thegeek82000/asf
/**
 * \brief Turn on/off ADC module.
 *
 * \param on True to start ADC, false to turn off.
 */
static void demo_start_adc(bool on)
{
	uint32_t low_threshold, high_threshold;

	if (on == true) {
		/* Check if already enabled */
		if (demo_adc_on) {
			return;
		}

		demo_config_adc();

		/* Start TC0 and hardware trigger. */
		tc_start(TC0, 1);

		/* Get the potentiometer initial value */
		pontentiometer_value = adc_get_channel_value(ADC,
				ADC_CHANNEL_POTENTIOMETER);

		/* Set Window threshold according to the initial values */
		low_threshold  = pontentiometer_value -
				(NB_INTERVALS * (0x1000 / 256));
		if (low_threshold > 0xf000000) {
			low_threshold = 0;
		}

		high_threshold = pontentiometer_value +
				(NB_INTERVALS * (0x1000 / 256));
		if (high_threshold >= 0x1000) {
			high_threshold = 0x1000 - 1;
		}

		pontentiometer_value
			= pontentiometer_value*100 + 1;

		/* Channel 5 has to be compared. */
		adc_set_comparison_channel(ADC, ADC_CHANNEL_POTENTIOMETER);
		/* Compare mode, out the window. */
		adc_set_comparison_mode(ADC, ADC_EMR_CMPMODE_OUT);

		/* Set up Threshold. */
		adc_set_comparison_window(ADC, low_threshold,
				high_threshold);

		/* Enable ADC interrupt. */
		NVIC_EnableIRQ(ADC_IRQn);

		/* Enable Compare Interrupt. */
		adc_enable_interrupt(ADC, ADC_IER_COMPE);

		/* Set adc on flag */
		demo_adc_on = 1;

		/* Reset clapse time */
		ppt_delay_clapse_counter = 0;
	} else {
		tc_stop(TC0, 1);
		/* Enable ADC interrupt. */
		NVIC_DisableIRQ(ADC_IRQn);
		/* Enable Compare Interrupt. */
		adc_disable_interrupt(ADC, ADC_IDR_COMPE);
		/* Set adc off flag */
		demo_adc_on = 0;
	}
}
示例#18
0
int main(void)
{
	uint8_t i;
	uint8_t temperature[BUFFER_SIZE];
	uint8_t light[BUFFER_SIZE];
	uint8_t value_disp[5];
	uint32_t adc_value;
	double temp;

	// Initialize clocks.
	sysclk_init();

	// Initialize GPIO states.
	board_init();

	// Configure ADC for light sensor.
	configure_adc();

	// Initialize at30tse.
	at30tse_init();

	// Configure IO1 buttons.
	configure_buttons();

	// Initialize SPI and SSD1306 controller.
	ssd1306_init();
	ssd1306_clear();

	// Clear internal buffers.
	for (i = 0; i < BUFFER_SIZE; ++i)
	{
		temperature[i] = 0;
		light[i] = 0;
	}

	while (true)
	{
		/* Refresh page title only if necessary. */
		if (app_mode_switch > 0)
		{
			app_mode = app_mode_switch - 1;

			// Clear screen.
			ssd1306_clear();
			ssd1306_set_page_address(0);
			ssd1306_set_column_address(0);

			/* Temperature mode. */
			if (app_mode == 0)
			{
				ioport_set_pin_level(IO1_LED1_PIN, IO1_LED1_ACTIVE);
				ioport_set_pin_level(IO1_LED2_PIN, !IO1_LED2_ACTIVE);
				ioport_set_pin_level(IO1_LED3_PIN, !IO1_LED3_ACTIVE);
				ssd1306_write_text("Temperature sensor:");
			}
			/* Light mode. */
			else if (app_mode == 1)
			{
				ioport_set_pin_level(IO1_LED2_PIN, IO1_LED2_ACTIVE);
				ioport_set_pin_level(IO1_LED1_PIN, !IO1_LED1_ACTIVE);
				ioport_set_pin_level(IO1_LED3_PIN, !IO1_LED3_ACTIVE);
				ssd1306_write_text("Light sensor:");
			}
			/* SD mode. */
			else
			{
				ioport_set_pin_level(IO1_LED3_PIN, IO1_LED3_ACTIVE);
				ioport_set_pin_level(IO1_LED1_PIN, !IO1_LED1_ACTIVE);
				ioport_set_pin_level(IO1_LED2_PIN, !IO1_LED2_ACTIVE);

				display_sd_info();
			}
			app_mode_switch = 0;
		}

		// Shift graph buffers.
		for (i = 0; i < BUFFER_SIZE - 1; ++i)
		{
			temperature[i] = temperature[i + 1];
			light[i] = light[i + 1];
		}

		// Get temperature in a range from 0 to 40 degrees.
		if (at30tse_read_temperature(&temp) == TWI_SUCCESS)
		{
			// Don't care about negative temperature.
			if (temp < 0)
				temp = 0;

			// Update temperature for display.
			// Note: -12 in order to rescale for better rendering.
			if (temp < 12)
				temperature[BUFFER_SIZE - 1] = 0;
			else
				temperature[BUFFER_SIZE - 1] = temp - 12;
		}
		else
		{
			// Error print zero values.
			temperature[BUFFER_SIZE - 1] = 0;
		}

		// Get light sensor information.
		// Rescale for better rendering.
		adc_start(ADC);
		adc_value = adc_get_channel_value(ADC, ADC_CHANNEL_4);
		light[BUFFER_SIZE - 1] = 24 - adc_value * 24 / 4096;

		// Print temperature in text format.
		if (app_mode == 0)
		{
			sprintf(value_disp, "%d", (uint8_t)temp);
			ssd1306_set_column_address(95);
			ssd1306_write_command(SSD1306_CMD_SET_PAGE_START_ADDRESS(0));
			ssd1306_write_text(" ");
			ssd1306_write_text(value_disp);
			// Display degree symbol.
			ssd1306_write_data(0x06);
			ssd1306_write_data(0x06);
			ssd1306_write_text("c");

			// Refresh graph.
			ssd1306_draw_graph(0, 1, BUFFER_SIZE, 3, temperature);
		}
		else if (app_mode == 1)
		{
			sprintf(value_disp, "%lu", 100 - (adc_value * 100 / 4096));
			ssd1306_set_column_address(98);
			ssd1306_write_command(SSD1306_CMD_SET_PAGE_START_ADDRESS(0));
			ssd1306_write_text(" ");
			ssd1306_write_text(value_disp);
			ssd1306_write_text("%");

			// Refresh graph.
			ssd1306_draw_graph(0, 1, BUFFER_SIZE, 3, light);
		}
		else
		{
			// Is card has been inserted or removed?
			if (sd_status_update == 1)
			{
				// Clear screen.
				ssd1306_clear();
				ssd1306_set_page_address(0);
				ssd1306_set_column_address(0);

				// Show SD card info.
				display_sd_info();

				sd_status_update = 0;
			}

		}

		/* Wait and stop screen flickers. */
		delay_ms(50);
	}
}
示例#19
0
/**
 *  \brief ACC example application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint8_t uc_key;
	int16_t s_volt = 0;
	uint32_t ul_value = 0;
	volatile uint32_t ul_status = 0x0;
	int32_t l_volt_dac0 = 0;

	/* Initialize the system */
	sysclk_init();
	board_init();

	/* Initialize debug console */
	configure_console();

	/* Output example information */
	puts(STRING_HEADER);

	/* Initialize DACC */
	/* Enable clock for DACC */
	pmc_enable_periph_clk(ID_DACC);
	/* Reset DACC registers */
	dacc_reset(DACC);
	/* External trigger mode disabled. DACC in free running mode. */
	dacc_disable_trigger(DACC);
	/* Half word transfer mode */
	dacc_set_transfer_mode(DACC, 0);
	/* Power save:
	 * sleep mode  - 0 (disabled)
	 * fast wake-up - 0 (disabled)
	 */
	dacc_set_power_save(DACC, 0, 0);
	/* Timing:
	 * refresh        - 0x08 (1024*8 dacc clocks)
	 * max speed mode -    0 (disabled)
	 * startup time   - 0xf (960 dacc clocks)
	 */
	dacc_set_timing(DACC, 0x08, 0, 0xf);
	/* Disable TAG and select output channel DACC_CHANNEL */
	dacc_set_channel_selection(DACC, DACC_CHANNEL_0);
	/* Enable output channel DACC_CHANNEL */
	dacc_enable_channel(DACC, DACC_CHANNEL_0);
	/* Setup analog current */
	dacc_set_analog_control(DACC, DACC_ANALOG_CONTROL);

	/* Set DAC0 output at ADVREF/2. The DAC formula is:
	 *
	 * (5/6 * VOLT_REF) - (1/6 * VOLT_REF)     volt - (1/6 * VOLT_REF)
	 * ----------------------------------- = --------------------------
	 *              MAX_DIGITAL                       digit
	 *
	 * Here, digit = MAX_DIGITAL/2
	 */
	dacc_write_conversion_data(DACC, MAX_DIGITAL / 2);
	l_volt_dac0 = (MAX_DIGITAL / 2) * (2 * VOLT_REF / 3) / MAX_DIGITAL +
			VOLT_REF / 6;

	/* Initialize ADC */
	/* Enable clock for ADC */
	pmc_enable_periph_clk(ID_ADC);
	/*
	 * Formula: ADCClock = MCK / ( (PRESCAL+1) * 2 )
	 * For example, MCK = 64MHZ, PRESCAL = 4, then:
	 *     ADCClock = 64 / ((4+1) * 2) = 6.4MHz;
	 */
	adc_init(ADC, sysclk_get_cpu_hz(), ADC_CLOCK, ADC_STARTUP_TIME_SETTING);

	/* Formula:
	 *     Startup  Time = startup value / ADCClock
	 *     Transfer Time = (TRANSFER * 2 + 3) / ADCClock
	 *     Tracking Time = (TRACKTIM + 1) / ADCClock
	 *     Settling Time = settling value / ADCClock
	 * For example, ADC clock = 6MHz (166.7 ns)
	 *     Startup time = 512 / 6MHz = 85.3 us
	 *     Transfer Time = (1 * 2 + 3) / 6MHz = 833.3 ns
	 *     Tracking Time = (0 + 1) / 6MHz = 166.7 ns
	 *     Settling Time = 3 / 6MHz = 500 ns
	 */
	/* Set ADC timing */
	adc_configure_timing(ADC, ADC_TRACK_SETTING, ADC_SETTLING_TIME_3,
			ADC_TRANSFER_SETTING);

	/* Channel 5 has to be compared */
	adc_enable_channel(ADC, ADC_CHANNEL_5);

	//! [acc_enable_clock]
	/** Enable clock for ACC */
	pmc_enable_periph_clk(ID_ACC);
	//! [acc_enable_clock]

	//! [acc_init]
	/** Initialize ACC */
	acc_init(ACC, ACC_MR_SELPLUS_AD5, ACC_MR_SELMINUS_DAC0,
			ACC_MR_EDGETYP_ANY, ACC_MR_INV_DIS);
	//! [acc_init]

	//! [acc_irq_enable]
	/** Enable ACC interrupt */
	NVIC_EnableIRQ(ACC_IRQn);

	/** Enable */
	acc_enable_interrupt(ACC);
	//! [acc_irq_enable]

	dsplay_menu();

	while (1) {
		while (uart_read(CONSOLE_UART, &uc_key)) {
		}

		printf("input: %c\r\n", uc_key);

		switch (uc_key) {
		case 's':
		case 'S':
			printf("Input DAC0 output voltage (%d~%d mv): ",
					(VOLT_REF / 6), (VOLT_REF * 5 / 6));
			s_volt = get_input_voltage();
			puts("\r");

			if (s_volt > 0) {
				l_volt_dac0 = s_volt;
				/* The DAC formula is:
				 *
				 * (5/6 * VOLT_REF) - (1/6 * VOLT_REF)     volt - (1/6 * VOLT_REF)
				 * ----------------------------------- = --------------------------
				 *              MAX_DIGITAL                       digit
				 *
				 */
				ul_value = ((s_volt - (VOLT_REF / 6))
					* (MAX_DIGITAL * 6) / 4) / VOLT_REF;
				dacc_write_conversion_data(DACC, ul_value);
				puts("-I- Set ok\r");
			} else {
				puts("-I- Input voltage is invalid\r");
			}
			break;
		case 'v':
		case 'V':
			/* Start conversion */
			adc_start(ADC);
			ul_status = adc_get_status(ADC);
			while ((ul_status & ADC_ISR_EOC5) != ADC_ISR_EOC5) {
				ul_status = adc_get_status(ADC);
			}
			/* Conversion is done */
			ul_value = adc_get_channel_value(ADC, ADC_CHANNEL_5);

			/*
			 * Convert ADC sample data to voltage value:
			 * voltage value = (sample data / max. resolution) * reference voltage
			 */
			s_volt = (ul_value * VOLT_REF) / MAX_DIGITAL;
			printf("-I- Voltage on potentiometer(AD5) is %d mv\n\r", s_volt);
			printf("-I- Voltage on DAC0 is %ld mv \n\r", (long)l_volt_dac0);
			break;
			
		case 'm':
		case 'M':
			dsplay_menu();
			break;
		}
	}
}
示例#20
0
/**
 * \brief Example entry point.
 *
 * Initialize ADC to 12-bit, enable channel "ADC_CHANNEL_POTENTIOMETER", then
 * enable hardware trigger with TIOA0 every second. Finally, start conversion.
 *
 * \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint8_t c_choice;
	int16_t s_adc_value;
	int16_t s_threshold = 0;

	/* Initialize the SAM system. */
	sysclk_init();
	board_init();


	configure_console();

	/* Output example information. */
	puts(STRING_HEADER);

	/* Initialize threshold. */
	gs_us_low_threshold = 0x0;
	gs_us_high_threshold = MAX_DIGITAL;

	/* Enable peripheral clock. */
	pmc_enable_periph_clk(ID_ADC);
	/* Initialize ADC. */
	/* startup = 10:    640 periods of ADCClock
	 * for prescale = 4
	 *     prescale: ADCClock = MCK / ( (PRESCAL+1) * 2 ) => 64MHz / ((4+1)*2) = 6.4MHz
	 *     ADC clock = 6.4 MHz
	 */
	adc_init(ADC, sysclk_get_cpu_hz(), 6400000, 10);
#if SAM3S ||  SAM3XA || SAM4S
	adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
#elif SAM3N
	adc_configure_timing(ADC, 0);
#endif
	adc_check(ADC, sysclk_get_cpu_hz());

	/* Hardware trigger TIOA0. */
	adc_configure_trigger(ADC, ADC_TRIG_TIO_CH_0, 0);
	/* Enable channels for x,y and z. */
	adc_enable_channel(ADC, ADC_CHANNEL_POTENTIOMETER);

	/* Configure TC. */
	configure_tc0();

	/* Channel 5 has to be compared. */
	adc_set_comparison_channel(ADC, ADC_CHANNEL_POTENTIOMETER);
	/* Compare mode, in the window. */
	adc_set_comparison_mode(ADC, ADC_EMR_CMPMODE_IN);

	/* Set up Threshold. */
	adc_set_comparison_window(ADC, gs_us_high_threshold, gs_us_low_threshold);

	/* Enable ADC interrupt. */
	NVIC_EnableIRQ(ADC_IRQn);

	/* Start TC0 and hardware trigger. */
	tc_start(TC0, 0);

	/* Display main menu. */
	display_menu();

	while (1) {
		while (uart_read(CONSOLE_UART, &c_choice)) {
		}
		printf("%c\r\n", c_choice);

		switch (c_choice) {
		case '0':
			s_adc_value = adc_get_channel_value(ADC,
					ADC_CHANNEL_POTENTIOMETER);
			printf("-I- Current voltage is %d mv, %d%% of ADVREF\n\r",
			(s_adc_value * VOLT_REF / MAX_DIGITAL), (s_adc_value * 100 / MAX_DIGITAL));
			break;

		case '1':
			puts("Low threshold is set to(mv):");
			s_threshold = get_voltage();
			puts("\r");

			if (s_threshold >= 0) {
				s_adc_value = s_threshold * MAX_DIGITAL /
						VOLT_REF;
				adc_set_comparison_window(ADC, s_adc_value,
						gs_us_high_threshold);
				/* Renew low threshold. */
				gs_us_low_threshold = s_adc_value;
				float f_low_threshold = (float)gs_us_low_threshold * VOLT_REF / MAX_DIGITAL;
				uint32_t ul_low_threshold = f_to_int(f_low_threshold);
				printf("Setting low threshold to %u mv (reg value to 0x%x ~%d%%)\n\r",
						ul_low_threshold,
						gs_us_low_threshold,
						gs_us_low_threshold * 100 / MAX_DIGITAL);
			}
			break;

		case '2':
			puts("High threshold is set to(mv):");
			s_threshold = get_voltage();
			puts("\r");

			if (s_threshold >= 0) {
				s_adc_value = s_threshold * MAX_DIGITAL /
						VOLT_REF;
				adc_set_comparison_window(ADC, gs_us_low_threshold,
						s_adc_value);
				/* Renew high threshold. */
				gs_us_high_threshold = s_adc_value;
				float f_high_threshold = (float)gs_us_high_threshold * VOLT_REF / MAX_DIGITAL;
				uint32_t ul_high_threshold = f_to_int(f_high_threshold);
				printf("Setting high threshold to %u mv (reg value to 0x%x ~%d%%)\n\r",
						ul_high_threshold,
						gs_us_high_threshold,
						gs_us_high_threshold * 100 / MAX_DIGITAL);
			}
			break;
		case '3':
			puts("-a. Below low threshold.\n\r"
					"-b. Above high threshold.\n\r"
					"-c. In the comparison window.\n\r"
					"-d. Out of the comparison window.\n\r"
					"-q. Quit the setting.\r");
			c_choice = get_comparison_mode();
			adc_set_comparison_mode(ADC, c_choice);
			printf("Comparison mode is %c.\n\r", 'a' + c_choice);
			break;

		case 'm':
		case 'M':
			display_menu();
			break;

		case 'i':
		case 'I':
			display_info();
			break;

		case 's':
		case 'S':
			enter_asleep();
			break;
		}
		puts("Press \'m\' or \'M\' to display the main menu again!\r");
	}
}