|
Не работает с float, mega16 |
|
|
|
Apr 27 2006, 14:30
|

инженер
   
Группа: Свой
Сообщений: 520
Регистрация: 19-09-05
Из: Самара
Пользователь №: 8 701

|
Цитата X = -(log((0.0025*Y)/4.959)/0.029) А также основание логарифма - натуральный, десятичный и диапазон Y, при котором тестирование происходило  А может тяжелый вес для AVR. Советую упростить, хотя так X=-(log(((int)(Y/4)*10000.)/0.143811 Это на первый взгляд, может кто еще проще предложит. Можно, например, константу 0.143811 (это 4.959*0.029) под знак логарифма внести и объединить с 10000.
|
|
|
|
|
Apr 28 2006, 04:00
|

Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 13-01-05
Из: Москва
Пользователь №: 1 922

|
Код следующий:
//Mega16 //iar EW AVR 4.12
#include <iom16.h> #include <ioavr.h> #include <inavr.h> #include <stdlib.h> #include <math.h>
#define NUM_IZM 128
//#define _N0 0x03 //#define _N1 0x9f //#define _N2 0x25 //#define _N3 0x0d //#define _N4 0x99 //#define _N5 0x49 //#define _N6 0x41 //#define _N7 0x1f //#define _N8 0x01 //#define _N9 0x09
// 1-st digit 0x10 // 2-nd digit 0x08 // 3-rd digit 0x04 // 4-th digit 0x02 // 5-th digit 0x01
//fuses 8MHz CKSEL3=0 CKSEL2=1 CKSEL1=0 CKSEL0=0 // SUT1=1 SUT0=0 65ms startup
__flash unsigned char Nums[]={0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09};
#pragma vector = TIMER2_OVF_vect __interrupt void TIMER2_OVF(void);
#pragma vector = TIMER2_COMP_vect __interrupt void TIMER2_COMP(void);
unsigned char print[5]; unsigned char num=0, di=0; unsigned int i=0; unsigned int temp=0, gc=0; //float temperature=0.0;
void init(void); void long2char(unsigned int); unsigned int ADCread(void);
//long int ADCread(void);
void main(void) { init(); di=0; while(1) { temp = ADCread(); gc=(unsigned int)((log(((temp*0.0025)-0.1438)/4.959))/0.029); long2char(gc); } }
unsigned int ADCread(void) { unsigned long ADC=0, tempADC=0; unsigned char i=0; while (i < NUM_IZM) // Усреднение по NUM_IZM замерам { // VCC ref and ADCx ADMUX = (1<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0); //Начинаем одиночное преобразование // ADLAR=0 -> ADCH ------98 ADCL 76543210 ADCSRA |= (1<<ADSC); while (ADCSRA & (1<<ADSC)); // ADCSRA |= (1<<ADSC); // ADLAR=1 -> ADCH 98765432 ADCL 10------ // while(!(ADCSRA & (1 << ADIF))); //Ждем окончания преобразования ADCSRA |= (1<<ADIF); //Сбрасываем флаг tempADC = ADCL; tempADC += (ADCH<<8); ADC +=tempADC; i++; } ADC /= NUM_IZM; return ((unsigned int)ADC); }
#pragma vector = TIMER2_OVF_vect __interrupt void TIMER2_OVF(void) { di++; if (di>=5) { di=0; // i++; } }
#pragma vector = TIMER2_COMP_vect __interrupt void TIMER2_COMP(void) { PORTB = 0x1f^(1<<di); PORTC = Nums[print[di]]; }
void long2char(unsigned int input_num) { unsigned char ni=5; while (ni>0) { print[ni-1]=div(input_num,10).rem; input_num /=10; ni--; } }
#pragma inline=forced void init (void) { //port setup using portb & portc
PORTC = (1<<PORTC7) | (1<<PORTC6) | (1<<PORTC5) | (1<<PORTC4) | (1<<PORTC3) | (1<<PORTC2) | (1<<PORTC1) | (1<<PORTC0); DDRC = (1<<DDC7) | (1<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0); PORTB = (1<<PORTB4) | (1<<PORTB3) | (1<<PORTB2) | (1<<PORTB1) | (1<<PORTB0); DDRB = (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
TCCR2 = (0<<FOC2) | (0<<WGM20) | (0<<COM21) | (0<<COM20) | (0<<WGM21) | (0<<CS22) | (0<<CS21) | (1<<CS20); TIFR = (1<<OCF2) | (1<<TOV2); //clear TIMSK = (1<<OCIE2) | (1<<TOIE2); //enable interrupt
TCNT2 = 0; OCR2 = 0x7f;
//ADC init //internal 2.56v with external capacitor at AREF pin //ADC0 single ended ADMUX = (1<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0);
ADCSRA = (1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (1<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);
ADCSRA |= (1<<ADSC); while (ADCSRA & (1<<ADSC)); //wait for end conversion ADCSRA=ADCSRA; //clear ADCSRA __enable_interrupt();
}
|
|
|
|
|
May 2 2006, 06:51
|
Знающий
   
Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32

|
Цитата(Serg_greS) а на float я стал грешить после того, как сделал переменную gc типа float : Предлагаю операнды во float-point арифметике всё же приводить к правильному типу. В данном случае это будет выглядеть так: gc = 120.0 - ((float)(0x3ff-temp))*0.48;
--------------------
Главная линия этого опуса ясна мне насквозь!
|
|
|
|
|
May 3 2006, 06:18
|

Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 13-01-05
Из: Москва
Пользователь №: 1 922

|
подскажите в чем проблема при вычислении, если вот эту часть Цитата temp = ADCread(); gc=(unsigned int)((log(((temp*0.0025)-0.1438)/4.959))/0.029); long2char(gc); заменить на : ADCread(); if (temp<37) temp=37; gc=(unsigned int)(22499365 - 22473186*(powf(temp,0.00015))); long2char(gc); А то выяснилось, что такая функция намного лучше приводит значения полученные с АЦП к тем значениям, которым они соответствуют. В AVR Studio вся арифметика проходит гладко и без сбоев: с АЦП 965 --> gc=3002 с АЦП 0 --> 37 --> gc=14002 в реальном железе индикаторы не горят, хотя нули должны гореть всегда. и еще: в свойствах проекта CSTACK=0x256 RSTACK=128 надо ли их уменьшить/увеличить?
Сообщение отредактировал Serg_greS - May 3 2006, 06:32
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|