📄 adc_c.htm
字号:
TCCR0B = (0<<FOC0A) | (0<<FOC0B) | // No force output compare A or B.
(0<<WGM02) | // Mode 2 - clear timer on compare match.
CSPS; // Timer clock prescale -- see above.
// Set the timer/counter0 interrupt masks.
TIMSK = (1<<OCIE0A) | // Interrupt on compare match A.
(0<<OCIE0B) | // No interrupt on compare match B.
(0<<TOIE0); // No interrupt on overflow.
// Set the compare match A value which initiates an ADC sample.
OCR0A = CRVALUE;
#endif // __AVR_ATtiny45__ || __AVR_ATtiny85__
#if defined(__AVR_ATmega8__)
// Set timer/counter0 control register.
TCCR0 = CSPS; // Timer clock prescale -- see above.
// Clear any pending interrupt.
TIFR |= (1<<TOV0); // Interrupt on overflow.
// Set the timer/counter0 interrupt masks.
TIMSK |= (1<<TOIE0); // Interrupt on overflow.
#endif // __AVR_ATmega8____
#if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
// Set timer/counter0 control register A.
TCCR0A = (0<<COM0A1) | (0<<COM0A0) | // Disconnect OCOA.
(0<<COM0B1) | (0<<COM0B0) | // Disconnect OCOB.
(1<<WGM01) | (0<<WGM00); // Mode 2 - clear timer on compare match.
// Set timer/counter0 control register B.
TCCR0B = (0<<FOC0A) | (0<<FOC0B) | // No force output compare A or B.
(0<<WGM02) | // Mode 2 - clear timer on compare match.
CSPS; // Timer clock prescale -- see above.
// Set the timer/counter0 interrupt masks.
TIMSK0 = (1<<OCIE0A) | // Interrupt on compare match A.
(0<<OCIE0B) | // No interrupt on compare match B.
(0<<TOIE0); // No interrupt on overflow.
// Set the compare match A value which initiates an ADC sample.
OCR0A = CRVALUE;
#endif // __AVR_ATmega88__ || __AVR_ATmega168__
}
#if defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
SIGNAL(SIG_OUTPUT_COMPARE0A)
// Handles timer/counter0 compare match A.
{
// Increment the timer when positions are being sampled.
if (adc_channel == ADC_CHANNEL_POSITION) timer_increment();
}
#endif // __AVR_ATtiny45__ || __AVR_ATtiny85__ || __AVR_ATmega88__ || __AVR_ATmega168__
#if defined(__AVR_ATmega8__)
SIGNAL(SIG_OVERFLOW0)
// Handles timer/counter0 overflow. This interrupts initiates the next
// ADC sample and assumes that the ADC sample will complete before the
// next timer overflow interrupt.
{
// Increment the timer when positions are being sampled.
if (adc_channel == ADC_CHANNEL_POSITION) timer_increment();
// Initiate an ADC sample.
ADCSRA = (1<<ADEN) | // Enable ADC.
(1<<ADSC) | // Start the first conversion.
(0<<ADFR) | // Free running disabled.
(1<<ADIF) | // Clear any pending interrupt.
(1<<ADIE) | // Activate ADC conversion complete interrupt.
ADPS; // Prescale -- see above.
// Reset the counter value to initiate another ADC sample at the specified time.
TCNT0 = 256 - CRVALUE;
}
#endif // __AVR_ATmega8__
SIGNAL(SIG_ADC)
// Handles ADC interrupt.
{
// Read the 10-bit ADC value.
uint16_t new_value = ADCW;
// Which channel is being read?
switch (adc_channel)
{
case ADC_CHANNEL_POSITION:
// Save the new position value.
adc_position_value = new_value;
// Flag the position value as ready.
adc_position_ready = 1;
// Switch to power for the next reading.
adc_channel = ADC_CHANNEL_POWER;
#if defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
// Set the ADC multiplexer selection register.
ADMUX = (0<<REFS2) | (0<<REFS1) | (0<<REFS0) | // Select VCC as voltage reference.
(0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0) | // Select ADC0 (PB5), no gain.
(0<<ADLAR); // Keep high bits right adjusted.
// Start the ADC of the power channel now
ADCSRA |= (1<<ADSC);
#endif
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
// Set the ADC multiplexer selection register.
ADMUX = (0<<REFS1) | (1<<REFS0) | // Select AVCC as voltage reference.
(0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0) | // Select ADC0 (PC0) as analog input.
(0<<ADLAR); // Keep high bits right adjusted.
// Start the ADC of the power channel now
ADCSRA |= (1<<ADSC);
#endif
break;
case ADC_CHANNEL_POWER:
// Save the new power value.
adc_power_value = new_value;
// Flag the power value as ready.
adc_power_ready = 1;
#if defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
// Switch to position for the next reading.
adc_channel = ADC_CHANNEL_POSITION;
// Set the ADC multiplexer selection register.
ADMUX = (0<<REFS2) | (0<<REFS1) | (0<<REFS0) | // Select VCC as voltage reference.
(0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (1<<MUX0) | // Select ADC3 (PB3), no gain.
(0<<ADLAR);
break;
#endif
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
if (adc_voltage_needed)
{
// Switch to voltage for the next reading.
adc_channel = ADC_CHANNEL_VOLTAGE;
// Set the ADC multiplexer selection register.
ADMUX = (0<<REFS1) | (1<<REFS0) | // Select AVCC as voltage reference.
(0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0) | // Select ADC1 (PC1) as analog input.
(0<<ADLAR); // Keep high bits right adjusted.
// Start the ADC of the voltage channel now
ADCSRA |= (1<<ADSC);
}
else
{
// Switch to position for the next reading.
adc_channel = ADC_CHANNEL_POSITION;
// Set the ADC multiplexer selection register.
ADMUX = (0<<REFS1) | (1<<REFS0) | // Select AVCC as voltage reference.
(0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0) | // Select ADC2 (PC2) as analog input.
(0<<ADLAR); // Keep high bits right adjusted.
}
break;
case ADC_CHANNEL_VOLTAGE:
// Remove flag
adc_voltage_needed = 0;
// Save voltage value to registers
registers_write_word(REG_VOLTAGE_HI, REG_VOLTAGE_LO, new_value);
// Switch to position for the next reading.
adc_channel = ADC_CHANNEL_POSITION;
// Set the ADC multiplexer selection register.
ADMUX = (0<<REFS1) | (1<<REFS0) | // Select AVCC as voltage reference.
(0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0) | // Select ADC2 (PC2) as analog input.
(0<<ADLAR); // Keep high bits right adjusted.
break;
#endif
}
}
</PRE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -