АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Поклонники продукции Microchip Technology Inc тусуются тут.
Frosty85
Встал на лапы
Сообщения: 84
Зарегистрирован: Ср окт 22, 2014 04:24:01

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение Frosty85 »

так вот это у меня и есть основная формула

per_tmp = (long)((float)(per_tmp/k));

в которую я раньше ручками подставлял значение k
если мне нужно было входной сигнал поделить на 13.6 я вместо k записывал значение 0,0735 (1/13.6)
если мне нужно было входной сигнал умножить на 11 я вместо k записывал значение 11


теперь вот пытаюсь спомощью АЦП реализовать переменное значение k
Реклама
Аватара пользователя
botchin
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение botchin »

Ето

Код: Выделить всё

        if (data.adc <= 511){k = 512-data.adc;}
        else{k = data.adc - 511;}
          
            per_tmp = (long)((float)(per_tmp/k));
должно стать как-то так

Код: Выделить всё

        if (data.adc <= 511){
            k = 512-data.adc;
            k = k - (k-1)*.9;    /*приводим переменную в диапазоне 1-52 */
            per_tmp = (long)((float)(per_tmp/k));
        }
        else{
            k = data.adc - 511;
             k = k - (k-1)*.95; /*приводим переменную в диапазоне 1-26,5 */
           k = k - (k-1)*.9; /*приводим переменную в диапазоне 1-52 */
            per_tmp = (long)((float)(per_tmp*k));
         }
только посмотрите какой тип вам надо задать для переменной k. float явно не подходить - компилятор ругается
Здесь манипулируя константой 0,9 можно делать растяжка диапазона. Если заменить 0,9 на 0,5 то диапазон k будет менятся с 1 по 256.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Реклама
Frosty85
Встал на лапы
Сообщения: 84
Зарегистрирован: Ср окт 22, 2014 04:24:01

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение Frosty85 »

Ошибку при компиляции выдает.

Код: Выделить всё

Build D:\taho_675\taho for device 12F675
Using driver C:\Program Files (x86)\Microchip\xc8\v1.20\bin\xc8.exe

Make: The target "D:\taho_675\main.p1" is out of date.
Executing: "C:\Program Files (x86)\Microchip\xc8\v1.20\bin\xc8.exe" --pass1 D:\taho_675\main.c -q --chip=12F675 -P --runtime=default,+clear,+init,-keep,+osccal,-download,-resetbits,-stackcall,-config,+clib,+plib --opt=default,+asm,+debug,+speed,-space,9 --warn=0 -N255 -D__DEBUG=1 -Bsmall --double=32 --float=32 --addrqual=ignore -g --asmlist "--errformat=Error   [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s" 
Warning [356] D:\taho_675\main.c; 120.18 implicit conversion of float to integer
Warning [356] D:\taho_675\main.c; 123.18 implicit conversion of float to integer
Executing: "C:\Program Files (x86)\Microchip\xc8\v1.20\bin\xc8.exe" -otaho.cof -mtaho.map --summary=default,-psect,-class,+mem,-hex --output=default,-inhx032 main.p1 --chip=12F675 -P --runtime=default,+clear,+init,-keep,+osccal,-download,-resetbits,-stackcall,-config,+clib,+plib --opt=default,+asm,+debug,+speed,-space,9 --warn=0 -N255 -D__DEBUG=1 -Bsmall --double=32 --float=32 --addrqual=ignore -g --asmlist "--errformat=Error   [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s" 
Microchip MPLAB XC8 C Compiler V1.20
Copyright (C) 2013 Microchip Technology Inc.
License type: w
Error   [1250] D:\taho_675\main.c; 10. could not find space (4 bytes) for variable _per_tmp
(908) exit status = 1

********** Build failed! **********
:cry: :facepalm: :facepalm: :facepalm: :facepalm:
Frosty85
Встал на лапы
Сообщения: 84
Зарегистрирован: Ср окт 22, 2014 04:24:01

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение Frosty85 »

с ошибками разобрался, но снова уткнулся в нехватку места.

Спойлер

Код: Выделить всё

if(per_tmp){
        if (data.adc <= 511){k = 512-data.adc;
                             k =(long)((float)( k - (k-1)*.95));
							per_tmp = (long)((float)(per_tmp/k));}
        else{k = data.adc - 511;
            k =(long)((float)( k - (k-1)*.95));
            per_tmp = (long)((float)(per_tmp*k));}

Код: Выделить всё

Microchip MPLAB XC8 C Compiler V1.20
Copyright (C) 2013 Microchip Technology Inc.
License type: w
Error   [1250] D:\taho_675\main.c; 10. could not find space (4 bytes) for variable _per_tmp
(908) exit status = 1
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
botchin
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение botchin »

Попробуй так

Код: Выделить всё

     
unsigned int k;
.......
   if (data.adc <= 511){k = 512-data.adc;
            k -= (unsigned)((float)((k-1)*9/10));
            per_tmp = (long)((float)(per_tmp/k));}
        else{k = data.adc - 511;
            k -= (unsigned)((float)((k-1)*9/10));
            per_tmp = (long)((float)(per_tmp*k));}
.......
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Реклама
Frosty85
Встал на лапы
Сообщения: 84
Зарегистрирован: Ср окт 22, 2014 04:24:01

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение Frosty85 »

botchin писал(а):Попробуй так

Код: Выделить всё

     
unsigned int k;
.......
   if (data.adc <= 511){k = 512-data.adc;
            k -= (unsigned)((float)((k-1)*9/10));
            per_tmp = (long)((float)(per_tmp/k));}
        else{k = data.adc - 511;
            k -= (unsigned)((float)((k-1)*9/10));
            per_tmp = (long)((float)(per_tmp*k));}
.......

теперь :

Код: Выделить всё

Microchip MPLAB XC8 C Compiler V1.20
Copyright (C) 2013 Microchip Technology Inc.
License type: w
Error   [1360] D:\taho_675\main.c; 72. no space for auto/param ___fldiv@exp
(908) exit status = 1
Реклама
Frosty85
Встал на лапы
Сообщения: 84
Зарегистрирован: Ср окт 22, 2014 04:24:01

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение Frosty85 »

:shock: собрался
Аватара пользователя
botchin
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение botchin »

675 маленькии. Не хватает место.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение КРАМ »

Никак не могу взять в толк, зачем вообще тут флоат? Ни для управления умножением-делением он не нужен, ни для вывода на индикацию.
Для отображения вполне хватит обычного формата с фиксированной точкой, то есть int в мантиссе и char в обозначении позиции точки.
Порой желание написать некую конструкцию на Си выходит за границы здравого смысла.
Frosty85
Встал на лапы
Сообщения: 84
Зарегистрирован: Ср окт 22, 2014 04:24:01

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение Frosty85 »

КРАМ писал(а):Никак не могу взять в толк, зачем вообще тут флоат? Ни для управления умножением-делением он не нужен, ни для вывода на индикацию.
Для отображения вполне хватит обычного формата с фиксированной точкой, то есть int в мантиссе и char в обозначении позиции точки.
Порой желание написать некую конструкцию на Си выходит за границы здравого смысла.

Я прекрасно Вас понимаю, моя основная головная боль в том что я совсем запутался в этих всех значениях float int char и т.д.
я прекрасно себе представляю картину того что мне нужно сделать, но как программно это реализовать для меня темный лес, особенно на PIC-контроллерах. :facepalm:
Аватара пользователя
botchin
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение botchin »

Здесь дело в точности. Вам нужно получить какой-то коефициент 4,8567 (скажем) вот и здесь нужно float (или double).
k -= (unsigned)((float)((k-1)*9/10));
В етом ряде все равно приводим к целое.

Да и я как понял ета информация не въводится - да я и не смотрел что с ней потом делается.


Так:
А что если сделаем другое. Берем с ADC старшие 5 битов. Сдвигаем их вправо и получаем коефициентъ с 1 до 31, если возмем 4 бита то с 1 по 15.

Ето сърое еще.

Код: Выделить всё

        if (data.adc <= 511){k = 512-data.adc;
            k -= (unsigned)((k-1)*9/10);
            per_tmp = (long)(per_tmp/k);}
        else{k = data.adc - 511;
            k -= (unsigned)((k-1)*9/10);
            per_tmp = (long)(per_tmp*k);}
А так?
Последний раз редактировалось botchin Чт май 19, 2016 15:19:28, всего редактировалось 1 раз.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Frosty85
Встал на лапы
Сообщения: 84
Зарегистрирован: Ср окт 22, 2014 04:24:01

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение Frosty85 »

Спойлер

Код: Выделить всё

#include "pic.h"
__CONFIG ( WDTDIS & INTIO & MCLREN & UNPROTECT );
/****************************************************************/
#define PIN_OUT     GPIO0       // Выходной ПИН
#define TRIS_OUT    TRISIO0     //
#define adc_bits 10 
#define adc_clock 3 
#define adc_sampleus 50 
/****************************************************************/
unsigned long per_tmp;
unsigned int k;
/****************************************************************/
volatile unsigned long   Per_In=0;       // Преобразованный период входного сигнала
static bit               In_Fl=0;        // Флаг окончания преобразования периода
volatile unsigned long   Per_Out=0;      // Период выходного сигнала
/****************************************************************/
union
{
struct {
unsigned char lo;
unsigned char hi;
}st;
unsigned int adc;
}data;

/****************************************************************/
void interrupt _isr(void){
static bit p_fl=0;                      // Флаг преобразования входного периода
static unsigned int     H_Per_In=0;     // Старшие байты вх. периода
static unsigned char    H_Per_Out=0;    // Старший байт вых. периода
//-------------------------------------//
    if(INTF){
        INTF=0;
            if(!p_fl){
                p_fl=1;
                TMR0=0;
                H_Per_In=0;
            }
            else{
                *((char*)&Per_In)=TMR0+5;
                TMR0=0;
                    if(T0IF)                // Если было переполнение
                        H_Per_In++;         // обрабатываем его
                *((int*)((char*)&Per_In+1))=H_Per_In;
                H_Per_In=0;
                In_Fl=1;    // Ставим флаг окончания преобразования
            }
        T0IF=0;
    }
//-------------------------------------//
    if(T0IF && T0IE){
        T0IF = 0;
        H_Per_In++;                         //  +256
            if( *((char*)&H_Per_In+1)>=16 ){    //  >=16*65536 ~1000000 МЦ
                H_Per_In=0;
                p_fl=0;     // Сброс флага преобразования
                Per_In=0;   // Период = 0
                In_Fl=1;    // Ставим флаг окончания преобразования
            }
    }
//-------------------------------------//
    if(TMR1IF && TMR1IE){
    TMR1IF=0;
        if(!H_Per_Out--){
            TMR1 -= *((int*)((char*)&Per_Out));
            H_Per_Out = *((char*)&Per_Out+2);
            PIN_OUT=!PIN_OUT;
        }
    }
//-------------------------------------//

}
/****************************************************************/
void main(){

CMCON=7;        // Настраиваем порты как цифровые
ADCON0=135;
ANSEL=50;

TRIS_OUT=0;
PIN_OUT=0;

T0CS =0;
PSA=1;
PS2=0;
PS1=0;
PS0=0;
TMR0 = 0;
T0IE =1;

TMR1ON=1;
TMR1IE=0;

INTE=1;
INTEDG=0;

PEIE=1;
GIE=1;

Per_Out=0;

while(1){

// производим измерение АЦП каждые 10 мс
ADCON0 |= 0b00000010;
     while(ADCON0 & 0b00000010);
data.st.hi=ADRESH;
data.st.lo=ADRESL;

   if(In_Fl){
        In_Fl=0;
        //--------------------
        GIE=0;
        per_tmp = Per_In;
        GIE=1;
        per_tmp/=2;
        //--------------------
        if(per_tmp){
        if (data.adc <= 511){k = 512-data.adc;
							k -= (unsigned)((float)((k-1)*9/10));
                             per_tmp = (long)((float)(per_tmp/k));}
        else{k = data.adc - 511;
			k -= (unsigned)((float)((k-1)*9/10));
           per_tmp = (long)((float)(per_tmp*k));}
 			
            GIE=0;
            Per_Out = per_tmp;
            GIE=1;
            TMR1IE=1;
        }
        else{
            TMR1IE=0;
            PIN_OUT=0;
        }
    }
 }
}
/****************************************************************/
Итак в этом варианте благодаря помощи botchin, получилось добиться деления и умножения с значением коэфф от 1 до 51 но только в целом числе. теперь как сделать этот коэф с плавающей запятой т.е. от 0,1 до 51,0

Подскажите как я совсем с этими типами переменных запутался :kill: :facepalm:
Аватара пользователя
botchin
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение botchin »

Frosty85, деление на 0,1 ето умножение на 10. Вам ето нужно? Как и умножение на 0,1
Коефициентъ должнъ бъть с 1 до ...

Кстати, у нас уже идут целочисленнъе коефициентъ
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение КРАМ »

Господа, как можно писать код без понимания ДЛЯ ЧЕГО И В КАКОМ ФОРМАТЕ нужен результат?
:facepalm:
Аватара пользователя
botchin
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Re: АЦП pic12f629 вопрос по регистрам ADRESL и ADREHL

Сообщение botchin »

вот здесь уже работают и десятъе. И компилируется

Код: Выделить всё

        if (data.adc <= 511){k = 512-data.adc;
            k *=10;
            k -= (unsigned)((k-1)*9);  //приводим к коефициента умноженном на 10
            per_tmp = (long)(per_tmp/k);
   per_tmp *= 10;    // умножаем на 10 для получения нормального коефициента
         }
        else{k = data.adc - 511;
            k *=10;
            k -= (unsigned)((k-1)*9);
            per_tmp = (long)(per_tmp*k);
   per_tmp /= 10;          // делим на 10 для получения нормального коефициента
         }
Если не потерял где-то, что-то.

PS: Поменял код. Не работал для деления.

Да-а-а-а. Не получается. Запустил Debug. Можно желать лучшего. Теряется точность.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Ответить

Вернуться в «PIC»