в которую я раньше ручками подставлял значение k
если мне нужно было входной сигнал поделить на 13.6 я вместо k записывал значение 0,0735 (1/13.6)
если мне нужно было входной сигнал умножить на 11 я вместо k записывал значение 11
теперь вот пытаюсь спомощью АЦП реализовать переменное значение 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.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
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
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
Никак не могу взять в толк, зачем вообще тут флоат? Ни для управления умножением-делением он не нужен, ни для вывода на индикацию.
Для отображения вполне хватит обычного формата с фиксированной точкой, то есть int в мантиссе и char в обозначении позиции точки.
Порой желание написать некую конструкцию на Си выходит за границы здравого смысла.
КРАМ писал(а):Никак не могу взять в толк, зачем вообще тут флоат? Ни для управления умножением-делением он не нужен, ни для вывода на индикацию.
Для отображения вполне хватит обычного формата с фиксированной точкой, то есть int в мантиссе и char в обозначении позиции точки.
Порой желание написать некую конструкцию на Си выходит за границы здравого смысла.
Я прекрасно Вас понимаю, моя основная головная боль в том что я совсем запутался в этих всех значениях float int char и т.д.
я прекрасно себе представляю картину того что мне нужно сделать, но как программно это реализовать для меня темный лес, особенно на PIC-контроллерах.
Здесь дело в точности. Вам нужно получить какой-то коефициент 4,8567 (скажем) вот и здесь нужно float (или double).
k -= (unsigned)((float)((k-1)*9/10));
В етом ряде все равно приводим к целое.
Да и я как понял ета информация не въводится - да я и не смотрел что с ней потом делается.
Так:
А что если сделаем другое. Берем с ADC старшие 5 битов. Сдвигаем их вправо и получаем коефициентъ с 1 до 31, если возмем 4 бита то с 1 по 15.
#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
Подскажите как я совсем с этими типами переменных запутался
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. Можно желать лучшего. Теряется точность.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.