bugor 0 27 августа, 2009 Опубликовано 27 августа, 2009 · Жалоба Ситуатция известная - - результат АЦП их двух байт в разных банках. - работает три канала. - есть массив из трех int. Надо младший и старший байты результата АЦП обьединить в три целых переменных в массиве. Чегото не получается никак - уже который раз пытаюсь. В AVR наких проблем нету, а на PIC редко пишу - направьте где посмотреть как это делается? Надо на СИ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
*antzol* 0 27 августа, 2009 Опубликовано 27 августа, 2009 · Жалоба Это не подойдёт? int result = ((int)highByte << 8) + lowByte; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bugor 0 27 августа, 2009 Опубликовано 27 августа, 2009 · Жалоба Это не подойдёт? int result = ((int)highByte << 8) + lowByte; HTEC PIC ругается - degenerate unsigned comparison volatile unsigned int U[3] @ 0x20; //массив ADRESH и ADRESL - это байты результата надо в U[0] поместить ADRESH и ADRESL первого преобразования в U[1] -----------------------------------второго преобразования и тд Ммссив надо как то в цикле индексировать по счетчику каналов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
*antzol* 0 27 августа, 2009 Опубликовано 27 августа, 2009 · Жалоба За правильность не ручаюсь, т.к. с пиками давно не работал, а в HTEC PIC вообще не писал. :) char i; for (i = 0; i < 3; i++) { ADCON0 &= 0xC3; // сброс выбора входа ADCON0 |= (i<<3); // выбор входа // тут надо вставить задержку ADCON0 |= (1<<2); // запуск преобразования while (ADCON0 & (1<<2)); // ожидание завершения преобразования u[i] = ADRESH; u[i] <<=8; u[i] +=ADRESL; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 27 августа, 2009 Опубликовано 27 августа, 2009 · Жалоба HTEC PIC ругается - degenerate unsigned comparisonВидимо потому, что перед сдвигом надо приводить к типу unsigned int, а не (signed) int. Или использовать временную локальную переменную типа unsigned int . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
*antzol* 0 27 августа, 2009 Опубликовано 27 августа, 2009 (изменено) · Жалоба ... Изменено 27 августа, 2009 пользователем *antzol* Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Student Pupkin 0 27 августа, 2009 Опубликовано 27 августа, 2009 · Жалоба А нельзя типа такого? short int adc_mass[3]; // или int16_t в духе С99 ??? char *adc_byte; // или int8_t в духе С99 ??? adc_byte = (char*)adc_mass; *(adc_byte++) = LOW_BYTE_ADC1; // не знаю как называются, но *(adc_byte++) = HIGH_BYTE_ADC1; // допустим так... /* и т.д. для остальных каналов АЦП */ Я есесно в пиках и хитеке ни гугу. Это, так сказать, лишь идея.... :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bugor 0 27 августа, 2009 Опубликовано 27 августа, 2009 · Жалоба За правильность не ручаюсь, т.к. с пиками давно не работал, а в HTEC PIC вообще не писал. :) Скомпилировался и в железе запустился вроде - что за значения получаются завтра проверю. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DpInRock 0 27 августа, 2009 Опубликовано 27 августа, 2009 · Жалоба char как и int - переменные со знаком. Если не знаете зачем вам нужен знак используйте unsigned. И компилятор тут не при делах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bugor 0 28 августа, 2009 Опубликовано 28 августа, 2009 · Жалоба А нельзя типа такого? Не работает - преобразование вешается, я с указателями пробовал и не работает с ними у меня этот компилятор - не пойму почему. Судя по листингу он сам активно использует косвенную адресацию и гдето там и происходит глюк, а как найти не знаю. Вот полный код который компилируется но не работает - подскажите где ошибка. //--------------------------------------- // Процессор PIC12F675 // Fosc = 4MHz Генератор RC-внутренний // HI-TECH 8.05LP1 //--------------------------------------- #include <pic.h> #include <math.h> __CONFIG(WDTDIS & INTIO & UNPROTECT & MCLRDIS & PWRTEN & BOREN ); #define warm_out GPIO5 //выход нагревателя #define sound_out GPIO4 //выход pреле звука #define start_out GPIO3 //вход выключателя нагрева volatile unsigned char Temp, Count, Channel; volatile unsigned int U[3];// @ 0x20; //массив из трех двухбайтных элементов volatile unsigned char *pU =(char*)U; //указатель на адрес 1го элемента массива //МАКРОСЫ //----------------------------------------- #define TESTBIT(ADRESS,BIT) (ADRESS & (1<<BIT)) #define SETBIT(ADRESS,BIT) (ADRESS |= (1<<BIT)) #define CLEARBIT(ADRESS,BIT) (ADRESS &= ~(1<<BIT)) //================================ //задержка для A/D преобразования //================================ void ADDelay() { //задержка 10uS static unsigned char i; i = 3; //Генератор 4Mhz, период 3uS, while(i > 0) { //переменная равна 3 плюс смещение i--; } } //================================ //Инициализация A/D преобразования //================================ void InitAD() { ADIE = 1; //Разрешить прерывания от АЦП ADCON0 = Channel; //Генегатор внутр RC + номер канала ADIF = 0; //очистить флаг прерывания от АЦП PEIE = 1; //Разрешить переферийные прерывания asm("nop"); } //========================================================================== // MAIN //========================================================================== void main(void) { GPIO = 0b00000000; // порты в ноль TRISIO = 0b10001111; // GP4-5 на выход OPTION = 0b00000110; // R-up выкл, делитель 1:128 к TMR0 VRCON = 0x00; // выключить источнок опорного напряжения WPU = 0b00000000; // gp0 gp5 подтягивающие резисторы выключены IOCB = 0x00; // запрет прерываний по входам CMCON = 0b00000111; // компаратор выключен INTCON =0b10000000; // разреш прерывания ANSEL =0b01010111; warm_out = 1; Count = 0; //первый запуск ацп Channel = 129; //канал ацп 0 InitAD(); ADDelay(); SETBIT(ADCON0,1); while(1) { ei(); asm("nop"); di(); } } //================================ //Обработка прерываний //================================ void interrupt ADC() { sound_out = 1; //индикатор работы ацп *(pU) = ADRESH; //старший байт в первый элемент массива *(pU++) = ADRESL; //младший байт во второй элемент массива //точно также в 3-4 и в 5-6 элементы по циклу if(Count++ < 3) { Channel = Channel + 8; //загрузить другой канал }else { Channel = 129; //10000001b загрузка канала АЦП 0 Count = 0; //перезагрузить счетчик каналов *pU = U[0]; //перегружаем адрес первого элемента массива } InitAD(); ADDelay(); //задержка на 2xTad для восстановления sound_out=0; ADDelay(); SETBIT(ADCON0,1); //Запуск A/D преобразования } По посту №4 работает АЦП и даже есть результат но понятно это по изменению младшего байта результата, а вот когда пытаюсь запихать два байта в целое то сравнения не работают то есть не получается нормальног INT из двух CHAR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kane 0 28 августа, 2009 Опубликовано 28 августа, 2009 · Жалоба Вот на что обратил внимание: while(1) { ei(); asm("nop"); di(); } Зачем в цикле запрещаете прерывания и снова разрешаете (если я правильно угадал смысл ei() и di())? *(pU) = ADRESH; //старший байт в первый элемент массива *(pU++) = ADRESL; //младший байт во второй элемент массива //точно также в 3-4 и в 5-6 элементы по циклу в этом куске младший байт всегда будет перетираться старшим байтом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bugor 0 28 августа, 2009 Опубликовано 28 августа, 2009 (изменено) · Жалоба Вот на что обратил внимание: Зачем в цикле запрещаете прерывания и снова разрешаете (если я правильно угадал смысл ei() и di())? в этом куске младший байт всегда будет перетираться старшим байтом. После запрещения прерывания будут вычисления и чтобы в момент вычислений не изменились данные по прерыванию АЦП так сделано. Я уже посмотрел по листингу что происходит затирка, а как сделать чтобы этого небыло не знаю. Но дело еще в том, что код не работает не в смысле неправильного формирования данных а в том смысле что преобразования АЦП не производятся - то есть на выходе индикатора должен быть что то подобие меандра, а ничего не происходит - висит 1 - то есть в прерывание вход есть, а выхода нет Причем это наблюдается если начинаю использовать указатели - если без них то циклическое преобразование есть - но с данными непонятно что происходит. Изменено 28 августа, 2009 пользователем bugor Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DpInRock 0 28 августа, 2009 Опубликовано 28 августа, 2009 · Жалоба После запрещения прерывания будут вычисления При зазоре в один ноп могут быть очень большие проблемы с прерываниями. У пика конвейер из 4 слов, насколько припоминаю... Не запрещайте прерываний без четкого понимания - для чего именно вам это нужно именно в данный момент. В данной программе данный код не имеет смысла. Даже для якобы будущих вычислений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bugor 0 28 августа, 2009 Опубликовано 28 августа, 2009 · Жалоба Убрал запрещения и собственно ничего не изменилось - нет преобразований АЦП. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tag 0 28 августа, 2009 Опубликовано 28 августа, 2009 · Жалоба *(pU) = ADRESH; //старший байт в первый элемент массива *(pU++) = ADRESL; //младший байт во второй элемент массива не понятно где и как инициализируется pU? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться