Я понимаю, что не очень красиво выкладывать в форуме целые проги.
Есть предложение: может отдельный Topic открыть или по E-mail общаться?
Но пока представляю вашему вниманию следующее. Это я уже написал для Tiny26 с учетом его особенностей. B) С нетерпением жду комментариев. И вообще, будет ли это работать. От идеи с 6-преобразованиями пришлось отказаться по причине нехватки линий. Жалко, конечно
, но не принципиально. Почему не COM я уже говорил. К вопросам прибавлю, если, например с PB0 выдавать подсветку, о том что результат готов это скажется на загадочном PinChange?
Итак, прога:
/*
В проге используется ADC контроллера Tiny26 для
АЦП напряжений по трем каналам (ADC7,ADC8,ADC10).
По прерыванию от LPT (INT0) выбирается канал ADC.
По прерыванию Pin Change преобразованные 8-ми битные значения выдаются в порт A.
*/
#include
void port_init(void);
void init_devices(void);
void adc_init(void);
void main(void);
unsigned char counter; // счетчик импульсов для мультиплексора АЦП
unsigned char result;
///////////// programm /////////////////
void main(void)
{
init_devices();
ADCSR|=0x40; // start conversion bit6 = 1
while (1);
}
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
ADCSR = 0x00; //disable adc
counter++;
if (counter==1)
ADMUX = 0x27;//ADC7
goto exit;
if (counter==2)
ADMUX = 0x28;//ADC8
goto exit;
if (counter==3)
counter=0;
ADMUX = 0x2A;//ADC10
goto exit;
exit:
ADCSR = 0x8E;//1000 1110
GIMSK = 0x00;//запрет.IRQ пока нет рез-та АЦП
ADCSR|=0x40;//запустить АЦП
}
interrupt [PIN_CHANGE] void pin_change_isr(void)
{
// Read the 8 most significant bits
// of the AD conversion result
result=ADCH; // 8-ми битный результат
PORTA=result;// отправить в порт A
GIMSK = 0x00;//запретить IRQ пока не вып-ся АЦП
ADCSR|=0x40;// запустить АЦП
}
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
GIMSK = 0xc0; //Enable INT0,
//ChangePin PB3:0
//Disable PB7:4;PA7:6;PA3;
//разрешаем IRQ т.к.резульат уже есть
}
////////// initialization /////////////
void init_devices(void)
{
counter = 0; //обнуление счетчика
#asm("CLI"); //disable all interrupts
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFh
// OC1A output: Disconnected
// OC1B output: Disconnected
PLLCSR=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1=0x00;
OCR1A=0x00;
OCR1B=0x00;
OCR1C=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
// INT0 Mode: Rising Edge
// Interrupt on any change on pins PA3, PA6, PA7 and PB4-7: Off
// Interrupt on any change on pins PB0-3: On
MCUCR=0x03;//00000011(Rising INT0)
GIFR=0x60;//01100000(разрешаем прерывания)
port_init();
adc_init();
GIMSK = 0x00; // запрещаем внешние IRQ, чтобы не переключать MUX ока не выполнится преобразование(0x50 (01010000)разрешаем)
#asm("SEI"); //re-enable interrupts
}
void port_init(void)
{
PORTA=0x00;
DDRA=0xFF;
PORTB=0x00;
DDRB=0x00;
}
void adc_init(void)
{
// ADC Clock frequency: 62,500 kHz
// ADC Voltage Reference: AVCC pin
// Only the 8 most significant bits of
// the AD conversion result are used
ADCSR = 0x00; //disable adc
ADMUX = 0x27; //select adc input 0 (PA0)0*20
//00 - REF = AVCC
//1 - 8 BIT
//27=00100111 - ADC7; 28=00101000 - ADC8; 2A=00101010 - ADC10;
ADCSR = 0x8E;//1000 1110
/*
Bit 7 - ADEN: Enabled ADC
Bit 6 - ADSC: Start ADC (у меня Stop)
Bit 5 - ADFR: Non FreeRun
Bit 4 - ADIF: Interrupt Flag "1" - reset flag if "1" set
Bit 3 - ADIE: Enabled Interrupt
Bits 2..0 - ADPS2..ADPS0: Prescaler 4000/64=62.5kHz
*/
}