|
прошу помощи по AD7794/7795, Проблема интерфейса |
|
|
|
Mar 12 2013, 15:14
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 12-03-13
Пользователь №: 75 988

|
Не получается найти общий язык с АЦПехой AD7795... =( Вроде и все последовательности с времянками соблюдаю, а простейшие ID (как признак связи) читать не получается. Выкладываю куски кода, прошу помочь найти основную ошибку. ЗЫ. Пишу на WinAVRе, чуть почистил код перед выпиской сюда... Код void ADC_SendByte( char Byte) { uint8_t mask; for (mask=0x80; mask; mask>>=1 ) { // +++++++++++++++++++++ Shift out Bits loop ADC_Set_CLK(0); _delay_us(100); ADC_Set_DIN( Byte & mask); _delay_us(100); ADC_Set_CLK(1); _delay_us(100); }; // --------------------- Shift out Bits loop ADC_Set_DIN(1);//после каждой передачи поднять Din ADC_Set_CLK(1); };
uint8_t ADC_GetByte( uint8_t *BytePtr) { uint8_t mask; uint8_t Byte = 0; for (mask=0x80; mask; mask>>=1 ) { // +++++++++++++++++++++ Shift out Bits loop ADC_Set_CLK(0); _delay_us(100); if ( ADC_Get_DOUT() ) Byte |= mask; _delay_us(100); ADC_Set_CLK(1); _delay_us(100); }; // --------------------- Shift out Bits loop ADC_Set_CLK(1); *BytePtr = Byte; return(1); };
void ADC_Init( ) { uint8_t ID; // ................................... Reset all ADCs ADC_SendByte( 0xFF ); ADC_SendByte( 0xFF ); ADC_SendByte( 0xFF); ADC_SendByte( 0xFF ); ///................................... Reset all ADCs _delay_us(500); ADC_SendByte(0x60); ADC_GetByte(&ID);
tstw("ID=",ID); //форматный вывод результата } На выходе получаю в лучщем случае 0. ЗЫ. Поиск юзал, темы читал, как вписано в ДШ делал, но не получается считать даже ID, про преобразования молчу... глянул тут http://electronix.ru/forum/index.php?showt...6&hl=ad7792 но не понял в каком смысле дернуть 32 раза? 32 раза моргнуть циклом 1/0 ногой Din?(32 еденицы, 32 нуля в итоге)
|
|
|
|
|
Mar 12 2013, 19:54
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
Цитата(StasUKR @ Mar 12 2013, 17:14)  Не получается найти общий язык с АЦПехой AD7795... =( глянул тут http://electronix.ru/forum/index.php?showt...6&hl=ad7792 но не понял в каком смысле дернуть 32 раза? 32 раза моргнуть циклом 1/0 ногой Din?(32 еденицы, 32 нуля в итоге) Ну вы и докопались, аж до темы 2006-го года  Тут, как и в любом другом деле, важна методология. 1. Убедитесь, что АЦП работает (по дефолту после сброса он вроде бы преобразовывает в цикле, это можно проверить по наличию импульсов на выводе RDY (нужен pull-up подтягивающий резистор!). Если нет импульсов- убедитесь по даташиту, что по ресету состояние регистров соответствует режиму преобразования, вдруг AD что-то поменял в этой модели. При этом обеспечьте неактивное состояние на SPI интерфейсе от включения и до конца эксперимента, вдруг Вы его куда-то загоняете и поэтому он не преобразовывает. 2. Только если первый уровень игры пройден- переходим ко второму. проверяем связь. Про сброс пачкой импульсов написано в даташите, страница Rev. D | Page 28 of 36: Цитата The serial interface can be reset by writing a series of 1s on the DIN input. If a Logic 1 is written to the AD7794/AD7795 line for at least 32 serial clock cycles, the serial interface is reset. This ensures that the interface can be reset to a known state if the interface gets lost due to a software error or some glitch in the system. Reset returns the interface to the state in which it is expecting a write to the communications register. This operation resets the contents of all registers to their power-on values. Following a reset, the user should allow a period of 500 μs before addressing the serial interface. Вот код из одного старенького проекта про AD7792 (приаттачить файл с расширением "с" не разрешает почему-то, так что прямо сюда и копирую. там даже выпиливание побитное есть закомментаренное, наверное с времен моих разборок осталось. CODE #include <pic18.h>
//#include "pic18cfg.h"
#include "deftype.h"
#include "ad7792_const.h" #include "PinDef.h" #include <always.h>
#include "var2_ext.h"
void delay_1ms(void); void delay_ms(int nms); u16 ADC_RequestData(u8 codeADCdev);
void delay_halphBit(void);
void initSPI (void); u8 SPI_tx8bit(u8 txData); u16 AD7792_RdReg16bit(u8 codeADCdev, u8 nReg); void AD7792_WrReg16bit(u8 codeADCdev, u8 nReg, u16 wrData); void AD7792_WrReg8bit(u8 codeADCdev, u8 nReg, u8 wrData); void delay_1us(void); void Ad7792_reset(void); void ADC_Init(void); void adc_StartCalibrZS(u8 codeADCdev); void adc_StartCalibrFS(u8 codeADCdev);
void ADC_Init(void) { u8 n; Ad7792_reset(); // delay_ms(20);
//TC_ALL AD7792_WrReg16bit(DEVCODE_TC_ALL, AD7792_REG_CONFIG, TC_CONFIG); AD7792_WrReg8bit (DEVCODE_TC_ALL, AD7792_REG_IO, TC_IO);
//TC1 AD7792_WrReg16bit(DEVCODE_TC1, AD7792_REG_CONFIG, TC_CONFIG_FOR_TC1);
AD7792_WrReg16bit(DEVCODE_TC_ALL, AD7792_REG_MODE, TC_MODE);
// delay_ms(300); /* //калибровка TC adc_StartCalibrZS(DEVCODE_TC1); adc_StartCalibrZS(DEVCODE_TC2); adc_StartCalibrZS(DEVCODE_TC3); adc_StartCalibrZS(DEVCODE_TC4); adc_StartCalibrZS(DEVCODE_TC5); delay_ms(1000); //время, которого точно хватит на калибровку adc_StartCalibrFS(DEVCODE_TC1); adc_StartCalibrFS(DEVCODE_TC2); adc_StartCalibrFS(DEVCODE_TC3); adc_StartCalibrFS(DEVCODE_TC4); adc_StartCalibrFS(DEVCODE_TC5); delay_ms(2000); //время, которого точно хватит на калибровку */ return; }
void ADC_Init2(void) { u8 n; Ad7792_reset();
//TC AD7792_WrReg16bit(DEVCODE_TC_ALL, AD7792_REG_CONFIG, TC_CONFIG);
AD7792_WrReg16bit(DEVCODE_TC1, AD7792_REG_CONFIG, TC_CONFIG_FOR_TC1);
AD7792_WrReg8bit (DEVCODE_TC_ALL, AD7792_REG_IO, TC_IO);
AD7792_WrReg16bit(DEVCODE_TC_ALL, AD7792_REG_MODE, TC_MODE);
return;
}
void Ad7792_reset(void) { u16 n; SPICS_TC1 = 0; SPICS_TC2 = 0; SPICS_TC3 = 0; SPICS_TC4 = 0; SPICS_TC5 = 0; SPICS_TC6 = 0; SPICS_TC7 = 0; SPICS_TC8 = 0; SPICS_TC9 = 0; SPICS_TC10= 0; SPICS_TC11= 0; SPICS_TC12= 0; SPICS_TC13= 0; SPICS_TC14= 0; SPICS_TC15= 0;
SPI_tx8bit(0xFF); SPI_tx8bit(0xFF); SPI_tx8bit(0xFF); SPI_tx8bit(0xFF); SPI_tx8bit(0xFF); SPICS_TC1 = 1; SPICS_TC2 = 1; SPICS_TC3 = 1; SPICS_TC4 = 1; SPICS_TC5 = 1; SPICS_TC6 = 1; SPICS_TC7 = 1; SPICS_TC8 = 1; SPICS_TC9 = 1; SPICS_TC10= 1; SPICS_TC11= 1; SPICS_TC12= 1; SPICS_TC13= 1; SPICS_TC14= 1; SPICS_TC15= 1;
for (n = 0; n < 500;n++) delay_1us(); //pause 500us for (n = 0; n < 500;n++) delay_1us(); //pause 500us
}
void initSPI (void) { //выключил все каналы встроенного АЦП PIC ADCON1 = 0b00000110;
TRISC3 = 0; TRISC4 = 1; TRISC5 = 0;
TRIS_SPICS_TC1 = 0; TRIS_SPICS_TC2 = 0; TRIS_SPICS_TC3 = 0; TRIS_SPICS_TC4 = 0; TRIS_SPICS_TC5 = 0; TRIS_SPICS_TC6 = 0; TRIS_SPICS_TC7 = 0; TRIS_SPICS_TC8 = 0; TRIS_SPICS_TC9 = 0; TRIS_SPICS_TC10 = 0; TRIS_SPICS_TC11 = 0; TRIS_SPICS_TC12 = 0; TRIS_SPICS_TC13 = 0; TRIS_SPICS_TC14 = 0; TRIS_SPICS_TC15 = 0; TRIS_SPICS_TC16 = 0;
SPICS_TC1 = 1; SPICS_TC2 = 1; SPICS_TC3 = 1; SPICS_TC4 = 1; SPICS_TC5 = 1; SPICS_TC6 = 1; SPICS_TC7 = 1; SPICS_TC8 = 1; SPICS_TC9 = 1; SPICS_TC10 = 1; SPICS_TC11 = 1; SPICS_TC12 = 1; SPICS_TC13 = 1; SPICS_TC14 = 1; SPICS_TC15 = 1; SPICS_TC16 = 1;
//тактовая SPICLK = TMR2 / 2 = 24 kHz
//TMR2 F= (Fosc /4)/4) / 96 = 2304000 /(pr2+1) Hz = 24 kHz T2CON = 0b00000101; //presc = 4 //тактовая SPICLK = (((( Fosc /4)/4) / 96))/2 = 12kHz
PR2 = 47;
//при прохождении через оптроны сигналы SPI (кроме CS) инвертируются. Меняем полярность на обратную.
//Также необходимо далее инвертировать биты данных, передаваемых/принимаемых через SPI. SSPSTAT = 0b00000000; SSPCON1 = 0b00100011; // TMR2out/2 = 12 kHz
}
void select_ADC_CS(u8 n) { // gie_off; switch (n) { case DEVCODE_TC1: SPICS_TC1 = 0; goto end; case DEVCODE_TC2: SPICS_TC2 = 0; goto end; case DEVCODE_TC3: SPICS_TC3 = 0; goto end; case DEVCODE_TC4: SPICS_TC4 = 0; goto end; case DEVCODE_TC5: SPICS_TC5 = 0; goto end; case DEVCODE_TC6: SPICS_TC6 = 0; goto end; case DEVCODE_TC7: SPICS_TC7 = 0; goto end; case DEVCODE_TC8: SPICS_TC8 = 0; goto end; case DEVCODE_TC9: SPICS_TC9 = 0; goto end; case DEVCODE_TC10: SPICS_TC10 = 0; goto end; case DEVCODE_TC11: SPICS_TC11 = 0; goto end; case DEVCODE_TC12: SPICS_TC12 = 0; goto end; case DEVCODE_TC13: SPICS_TC13 = 0; goto end; case DEVCODE_TC14: SPICS_TC14 = 0; goto end; case DEVCODE_TC15: SPICS_TC15 = 0; goto end; case DEVCODE_TC16: SPICS_TC16 = 0; goto end; case DEVCODE_TC_ALL: { SPICS_TC1 = 0; SPICS_TC2 = 0; SPICS_TC3 = 0; SPICS_TC4 = 0; SPICS_TC5 = 0; SPICS_TC6 = 0; SPICS_TC7 = 0; SPICS_TC8 = 0; SPICS_TC9 = 0; SPICS_TC10 = 0; SPICS_TC11 = 0; SPICS_TC12 = 0; SPICS_TC13 = 0; SPICS_TC14 = 0; SPICS_TC15 = 0; SPICS_TC16 = 0; goto end; } default: return; } end:; delay_halphBit(); delay_halphBit(); return; }
void unselect_ADC_CS(u8 n) { SPICS_TC1 = 1; SPICS_TC2 = 1; SPICS_TC3 = 1; SPICS_TC4 = 1; SPICS_TC5 = 1; SPICS_TC6 = 1; SPICS_TC7 = 1; SPICS_TC8 = 1; SPICS_TC9 = 1; SPICS_TC10 = 1; SPICS_TC11 = 1; SPICS_TC12 = 1; SPICS_TC13 = 1; SPICS_TC14 = 1; SPICS_TC15 = 1; SPICS_TC16 = 1; delay_halphBit(); delay_halphBit(); }
//Запись в 8-битный регистр void AD7792_WrReg8bit(u8 codeADCdev, u8 nReg, u8 wrData) { u8 tmp;
select_ADC_CS(codeADCdev); //запись в Communications Register tmp = (0<<7) //WEN |(0<<6) //R/W |((nReg&0x07)<<3) //RS2..RS0 |(0<<2); //CREAD
SPI_tx8bit(tmp); //запись данных в регистр SPI_tx8bit(wrData); unselect_ADC_CS(codeADCdev); }
//Запись в 16-битный регистр void AD7792_WrReg16bit(u8 codeADCdev, u8 nReg, u16 wrData) { u8 tmp;
select_ADC_CS(codeADCdev); //запись в Communications Register tmp = (0<<7) //WEN |(0<<6) //R/W |((nReg&0x07)<<3) //RS2..RS0 |(0<<2); //CREAD
SPI_tx8bit(tmp); //запись данных в регистр SPI_tx8bit((u8)(wrData>>8)); //MSB delay_halphBit();
SPI_tx8bit((u8)(wrData)); //LSB unselect_ADC_CS(codeADCdev); }
//чтение 16-битного регистра u16 AD7792_RdReg16bit(u8 codeADCdev, u8 nReg) { u8 tmp; u16_2u8 tmp16;
select_ADC_CS(codeADCdev);
//запись в Communications Register tmp = (0<<7) //WEN |(1<<6) //R/W |((nReg&0x07)<<3) //RS2..RS0 |(0<<2); //CREAD
SPI_tx8bit(tmp); //чтение данных (передается мусор) tmp16._u8[1] = SPI_tx8bit(0xFF); tmp16._u8[0] = SPI_tx8bit(0xFF);
unselect_ADC_CS(codeADCdev); return tmp16._u16; }
//чтение 8-битного регистра u8 AD7792_RdReg8bit(u8 codeADCdev, u8 nReg) { u8 tmp, tmp8H;
select_ADC_CS(codeADCdev);
//запись в Communications Register tmp = (0<<7) //WEN |(1<<6) //R/W |((nReg&0x07)<<3) //RS2..RS0 |(0<<2); //CREAD
SPI_tx8bit(tmp); //чтение данных (передается мусор) tmp8H = SPI_tx8bit(0x00);
unselect_ADC_CS(codeADCdev); return tmp8H; }
//передача байта в SPI //выход: принятый байт u8 SPI_tx8bit(u8 txData) { SSPIF = 0; SSPBUF = txData^0xff; ////при прохождении через оптроны сигналы SPI инвертируются.
while (SSPIF == 0); //ждем окончания передачи return SSPBUF ^ 0xff; //читаем принятый байт //при прохождении через оптроны сигналы SPI (кроме CS) инвертируются.
/* //выпиливаем побитно
u8 rxdata = 0; u8 txdata = txData^0xff; u8 n;
delay_1us(); delay_1us(); delay_1us(); delay_1us(); delay_1us();
for (n = 0; n < 8; n++) { delay_halphBit(); PIN_SCLK = 1; //прием rxdata = rxdata << 1; if (PIN_MISO != 0) rxdata = rxdata | 0x01; //передача delay_halphBit(); PIN_SCLK = 0; if ((txdata & 0x80)==0) PIN_MOSI=0; else PIN_MOSI=1; txdata = txdata << 1;
} return rxdata^0xff; */ }
void delay_halphBit(void) { //170us int n; for (n = 0; n < 50; n++) delay_1us(); }
void delay_1us(void) { #asm // nop; // nop; // nop; // nop nop; nop; nop; nop; nop; #endasm return; }
u16 ADC_RequestData(u8 codeADCdev) { u16_2u8 rez; delay_ms(5);
select_ADC_CS(codeADCdev); delay_ms(20);
//команда на старт АЦП SPI_tx8bit(0x08); SPI_tx8bit(0x20); //MSB SPI_tx8bit(0x0F); //LSB //пауза 0.5 сек. unselect_ADC_CS(codeADCdev);
delay_ms(1000); select_ADC_CS(codeADCdev); //команда на чтение данных SPI_tx8bit(0x58); //чтение данных (передается мусор) delay_ms(1); rez._u8[1] = SPI_tx8bit(0x00); delay_ms(1); rez._u8[0] = SPI_tx8bit(0x00);
delay_ms(1); SPI_tx8bit(0x58); delay_ms(1); rez._u8[1] = SPI_tx8bit(0x00); delay_ms(1); rez._u8[0] = SPI_tx8bit(0x00);
unselect_ADC_CS(codeADCdev); return rez._u16; }
//задержка на указанное кол-во ms void delay_1ms(void) { int n; for (n = 0; n < 420; n++) delay_1us(); return; }
//задержка на указанное кол-во ms void delay_ms(int nms) { int n; for (n = 0; n < nms; n++) delay_1ms(); return; }
//запуск калибровки Zero-Scale указанного АЦП void adc_StartCalibrZS(u8 codeADCdev) { AD7792_WrReg16bit(codeADCdev, AD7792_REG_MODE, TC_MODE_CALIBR_ZS); }
//запуск калибровки Full-Scale указанного АЦП void adc_StartCalibrFS(u8 codeADCdev) { AD7792_WrReg16bit(codeADCdev, AD7792_REG_MODE, TC_MODE_CALIBR_FS); }
extern void init_userTask(void); volatile u16 Debug2; volatile u16 Debug3; //проверка валидности конфигурации регистров АЦП и переинициализация, если нужно. void check_ADC_Regs(u8 codeADCdev) {
if (DEVCODE_TC1 == codeADCdev) { Debug2 = AD7792_RdReg16bit(codeADCdev, AD7792_REG_CONFIG); if (TC_CONFIG_FOR_TC1 != Debug2) {//вторая попытка чтения регистра Debug2 = AD7792_RdReg16bit(codeADCdev, AD7792_REG_CONFIG); Debug3 = AD7792_REG_CONFIG; if (TC_CONFIG_FOR_TC1 != Debug2) goto err; } } else { Debug2 = AD7792_RdReg16bit(codeADCdev, AD7792_REG_CONFIG); if (TC_CONFIG != Debug2) {//вторая попытка чтения регистра Debug2 = AD7792_RdReg16bit(codeADCdev, AD7792_REG_CONFIG); Debug3 = AD7792_REG_CONFIG; if (TC_CONFIG != Debug2) goto err; } } Debug2 = AD7792_RdReg8bit(codeADCdev, AD7792_REG_IO); if (TC_IO != Debug2) {//вторая попытка чтения регистра Debug2 = AD7792_RdReg8bit(codeADCdev, AD7792_REG_IO); Debug3 = AD7792_REG_IO; if (TC_IO != Debug2) goto err; }
return; //OK
//нужна переинициализация err:; nErr_ADC[codeADCdev] ++; // #asm // nop; // nop; // #endasm
ADC_Init(); init_userTask(); }
P.S. Кстати, бытует мнение, что техника работает лучше, если к ней относится как к чему-то разумному. Ну, не любит оно когда его как-то неуважительно или непривычно называют. У меня один знакомый процессор называет не иначе как "профессор", ну те и отвечают ему взаимностью. А на "АЦПху" оно и обидится может, вдруг у Вас тот самый случай, мстит оно Вам
|
|
|
|
|
Mar 13 2013, 08:33
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 12-03-13
Пользователь №: 75 988

|
Спасибо за ответ! Свое отношение к технике пересмотрю, не зря ведь однажды писал в начале кода комментарий с заговором от злых "кодовых духов" Кристал АЦП работает, дергает Din раз в 60мс... Прочесть ID (1 байт) не могу, на выходе 0 Переписал функцию ресета: Код void ADC_Id(void) { uint8_t ID; // ................................... Reset all ADCs ADC_Set_DIN(1); //Переводим Din в 1 _delay_us(30); for (uint8_t n=0; n<32; n++) { ADC_Set_CLK(0); _delay_us(100); ADC_Set_CLK(1); _delay_us(100); }; _delay_us(500); ADC_Set_DIN(0); //Переводим Din в 0 // ................................... Reset all ADCs ADC_SendByte(0x60); ADC_GetByte(&ID); tstw("ID=",ID);//форматированый вывод ID } еще пробовал после 32 клоков с Din=1 отпралять 4 бита по 0xFF(тот же сброс) перед 0x60...Безрезультатно, на выжоде 0... Функции ADC_GetByte, ADC_SendByte остались без изменений. Я ведь верно запрашиваю ID, 0x60 и чтение байта?
|
|
|
|
|
Mar 13 2013, 21:42
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
Цитата(StasUKR @ Mar 13 2013, 10:33)  Кристал АЦП работает, дергает Din раз в 60мс...
Прочесть ID (1 байт) не могу, на выходе 0 Еще не разобрались?  тогда по порядку: 0. Надеюсь, нога DVdd АЦП у Вас подключена к тому же питанию, что и процессор (то есть уровни согласованы) 1. Я так понял, Вы CS не дергаете, то есть он навсегда в ноль притянут? Я в этом режиме не работал, он мне кажется очень слабо устойчивым к помехам (нет синхронизации начала нового байта по CS). Для исключения поблем временно можете попробовать им все-таки дергать согласно даташиту (Rev. D | Page 9 of 36). То есть сбросили серией единиц, дальше CS=1, delay(1000 us), выход из инициализации. 2. 0x60 и потом чтение ID- это правильно. 3. про запрос на чтение ID: убедитесь в том, что передаете именно то что нужно. Интересно посмотреть на функцию "ADC_Set_DIN()", как Вы там внутри определяете ноль или единицу выставлять. Тут, конечно здорово бы помог цифровой осциллограф, запускающий развертку по спаду CS и показывающий развитие на выводах CLK и MOSI, Но можно и пошагово в отладчике, измерять тестером на выводе процессора, рисовать на бумаге. Там всего-то 2 байта пройти по клокам CLK, от спада CS=0 до окончания чтения (когда поставите CS=1) 4. Если запрос принят (сигнал дошел до ножек CS/DIN/CLK микросхемы АЦП, вдруг у вас там непропай какой-нибудь)- смотрите ответ, это второй байт в этом пакете. Чудес не бывает, где-то ошибку найдете. SPI шина тем и хороша, можно смотреть медленно и не спеша
|
|
|
|
|
Mar 14 2013, 07:07
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 12-03-13
Пользователь №: 75 988

|
Спасибо за ответ!!! Сейчас еду в командировку, по сему на плату глянуть не могу. Сегодня сквозь сон пробилась мысль о том, что вместо PINx=0xFE пишу PORTx=0xFE, что теоретически не опустит ногу FE в "0",тогда все становится на места, наверное Как только проверю - сразу же отпишусь... Спасибо
|
|
|
|
|
Mar 18 2013, 10:20
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 12-03-13
Пользователь №: 75 988

|
Цитата(Ruslan1 @ Mar 14 2013, 00:42)  Еще не разобрались?  тогда по порядку: 0. Надеюсь, нога DVdd АЦП у Вас подключена к тому же питанию, что и процессор (то есть уровни согласованы) 1. Я так понял, Вы CS не дергаете, то есть он навсегда в ноль притянут? Я в этом режиме не работал, он мне кажется очень слабо устойчивым к помехам (нет синхронизации начала нового байта по CS). Для исключения поблем временно можете попробовать им все-таки дергать согласно даташиту (Rev. D | Page 9 of 36). То есть сбросили серией единиц, дальше CS=1, delay(1000 us), выход из инициализации. 2. 0x60 и потом чтение ID- это правильно. 3. про запрос на чтение ID: убедитесь в том, что передаете именно то что нужно. Интересно посмотреть на функцию "ADC_Set_DIN()", как Вы там внутри определяете ноль или единицу выставлять. Тут, конечно здорово бы помог цифровой осциллограф, запускающий развертку по спаду CS и показывающий развитие на выводах CLK и MOSI, Но можно и пошагово в отладчике, измерять тестером на выводе процессора, рисовать на бумаге. Там всего-то 2 байта пройти по клокам CLK, от спада CS=0 до окончания чтения (когда поставите CS=1) 4. Если запрос принят (сигнал дошел до ножек CS/DIN/CLK микросхемы АЦП, вдруг у вас там непропай какой-нибудь)- смотрите ответ, это второй байт в этом пакете. Чудес не бывает, где-то ошибку найдете. SPI шина тем и хороша, можно смотреть медленно и не спеша  Спасибо за ответы, пока ID остается загадкой=( по пунктам: 0.DVdd АЦП подключена к тому же питанию, что и процессор, проверил 1.Как читал из форумов если дергать CS после ресета, теряется контакт и отвечает не верные данные... нужно сеанс чтения/записи с "0" вести, и только уже по необходимости его подымать обратно... Цитата Ruslan1 сделал как сказали - сразу заработало. хотя вчера всякие варианты пробовал.. Считалось число 0х4а что похоже на даташит. что следующим шагом предпринять ?
и почемуто два раза подряд не получается считать ID. не понимаю. UPD! понял вроде. я после чтения числа 0х4а поднимаю CS и повторная процедура не проходит, а если CS оставить опущенным и снова запросить ID то стабильно считывается 0х4а. Я правильно понимаю что на протяжении всей сессии общения с микрухой начиная от конфигурирования и на протяжении считывания регистра данных необходимо удерживать CS в активном опущенном состоянии ? и что если я вдруг подниму CS то потеряю интерфейсу ? 2.тут все Ок 3. ADC_Set_DIN() просто в #define задаю "if (Val)" и по 2-м разным Val пишу 2 состояния порта... осцилом проверял... 4. выдается постоянно разный результат.... ЗЫ, последнее сообщение было в утреннем бреду, порт CS пишу командочкой PORTx=0xFE..., проверил CS как надо... Не знаю в каком направлении еще глянуть=(((
|
|
|
|
|
Mar 19 2013, 11:53
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 12-03-13
Пользователь №: 75 988

|
Доброе время суток Пошагово проверил передачу 0x60 на порт, передается отлично, времянки соблюдены, но вот прочесть ничего не могу, сплошной 0 на Dout, при серии cинхроимпульсов на CLK... Почему AD7794 отвечает 0 на запрос 0x60? Спасибо Цитата(StasUKR @ Mar 19 2013, 14:30)  Доброе время суток
Пошагово проверил передачу 0x60 на порт, передается отлично, времянки соблюдены, но вот прочесть ничего не могу, сплошной 0 на Dout, при серии cинхроимпульсов на CLK...
Почему AD7794 отвечает 0 на запрос 0x60?
Спасибо да, вместо ответа на Dout , АЦП дергает Dout раз в 60мс... Получается АЦП не принял команду на чтение ID???
|
|
|
|
|
Mar 19 2013, 13:34
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
StasUKR, чудес не бывает. Разберемся. 1. Покажите Вашу схему: все соединения AЦП c внешним миром и с МК 2. Покажите мне осциллограмму, состоящую из CLK,CS,MOSI, ну и опционально MISO. два последовательных фрейма: Сброс и Чтение ID. Если 3/4-канального осциллографа нет- то на двухканальном запустите развертку от спада CS и покажите отдельно CLK+MOSI и CLK+MISO, MOSI+MISO. По поводу ресета и последующего чтения- ничего подобного, это разные фреймы. Здесь я называю фреймом последовательность сигналов шины, обрамленную неактивным CS (то есть от "установили CS в ноль" до "установили CS в единицу. Честно говоря, в реале я бы уже сказал "Или везите плату ко мне или везите меня к плате", но тут, надеюсь, можно дистанционно Цитата(StasUKR @ Mar 19 2013, 13:53)  да, вместо ответа на Dout , АЦП дергает Dout раз в 60мс... Получается АЦП не принял команду на чтение ID??? Если во время передачи байта- то это значит, что он не видит Ваши CLK. Но скорее всего это ничего не значит (потому как 60мс это очень большой период для SPI шины, непонятно что происходит на шине в момент, когда вы видите этот DOUT) . Осциллограммы в студию. P.S. Ваше письмо на емейл я получил, почта работает
|
|
|
|
|
Mar 19 2013, 14:27
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 12-03-13
Пользователь №: 75 988

|
схема Осцилограмм сейчас нет, есть только ручной осцилл в 1 канал, и кнопка(брейкпоинт, по нажатию перехожу к следующему брейку), так и просматривал общую картину записывая на бумаге пошагово... пробовал CS как в режиме постоянно на земле(для 1й микросхемы "0", для другой соответственно "1"), так и опускал в начале фрейма и подымал в конце... без результатов... Цитата потому как 60мс это очень большой период для SPI шины, непонятно что происходит на шине в момент, когда вы видите этот DOUT) этот вот короткий импульс на Dout через 60 мс есть всегда после включения питания...
|
|
|
|
|
Mar 19 2013, 15:10
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
Цитата(StasUKR @ Mar 19 2013, 16:27)  Осцилограмм сейчас нет, есть только ручной осцилл в 1 канал, и кнопка(брейкпоинт, по нажатию перехожу к следующему брейку), так и просматривал общую картину записывая на бумаге пошагово... Вот и отсканируйте то что на бумаге нарисовали, может уже понятно будет. Кстати, у Вас какой-нибудь симулятор МК это нарисовать может? Тут есть всего два варианта: 1. Ошибка в программе. Приведите Ваш исходник работы с АЦП. Я так понимаю, что полностью софтовое выпиливание? Это поддается симуляции на 100% (так как грубую процессорозавимую ошибку вроде неправильно сконфигурированной ноги осциллографом бы увидели). Некорректное выпиливание битов любой софтовый симулятор покажет, тут железо не нужно. 2. Железячная ошибка типа непропая или коротыша или ошибки при разводке на плате. Тут помочь дистанционно очень тяжело (Мне однажды так удалось найти ошибку в пайке по фотографии платы, но лучше так не делать  Но все это теория. Лучше один раз посмотреть на осциллограммы. Это самый простой и надежный путь. Найдите осциллограф или логический анализатор, скорость-то клока можно и маленькую поставить.
|
|
|
|
|
Mar 20 2013, 07:57
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 12-03-13
Пользователь №: 75 988

|
Взял номальный 2х канальный осцилл, посмотрел осцилограммы и обнаружилось, что везде затянутые фронты... Далее железная проверка и после обращения внимания на инициализацию порта найдена ошибка. После исправления в ID читается 4e, все окей... Всем спасибо огромное!!!!!!!!!!!!!!!! ЗЫ. спасибо этому миру за хорошие 2х канальные осцилы!!!=)
|
|
|
|
|
Mar 21 2013, 07:31
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 12-03-13
Пользователь №: 75 988

|
Цитата(Ruslan1 @ Mar 20 2013, 17:40)  Ну, любой осциллограф сильно жизнь упрощает. А хороший упрощает сильно. Поздравляю!  Вроде разобрался, да не совсем пока еще=( Основная проблема была как писал из-за того, что фронтов почти небыло по сему по сути Клока небыло, как и нормального Din... Сейчас возникли такие вот вопросы, чтоб уже до конца наладить общение... Опишу проблему, на плате несколько AD7794, обращаюсь к первой, получаю 0x7F, меняю CS, запрашиваю ID и получаю 0 на всех остальных... Что не так? ну и вопросы: 1) обязательно ли начинать чтение ID с проверки RDY(ухода его в 0) ? 2) во время работы с фреймом(последовательность записи и чтения) CS держать в "0" и только после завершения фрейма его подымать в "1" ? 3) после power ON(с некоторой задержкой), если не делать сброс (записывать 4*FF и ждать 500us) должно читаться 0x XF, а после ресета(4*FF ) должен считаться 0x СОБСТВЕННЫЙ ID, который будет отличен от изначального, или он останется 0xXF? СПАСИБО
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|