|
char + char = int как такое сделать, Сделать из двух байт целое |
|
|
|
Aug 27 2009, 17:10
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
Ситуатция известная - - результат АЦП их двух байт в разных банках. - работает три канала. - есть массив из трех int. Надо младший и старший байты результата АЦП обьединить в три целых переменных в массиве.
Чегото не получается никак - уже который раз пытаюсь. В AVR наких проблем нету, а на PIC редко пишу - направьте где посмотреть как это делается? Надо на СИ.
|
|
|
|
|
Aug 27 2009, 17:24
|
Участник

Группа: Участник
Сообщений: 73
Регистрация: 6-11-07
Пользователь №: 32 085

|
Это не подойдёт? int result = ((int)highByte << 8) + lowByte;
|
|
|
|
|
Aug 27 2009, 18:01
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
Цитата(*antzol* @ Aug 27 2009, 21:24)  Это не подойдёт? 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] -----------------------------------второго преобразования и тд Ммссив надо как то в цикле индексировать по счетчику каналов.
|
|
|
|
|
Aug 27 2009, 19:03
|
Участник

Группа: Участник
Сообщений: 73
Регистрация: 6-11-07
Пользователь №: 32 085

|
За правильность не ручаюсь, т.к. с пиками давно не работал, а в 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; }
|
|
|
|
|
Aug 27 2009, 19:17
|
Участник

Группа: Участник
Сообщений: 73
Регистрация: 6-11-07
Пользователь №: 32 085

|
...
Сообщение отредактировал *antzol* - Aug 27 2009, 19:23
|
|
|
|
|
Aug 27 2009, 19:50
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760

|
А нельзя типа такого? Код 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; // допустим так... /* и т.д. для остальных каналов АЦП */ Я есесно в пиках и хитеке ни гугу. Это, так сказать, лишь идея....
|
|
|
|
|
Aug 27 2009, 20:12
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
Цитата(*antzol* @ Aug 27 2009, 23:03)  За правильность не ручаюсь, т.к. с пиками давно не работал, а в HTEC PIC вообще не писал.  Скомпилировался и в железе запустился вроде - что за значения получаются завтра проверю. Спасибо.
|
|
|
|
|
Aug 28 2009, 07:35
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
Цитата(Student Pupkin @ Aug 27 2009, 23:50)  А нельзя типа такого? Не работает - преобразование вешается, я с указателями пробовал и не работает с ними у меня этот компилятор - не пойму почему. Судя по листингу он сам активно использует косвенную адресацию и гдето там и происходит глюк, а как найти не знаю. Вот полный код который компилируется но не работает - подскажите где ошибка. CODE //--------------------------------------- // Процессор 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.
Причина редактирования: Нарушение п.3.4 Правил форума.
|
|
|
|
|
Aug 28 2009, 08:13
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 10-02-06
Пользователь №: 14 185

|
Вот на что обратил внимание: Цитата(bugor @ Aug 28 2009, 11:35)  Код while(1) { ei(); asm("nop"); di(); } Зачем в цикле запрещаете прерывания и снова разрешаете (если я правильно угадал смысл ei() и di())? Цитата(bugor @ Aug 28 2009, 11:35)  Код *(pU) = ADRESH; //старший байт в первый элемент массива *(pU++) = ADRESL; //младший байт во второй элемент массива //точно также в 3-4 и в 5-6 элементы по циклу в этом куске младший байт всегда будет перетираться старшим байтом.
|
|
|
|
|
Aug 28 2009, 08:46
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
Цитата(Kane @ Aug 28 2009, 12:13)  Вот на что обратил внимание:
Зачем в цикле запрещаете прерывания и снова разрешаете (если я правильно угадал смысл ei() и di())?
в этом куске младший байт всегда будет перетираться старшим байтом. После запрещения прерывания будут вычисления и чтобы в момент вычислений не изменились данные по прерыванию АЦП так сделано. Я уже посмотрел по листингу что происходит затирка, а как сделать чтобы этого небыло не знаю. Но дело еще в том, что код не работает не в смысле неправильного формирования данных а в том смысле что преобразования АЦП не производятся - то есть на выходе индикатора должен быть что то подобие меандра, а ничего не происходит - висит 1 - то есть в прерывание вход есть, а выхода нет  Причем это наблюдается если начинаю использовать указатели - если без них то циклическое преобразование есть - но с данными непонятно что происходит.
Сообщение отредактировал bugor - Aug 28 2009, 08:47
|
|
|
|
|
Aug 28 2009, 09:50
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
Убрал запрещения и собственно ничего не изменилось - нет преобразований АЦП.
|
|
|
|
|
Aug 28 2009, 09:57
|
Частый гость
 
Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561

|
Код *(pU) = ADRESH; //старший байт в первый элемент массива *(pU++) = ADRESL; //младший байт во второй элемент массива не понятно где и как инициализируется pU?
|
|
|
|
|
Aug 28 2009, 10:28
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
Цитата(tag @ Aug 28 2009, 13:57)  Код *(pU) = ADRESH; //старший байт в первый элемент массива *(pU++) = ADRESL; //младший байт во второй элемент массива не понятно где и как инициализируется pU? Пост №10 там полный код приведен.
|
|
|
|
|
Aug 28 2009, 10:33
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 10-02-06
Пользователь №: 14 185

|
Цитата(tag @ Aug 28 2009, 13:57)  Код *(pU) = ADRESH; //старший байт в первый элемент массива *(pU++) = ADRESL; //младший байт во второй элемент массива не понятно где и как инициализируется pU? Это есть. в самом верху... Цитата(tag @ Aug 28 2009, 13:57)  Код
volatile unsigned int U[3];// @ 0x20; //массив из трех двухбайтных элементов volatile unsigned char *pU =(char*)U; //указатель на адрес 1го элемента массива не понятно где и как инициализируется pU? Какой pic используется? Я глядел в описалово на 16f87x, так там для регистра ADCON0 бит 1 - не определён. Получается, SETBIT(ADCON0,1); - просто не туда попадает.
Сообщение отредактировал Kane - Aug 28 2009, 10:38
|
|
|
|
|
Aug 28 2009, 10:45
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
ну так там написано в заголовке что pic12f675  ёлки - чего еще обнаружил - этот компилятор не понимает вот это Код #asm movwf OSCCAL #endasm а вот это понимает Код #asm movwf 0x90 #endasm хотя адрес этого регистра описан в хедере! чегото мне подумалось, что если в этом такой глюк - чего говорить об указателях  не подскажет ли кто поддерживает ли IAR мелкие процы, замучал меня чегото HT-TECH
Сообщение отредактировал bugor - Aug 28 2009, 11:00
|
|
|
|
|
Aug 28 2009, 11:28
|

Гуру
     
Группа: Модераторы
Сообщений: 10 983
Регистрация: 23-11-05
Пользователь №: 11 287

|
С Хай-теком всё в порядке, Вы сами себя замучили такой кашей, компилятор тут ни при чём. Ни к чему здесь наверняка ни асм-овые вставки, ни хитрости с прерываниями. Разберитесь сначала с битами конфигурации, работой АЦП. Выравнивание происходит правильно? MPLAB используете? В нём всё просто и удобно. Для объединения байтов в int есть несколько вариантов. Я использовал такой: Код ....... union {unsigned int wor; unsigned char by[2];} voltIN; ....... Vcm.by[0]=ADRESL; // младший байт Vcm.by[1]=ADRESH; // старший байт ....... HEXDEC(Vcm.wor); // обращение к целому int-у ....... И зачем Вам это: Код <span class="postcolor">volatile unsigned int U[3];// @ 0x20; //массив из трех двухбайтных элементов </span> почему не просто: Код unsigned int U[3]; //массив из трех двухбайтных элементов
|
|
|
|
|
Aug 28 2009, 15:45
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
Ну вот что получилось - ацп работает но результата по прежнему толком нет. В ацп есть какоето число но какое так и не смог выяснить. Уже голову сломал не могу найти ошибку. CODE //;--------------------------------------- //; Процессор PIC12C672 или PIC12F675 //; Fosc = 4MHz Генератор RC-внутренний //;---------------------------------------
#include <pic.h>
__CONFIG(WDTDIS & INTIO & UNPROTECT & MCLRDIS & PWRTEN & BOREN );
#define warm_out GPIO5 //выход нагревателя #define sound_out GPIO4 //выход pреле звука #define start_out GPIO3 //вход выключателя нагрева
unsigned char Temp, Count, Channel; unsigned int U[3]; //массив данных с 3х каналов
union{ unsigned int Vin; struct{ unsigned char UL:8; unsigned char UH:8; } byte; }volt;
#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 преобразования (ADCON1 после сброса уже установлен) //================================ void InitAD() { ADIE = 1; //Разрешить прерывания от АЦП ADCON0 = Channel; //Генегатор внутр RC + номер канала ADIF = 0; //очистить флаг прерывания от АЦП PEIE = 1; //Разрешить переферийные прерывания } //========================================================================== // MAIN //========================================================================== void main(void) {
#asm bsf status,5 // КАЛИБРОВКА ГЕНЕРАТОРА !!! call 0X3ff movwf 0X90 bcf status,5 #endasm
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 =0b00010111; // F/8 и три канала аналоговый вход warm_out = 1; // вкл выход
Count = 0; //первичная инициализация АЦП Channel = 129; InitAD(); ADDelay(); SETBIT(ADCON0,1);
while(1) { //бесконечный цикл
#asm nop nop nop nop nop nop #endasm
if(U[0] < 2900 ) { //вот тут не работает при напряжении на ацп 3,8 вольт sound_out = 1; //результат должен быть в районе 3114 а его нет }else { sound_out = 0; } } }
//================================ //Обработка прерываний //================================ void interrupt ADC() {
// sound_out = 1;
volt.byte.UL=ADRESL; volt.byte.UH=ADRESH; U[Count]=volt.Vin;
if(Count++ < 3) { Channel = Channel + 8; //загрузить другой канал }else { Channel = 129; //10000001b загрузка канала АЦП 0 Count = 0; //перезагрузить счетчик каналов } InitAD(); ADDelay(); //задержка на 2xTad для восстановления
// sound_out=0; ADDelay(); SETBIT(ADCON0,1); //Запуск A/D преобразования } Раньше писал для этого же процессора на асме и все работало - правда были мучения с вычислениями, а сейдас даже результата преобразования получить не могу - а ведь хотелось как быстрее и красивее Модератор. В очередной раз фиксирую нарушение Вами п.3.4 Правил форума. Либо упаковывайте цитаты исходников в тэги [ codebox ] самостоятельно, либо прилагайте их к сообщению в виде архива так, как это рекомендуют Правила форума. С уважением, rezident.
Причина редактирования: Нарушение п.3.4 Правил форума.
|
|
|
|
|
Aug 28 2009, 18:45
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760

|
Цитата(bugor @ Aug 28 2009, 19:45)  Ну вот что получилось - ацп работает но результата по прежнему толком нет. 1) Есть предложение попробовать "unsigned unt U[3]" переобозвать в " volatile unsigned int U[3]". 2) (это так... мелочь....  ) В функции ADDelay() к переменной-счетчику "static unsigned char i" тоже наверное желательно "volatile" присовокупить. А еще - зачем вы ее static сделали?
|
|
|
|
|
Aug 29 2009, 10:55
|

Гуру
     
Группа: Модераторы
Сообщений: 10 983
Регистрация: 23-11-05
Пользователь №: 11 287

|
Не пойму я, во-первых, зачем Вы структуру сюда прикрутили (было же просто и понятно), во-вторых, откуда у 10-разрядного АЦП возмётся результат больше, чем 1024, в-третьих, в обработчике прерывания флаг не очищается? И всё-таки: MPLAB есть? И почему бы не использовать примеры функций, включенных в HT-PICC? Там есть и для АЦП, и для программной задержки, и для прерываний...
|
|
|
|
|
Aug 29 2009, 17:14
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
1. В функции задержки переменная i только для счетчика и нигде больше не видна и не нужна - так что static. 2. Флаг ADIF сбрасывается в ноль в функции InitAD. 3. Попробую и volatile еще тем более, что изменяется в прерывании - раньше так и было но мне чего то код в асме не понравился вот и убрал. 4. Структуру прикрутил по совету выше и опыту проектов в IAR - да и скомпилировалось сразу без ошибок и по коду вроде все верно делает, объединяя два char в один int. 5. MPLAB есть но никогда им не пользовался так как есть среда ФИТОН но вот их hard-ключ уже третий раз глючит а пересылать в москву надоело и они чего то (как все нормальные конторы) за свой счет делать не предлагают - вот по этому HI-TECH........ И проблемы. 5. А вот в том что результат больше чем 1024 - ЭТО КОСЯК!!!! - какой меня дернуул думать что там 4096 - 12 бит!!!!! ума не приложу  Спасибо всем буду копать. КАК накопаю и получу рабочий код - расскажу.
Сообщение отредактировал bugor - Aug 29 2009, 17:22
|
|
|
|
|
Aug 29 2009, 18:39
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760

|
Цитата(bugor @ Aug 29 2009, 21:14)  1. В функции задержки переменная i только для счетчика и нигде больше не видна и не нужна - так что Для локальных переменных класс памяти static означает, что переменная сохраняется между вызовами функции. Не видна - это когда static применяется к глобальным переменным. Или нет? Однако тут на форуме говорили, что особо свирепый компилятор может так сильно "оптимизировать" подобную программную задержку, что ее совсем не будет (ну вроде как считаем без дела, время тратим, значит выкидываем). И вроде как для программной задержки переменную-счетчик надо объявлять volatile, чтоб оптимизацию над ней подавить...
|
|
|
|
|
Aug 29 2009, 18:47
|

Гуру
     
Группа: Модераторы
Сообщений: 10 983
Регистрация: 23-11-05
Пользователь №: 11 287

|
Цитата(bugor @ Aug 29 2009, 19:14)  4. Структуру прикрутил по совету выше и опыту проектов в IAR - да и скомпилировалось сразу без ошибок и по коду вроде все верно делает, объединяя два char в один int. Так там не нужна структура, достаточно объединения. Цитата 5. MPLAB есть но никогда им не пользовался так как есть среда ФИТОН но вот их hard-ключ уже третий раз глючит а пересылать в москву надоело и они чего то (как все нормальные конторы) за свой счет делать не предлагают - вот по этому HI-TECH........ И проблемы. И напрасно: MPLAB - удобная штука (может, бывают и получше среды, но не суть), осваивается легко, бесплатная, есть симулятор, чего же голову морочить...
Сообщение отредактировал Herz - Aug 29 2009, 18:48
|
|
|
|
|
Aug 31 2009, 18:28
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(bugor @ Aug 29 2009, 21:14)  1. В функции задержки переменная i только для счетчика и нигде больше не видна и не нужна - так что static. Ошибаетесь: static для локальной переменной функции и static для локальной переменной модуля имеют разный смысл. Код int get_cnt(void) { ststic int cnt = 100; return (cnt++); }
for (int i=0; i<3; i++) get_cnt(); /* Вернёт: 100 101 102 */ rezident в следующем сообщении более грамотно изложил суть... А для доступа к слову побайтно удобно пользоваться объединением с безымянной структурой (если Ваш компилятор это позволяет). Код typedef union { uint16_t word; struct { uint8_t byte0; uint8_t byte1; }; } my_int16_t;
my_int16_t x = {.word = 0xABCD};
void swap_bytes(my_int16_t* x) { uint8_t temp = x->byte0; x->byte0 = x->byte1; x->byte1 = temp; } Единственное о чём ещё следует позаботиться, так это о выравнивании полей структуры по границе байта (#pragma pack(1) или через атрибуты или через makefile)... И более того, даже так Вам не удастся избежать возможных граблей с big-little endian... Единственное дубовое решение - это макросы со сдвигами типа: Код #define GET_BYTE(X,Y) ((uint8_t)((X)>>((Y)*8))) #define BYTE0(X) GET_BYTE((X),0) #define BYTE1(X) GET_BYTE((X),1) #define BYTE2(X) GET_BYTE((X),2) #define BYTE3(X) GET_BYTE((X),3) ... #define LH2WORD(LBYTE,HBYTE) ((uint16_t)((HBYTE)<<8) | (LBYTE))
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Aug 31 2009, 18:36
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Student Pupkin @ Aug 30 2009, 00:39)  Для локальных переменных класс памяти static означает, что переменная сохраняется между вызовами функции. Не видна - это когда static применяется к глобальным переменным. Или нет? Для переменных типа static выделяется постоянное место в ОЗУ, точно также, как и для глобальных переменных. И инициализация static начальным значением (очистка, если значение явно не задано) осуществляется точно также, как и у глобальных переменных. Но область видимости переменной типа static действительно ограничена, также, как и у автоматической (локальной) переменной. Тут вы правы.
|
|
|
|
|
Sep 6 2009, 14:41
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 26-02-09
Пользователь №: 45 408

|
Ну вот собственно заработало. Проиллюстрирую поподробнее, может пригодится кому. Обязательно надо настроить все переиферийные устройства, не полагаясь на автоматические установки после сброса. Это переменная куда заносятся байты результата. Главное, чтобы они были именно в этом порядке. Пока сделал так - потом без структуры попробую. CODE union{ volatile unsigned int Vin; struct{ volatile unsigned char UL:8; volatile unsigned char UH:8; } byte; }volt; Это программы задержки и переинициализации АЦП CODE void ADDelay() { //задержка 10uS static unsigned char i; i = 3; //Генератор 4Mhz, период 3uS, while(i > 0) { //переменная равна 3 плюс смещение i--; } } void InitAD() { ADIE = 1; //Разрешить прерывания от АЦП ADCON0 = Channel; //Генегатор внутр RC + номер канала ADIF = 0; //очистить флаг прерывания от АЦП PEIE = 1; //Разрешить переферийные прерывания } Это необходимые процедуры для запуска АЦП CODE void main(void) {
#asm bsf status,5 // КАЛИБРОВКА ГЕНЕРАТОРА !!! call 0X3ff movwf 0X90 bcf status,5 #endasm
WPU = 0; // все подтягивающие резисторы выключены ANSEL = 0b01010011; // F/16 для АЦП и 2 канала аналоговых GPIO = 0b00000000; // порты в ноль TRISIO = 0b00001111; // GP4-5 на выход OPTION = 0b10000111; // R-up выкл, делитель 1:256 к TMR0 VRCON = 0x00; // выключить источник опорного напряжения IOCB = 0x00; // запрет прерываний по входам CMCON = 0b00000111; // выключить компаратор INTCON = 0b10000000; // разрешить общее прерывание
Count = 0; //первичная инициализация АЦП Channel = 129; InitAD(); ADDelay(); SETBIT(ADCON0,1);
while(1) { //бесконечный цикл #asm nop nop nop nop nop nop #endasm ...................................... //основная программа ......................................
} } А это обработка прерывания АЦП. CODE void interrupt ADC() {
if(ADIF == 1) {
volt.byte.UL=ADRESL; //ВОТ В ЭТИХ ТРЕХ СТРОКА ФОРМИРУЕТСЯ МАССИВ РЕЗУЛЬТАТОВ АЦП volt.byte.UH=ADRESH; //В ДАННОМ СЛУЧАЕ - ЭТО ДВА ЦЕЛЫХ ЧИСЛА U[Count]=volt.Vin; //ТУТ ПОЛУЧАЕМ ЦЕЛОЕ С ПРАВИЛЬНЫМ РАСПОЛОЖЕНИЕМ БАЙТОВ //ПРИ ДАЛЬНЕЙШЕЙ МАТЕМАТИЧЕСКОЙ ОБРАБОТКЕ ВСЕ ПРОИСХОДИТ ПРАВИЛЬНО if(++Count < 2) { Channel = Channel + 4; //загрузить другой канал InitAD(); ADDelay(); //задержка на 2xTad для восстановления ADDelay(); SETBIT(ADCON0,1); }else { Channel = 129; //10000001b загрузка канала АЦП 0 Count = 0; //перезагрузить счетчик каналов InitAD(); ADDelay(); ADDelay(); SETBIT(ADCON0,1); } }
............................ //Тут могут быть обработчики других прерываний ........................... } Итого был неправильно оформлен счетчик массива, разрядность АЦП 12 бит вместо десяти ну и обьединение для собственно запихивания байт в целое. Всем спасибо!
Причина редактирования: Уменьшение горизонального размера цитаты.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|