Есть переменная:
unsigned long tmp;
Есть формула:
tmp = (long)((float)(tmp/ADC));
где ADC - значение АЦП из двух регистров (ADRESL и ADREHL)
должно принимать значение от 1\25.6 до 25.6 (0-1023)
совсем запутался в этих преобразованиях
При 9 значущих битах ADC примет значения с 0 до 511Frosty85 писал(а):ADC принимает значения от 51.1 до 1/51.1
Что за дикие числа? Определитесь сколько знаков после запятой необходимо. И необходим ли вообще тип float. Что происходит с данными далее?Frosty85 писал(а):array[1024] = {51.1 , 51, 50.9, 50.8,....,0.019646365, 0.019607843, 0.019569472}
И? if (adc < 511)Frosty85 писал(а):Т.е. на резисторе относительно среднего положения влево - коэфф. деления, а вправо - коэфф. умножение.
Код: Выделить всё
volatile unsigned long Per_In=0;
unsigned long per_tmp;
unsigned long adc_tmp;
union
{
struct {
unsigned char lo;
unsigned char hi;
}st;
unsigned int adc;
}data;
adc_tmp=data.adc;
per_tmp = Per_In;
per_tmp/=2;
if(per_tmp){
if (data.adc<=511)
{adc_tmp=adc_tmp/10;}
else {adc_tmp= 1/((adc_tmp-511)/10);}
per_tmp = (long)((float)(per_tmp/data.adc));
}
Значить у нас три положении:Frosty85 писал(а):влево - коэфф. деления, а вправо - коэфф. умножение.
Код: Выделить всё
volatile unsigned long Per_In=0;
unsigned long per_tmp;
unsigned long adc_tmp;
unsigned int k; /* новая переменная */
union
{
struct {
unsigned char lo;
unsigned char hi;
}st;
unsigned int adc;
}data;
adc_tmp=data.adc;
per_tmp = Per_In;
per_tmp/=2;
if(per_tmp){
if (data.adc <= 511){
k = 512-data.adc;
/* делим что-то на етого коефициента k и делим на 10
для нуля:
в if (condition) проверяем меньше ли 511 значить самое маленькое число которое можеть получится ето 512-511=1 - больше нуля*/
}
else{
k = data.adc - 511; /*если ADC=512 (середина) то k=1 будем умножать по 1 */
/* умножаем что-то по етого коефициента k и делим на 10*/
}
}Код: Выделить всё
#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;}
else{k = data.adc - 511;}
per_tmp = (long)((float)(per_tmp/k));
GIE=0;
Per_Out = per_tmp;
GIE=1;
TMR1IE=1;
}
else{
TMR1IE=0;
PIN_OUT=0;
}
}
}
}
/****************************************************************/
Код: Выделить всё
Memory Summary:
Program space used 231h ( 561) of 400h words ( 54.8%)
Data space used 35h ( 53) of 40h bytes ( 82.8%)
EEPROM space used 0h ( 0) of 80h bytes ( 0.0%)
Configuration bits used 1h ( 1) of 1h word (100.0%)
ID Location space used 0h ( 0) of 4h bytes ( 0.0%)