|
我使用attiny45 的ADC进行转换,用debugwire单步调试时,AD转换值正确,但是连续执行时,发现程序不正确,好像ADC的输入没有反应似的。程序如下(使用timer0的compare a触发ADC,用ADC自己触发也试过,同样的问题)。
#include <avr/io.h>
#include <avr/interrupt.h>
#define PWR_CTRL_BIT PB2
#define SW_CTRL_BIT PB4
#define PWR_CTRL (_BV(PWR_CTRL_BIT))
#define SW_CTRL (_BV(SW_CTRL_BIT))
void init_adc(void)
{
ADMUX |= 0x93; //2.56V as ref, no external cap, ADC3 as input
ADCSRB |= 0x03; //timer0 compare match A as trigger source
DIDR0 |= 0x3F; //to reduce power consumption
ADCSRA |= _BV(ADEN) |_BV(ADATE) | _BV(ADIE) | 0x03; //enable adc, auto trigger , enable interrupt , 8 as prescaler, run as 125khz
sei();
}
//adc trigger source
void init_timer0(void)
{
GTCCR = 0x10; //timer synchronization mode
TCCR0A = 0x02; //ctc mode
TCCR0B = 0x02; //8 as prescaler, run as 125khz
OCR0A = 124; //125k/125 = 1khz as sampling rate
GTCCR = 0x00; //start counting
}
//osc source for sw_ctrl
void init_timer1(void)
{
}
void init_ports(void)
{
PORTB &= ~(PWR_CTRL | SW_CTRL);
DDRB |= (PWR_CTRL | SW_CTRL);
}
void init_device(void)
{
init_ports();
init_timer0();
init_timer1();
init_adc();
}
ISR(ADC_vect)
{
int value;
value = ((ADCH << 8) | (ADCL));
PORTB |= SW_CTRL;
#if 1
if (value > 0x60)
PORTB |= PWR_CTRL;
else
PORTB &= ~PWR_CTRL;
#endif
#if 0
for (int i = 0; i < 8; i++)
{
if (value & 0x80)
PORTB |= PWR_CTRL;
else
PORTB &= ~PWR_CTRL;
value <<= 1;
}
#endif
PORTB &= ~SW_CTRL;
TIFR |= _BV(OCF0A);
}
void WDT_off(void)
{
MCUSR = 0x00;
WDTCR |= (1 << WDCE) | (1 << WDE);
WDTCR = 0x00;
}
int main(void)
{
/* Replace with your application code */
WDT_off();
init_device();
while (1)
{
// PORTB |= _BV(PB2);
// PORTB &= ~_BV(PB2);
}
}
通过示波器观察PWR_CTRL上的波形得出上述结论。请问这是什么问题,小弟感谢万分。
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|