Цитата(Herz @ Aug 19 2010, 13:21)

У меня три таких АЦП работают параллельно по прерыванию. По включению синхронизирую, затем никаких сбоев не наблюдается. По первому фронту запускаю таймер, затем по прерыванию от таймера считываю данные программным SPI. Наверное, можно и по-другому, но пока устраивало. (А интерфейс и вправду кривоват. Но это ещё цветочки.

) Вот, на всякий случай, кусочек кода:
Untitled.c.txt ( 1.06 килобайт )
Кол-во скачиваний: 196По фронту?! Это же ждать секцию данный 24+6+6 клоков АЦП
Я стартую по спаду - мне ждать приходится 6+6 клоков АЦП.
В вобщем, у Вас тоже по таймеру.
Ниже мой код, который я оптимизировал для связки 6МГц АЦП и 16 МГц Atmega.
// Случилось прерывание от АЦП
// В переменной adr_sector храним текущее положение в массиве Sector[]
// счетчик dac_cnt инкрементируем в ассемблере
// Заработало после Vref=2.5В, Int1-по спаду, дополнительная задержка 1 мкС.
// Длительностьт процедуры сбора 24 бит АЦП - 64 мкС. (15,625 кГц) 6.0 Mhz
//-----------------------------------------------------------------------------
interrupt[EXT_INT1] void ext_int1_isr(void)
{
#asm
cli;
push r0; cnt byte counter
push r1; mask
push r2; read from DAC
push r3; keep SREG
push r26; store data at memory address R26:R27
push r27;
push R30; tmp
in r3, SREG;
// Test Section*****************************
// cbi 0x15,6; Port C6=0 during int0
// End test section************************
ldi r30,0x05; Задержка ~1 мкс (для 16 MHz Clk)
MT: dec r30
brpl MT;
//
lds r30, _dac_cnt;
cpi r30,0x18; не более 24 измерений на фазу перемагничивания
brpl M3;
ldi R30,0x00; Перестроить D3 на прием данных
out 0x3B, R30; GICR=0x00 (запретить прерывания)
lds R26, _adr_sector ; Загрузить адрес сектора куда производится запись
lds R27, _adr_sector+1; Содержимое переменной adr_sector в регистр X
//; Запомнить маркер данных
lds r2, _data_id; идентификатор данных (загрузить из ОЗУ, _data_id - адрес ячейки ОЗУ)
st X+,r2 ; Save byte to RAM variable Sector[] and increment addres
//; Запомнить значение таймера
in r2, 0x32; сохранить текущее состояние таймера TCNT0 0x32(0x52)
st X+,r2; Save byte from DAC to RAM variable Sector[] and increment addres
//; готовимся к опросу АЦП
ldi R30, LOW(0x03);
mov R0,R30; ldi r0, 0x03 ; byte counter (24 бита =3 байта)
ldi R30,0x80; prepare mask for next byte
mov r1,R30; r1=0x80 Данные летят со СТАРШЕГО бита
clr r2; prepere r2 for read from DAC
M0: sbi 0x12,2; ___|---- PORTD.2=1 SCLK Up smd only
nop;
sbic 0x10,3; пропустить след команду если PIND.3=0 (bit from ADC) smd only
or r2,r1; r2 = r2 | r1 формируем байт
cbi 0x12,2; ----|___ PORTD.2=0 SCLK Down smd only (Здесь ADC меняет выходной бит)
clc; сбросить флаг переноса carry=0;
ror r1; next bit
brcs M1; brunch if carry (this byte done)
rjmp M0; go to next bit
M1: st X+,r2; Save byte from ADC to RAM variable Sector[] and increment addres
mov r1,R30; prepare mask=0x80 for next byte
dec r0; next byte
brbs 1, M2; jmp if SREG.Z=1 (zero)
clr r2; prepare for next byte
rjmp M0; next byte
//; Сохранить текущий адрес X в переменной
M2: sts _adr_sector, R26; save the last data address to memory for next call
sts _adr_sector+1,R27;
lds r2, _dac_cnt; Отметим запись, иначе произойдет переполнение
inc r2;
sts _dac_cnt, r2;
ldi R30,0x80; Перестроить D2 на обработку int1 smd only
out 0x3B, R30; GICR=0x80
//Test Section****************************
//sbi 0x15,6; Port C6=1 during int0
//End test section************************
M3: ldi R30,0xFF;
out 0x3A, R30; GIFR сбросим флаг int1 , он запомнилься пока "скакали" данные
out SREG, r3;
pop r30;
pop r27;
pop r26;
pop r3;
pop r2;
pop r1;
pop r0;
sei;
#endasm
#asm("nop")
}