AndreyVN 0 18 августа, 2010 Опубликовано 18 августа, 2010 · Жалоба Всем привет, работаю с ADS 1252, при работе на васокой скорости (6МГц CLK ADS1252) в программе опроса запрограмировал прерывание по спаду, затем подобрал задержку до цикла DOUT и успешно вычитываю 24 бит данных (см. картинку). Теперь подвернулась задачка типа вольтметра, в которой ADS1252 работает на низкой, причем перестраиваемой скорости, вариант с задержкой выглядит некрасиво. Вот и задумался, с какой целью производитель сделал такую хитрую прелюдию к считыванию данных? И как правильнее всего организовать программу опроса? Пробовал обрабатвать каждое второе прерыывание - получается фигня, видимо при подаче питания DOUT/DRDY может немного попрыгать произвольно отчего сбивается "каждый второй". С привязкой к таймеру для измерения интервалов: 6clk нолик, 6clk единичка, вычитываниеданных - получается слишком сложно, пока не смог отладить программу. Может есть простой и эффективный вариант? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Herz 6 19 августа, 2010 Опубликовано 19 августа, 2010 · Жалоба У меня три таких АЦП работают параллельно по прерыванию. По включению синхронизирую, затем никаких сбоев не наблюдается. По первому фронту запускаю таймер, затем по прерыванию от таймера считываю данные программным SPI. Наверное, можно и по-другому, но пока устраивало. (А интерфейс и вправду кривоват. Но это ещё цветочки. ) Вот, на всякий случай, кусочек кода: Untitled.c.txt Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AndreyVN 0 19 августа, 2010 Опубликовано 19 августа, 2010 · Жалоба У меня три таких АЦП работают параллельно по прерыванию. По включению синхронизирую, затем никаких сбоев не наблюдается. По первому фронту запускаю таймер, затем по прерыванию от таймера считываю данные программным SPI. Наверное, можно и по-другому, но пока устраивало. (А интерфейс и вправду кривоват. Но это ещё цветочки. ) Вот, на всякий случай, кусочек кода: Untitled.c.txt По фронту?! Это же ждать секцию данный 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") } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Herz 6 19 августа, 2010 Опубликовано 19 августа, 2010 · Жалоба По фронту?! Это же ждать секцию данный 24+6+6 клоков АЦП Я стартую по спаду - мне ждать приходится 6+6 клоков АЦП. По заднему фронту. Не знаю, для чего у Вас такой сложный код, лень было разобраться. В конце концов, какая разница, сколько ждать - всё равно приём данных происходит по прерыванию. Во время ожидания прерывания от таймера можно продолжать заниматься чем угодно. При смене частоты тактирования нужно лишь автоматом менять и предустановку таймера. И никакого асм-а. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AndreyVN 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба По заднему фронту. Не знаю, для чего у Вас такой сложный код, лень было разобраться. В конце концов, какая разница, сколько ждать - всё равно приём данных происходит по прерыванию. Во время ожидания прерывания от таймера можно продолжать заниматься чем угодно. При смене частоты тактирования нужно лишь автоматом менять и предустановку таймера. И никакого асм-а. Да нет, сам опрос занимает строчек 10, остальное - всякие метки времени, и прочая необходимая ерунда. Проблему "переменной скорости" опроса решил подсчетом клоков ADS1252 на 12 клоков необходимо отсчитать 24 изменения состояния тактирования АЦП. Теперь какую скорость не настрой, данные вычитываются в нужное время. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Herz 6 22 августа, 2010 Опубликовано 22 августа, 2010 · Жалоба Тоже правильно, если есть доступ к сигналу тактирования. У меня его не было. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться