Отговори на тема  [ 24 мнения ]  Отиди на страница 1, 2  Следваща
FloatToString в MikroC 
Автор Съобщение
Ранг: Ориентиран
Ранг: Ориентиран
Аватар

Регистриран на: Нед Мар 27, 2005 12:40 am
Мнения: 206
Местоположение: София
Мнение FloatToString в MikroC
Здравейте,
Започвам да тъпча на едно място и не мога да измисля вече нищо. Имам чувството че този компилатор имам някакъв бъг или пък не..... може и аз да греша ама блокирах вече.Не мога да изобразя на LCD число от тип плаваща запетая (float). Проблемът е, че когато пусна дебъгера на този ред се случва някаква идиотщина и немога да разбера какво става
frequency(int par_1, int par_2) {
float freq;
freq = 3.14;
return freq;
}
вместо функцията да върне стойност 3.14, тя връща -2143289344. Е немога да си обясня защо. Ето го целия сорс. Това след време трябва да е честотомер. ......... Не се смейте :D . Първа програма ми е на Ц. Тази готова функция вместо да ме улесни, тя ме забави много. Вече бях решил сам да си пиша тази функция.
unsigned char oldstate;
int br = 0;
int n = 10; // Number of mesurment
int ctr;
char i_text[13];
float res;

void InitMain() {

ctr = 0;

PORTB = 0; // set PORTB to 0
TRISB = 0; // designate portb pins as output

ADCON1 = 6; // All ADC pins to digital I/O
PORTA = 255;
TRISA = 255; // PORTA is input

TMR0 = 0; // Clear Timer0
OPTION_REG.T0CS = 0;
OPTION_REG.PSA = 0;
OPTION_REG.PS2 = 1;
OPTION_REG.PS1 = 1;
OPTION_REG.PS0 = 1;

INTCON.T0IE = 1;
INTCON.GIE = 1;
}

void interrupt() {
ctr++;
INTCON.T0IF = 0;
}

void start_button() {
TMR0 = 0; ctr = 0; br = 0;
while (br<n) {
if (Button(&PORTA, 0, 1, 1)) oldstate = 1;
if (oldstate && Button(&PORTA, 0, 1, 0)) {
oldstate = 0;
br++;
}
}
}

frequency(int par_1, int par_2) {
float freq;
freq = 3.14;
return freq;
}

void main() {
initMain();

LCD_Init(&PORTB);
LCD_Cmd(LCD_CLEAR);
LCD_Cmd(LCD_CURSOR_OFF);
LCD_Out(1, 1, "Frequency is:");

while(1) {

start_button();
res = frequency(br, ctr);

IntToStr(br,i_text);
LCD_Out(2, 0, i_text);
FloatToStr(res,i_text);
LCD_Out(2, 7, i_text);
}
}


Нед Май 14, 2006 4:46 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Мар 08, 2006 2:12 pm
Мнения: 2017
Местоположение: Котел
Мнение 
Не се бъркам защото не чувам С-то, но защо си се спрял на това С. Продуктите на Микроелектроника са супер, гледам по форумите че при новите версии генерирания код е доста намален, ИДЕ-то е супер, да не говорим за вградените функции примерно като за работа с PS-2 клавиатура.
Моето мнение за начинаещ /субективно/ е Протон бейсика + Протеуса.
И малко по темата - защо си се спрял на число с плаваща запетая - излишно и забавящо според мен. За измерване на честота е достатъчно и целочислено - аз ползвам четирибайтово а запетаята си я слагам сам където ми е необходимо - за времеинтервали използвам 1 и 0.1 сек и спрямо това дали искам да ми показва резултата в Hz, Khz, Mhz позиционирам запетайката там където трябва.
Не се отказвай и успех!


Нед Май 14, 2006 6:26 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран
Аватар

Регистриран на: Нед Мар 27, 2005 12:40 am
Мнения: 206
Местоположение: София
Мнение 
Ами спрях се на това C, поради същите причини които изброяваш, а именно много добър набор от готови функции, много добра среда за програмиране - ИДЕ, най-близко до класическото C (Borland C), с което се занимавах някога малко. След това мисля да се позанимавам и с PCW C Compiler IDE.
Сега ще обясня, защо ползвам плаваща запетая:
Работя с PIC16F877 на 20MHz. Таймер 0 е конфигуриран да инкрементира по вътрешният цикъл, както и прескалера е свързан с Таймер 0. Прескалера е 1/256. т.е 20MHz/4MHz=5MHz/256(брояч)/256(прескалер)=76.29394531.Променливата ctr ми дава информация колко пъти е препълнен таймера за определен брой измервания (br). Аз правя 10 измервания и при 1 Hz излиза че таймера се е препълнил 762 пъти. Това го симулирам на Proteus. Оттук излиза, че 762/10=76,2. Като разделя горното число на това получавам за честотата 1,001232878Hz. Ето за това ми е необходимо да изобраявам числа с плаваща запетая. Това последното число искам да го изчисля с функцията FloatToStr и да го покажа на LCDто. Незнам дали успях да обясна добре ама това ми е идеята. Друг метод за измерване на честота засега не мога да се сетя. Как измерването става целочислено с четирибайтово число не мога да разбера, както и какви са тези времеинтервали - съжалявам. Иначе няма да се откажа докато не го направя. Благодаря ти. :)


Нед Май 14, 2006 7:17 pm
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Пет Авг 19, 2005 11:38 am
Мнения: 978
Местоположение: Europe -> BG
Мнение 
Абе аз ужким съм добре със С-то , ама нещо ми се губи идеята :-)

frequency(int par_1, int par_2) {
float freq;
freq = 3.14;
return freq;
}

Значи първо задай едно float тип на функцията (т.е че връща резултат от тип float (!) ).
Да не говорим , че аз лично обичам да си правя прототипите на функциите , както си му е реда.

Второ frequency приема два аргумента / всичко int /, ама никъде не го викаш с аргументи и никъде не ги ползваш дори и да го извикаш :? / но сигурно още тепърва пишеш идеята си , та затова.

edit: явно правиш тест, та въобще защо декларираш локална променлива , даваш й стойност и я връщаш :-)
направо за теста давай да връща стойността

return 3.14;

Проблема не идва от това дали се знае , че 3.14 е число с плаваща запетая , ами от това дали операциите , които и прилагаш знаят че е число с плаваща запетая :-)

3.14 като float има бинарно изразяване ХХХХХХХХХХХ , като еди кои си битове определят цялат част , другите часта след плаващата запетая, но ако не знаеш това и го гледаш примерно като signed int (май MSB бита определяше знака , а другото е числото). Нещо от сорта мисля че се случва.

Успех !

_________________
един факт :-)
Съжалявам , че исках да помогна ...


Нед Май 14, 2006 8:17 pm
Профил ICQ
Ранг: Ориентиран
Ранг: Ориентиран
Аватар

Регистриран на: Нед Мар 27, 2005 12:40 am
Мнения: 206
Местоположение: София
Мнение 
float frequency(int par_1, int par_2) {
float freq;
freq = 3.14;
return freq;
}
Предполагам имаш в предвид това. Сега ще опитам за да видя дали не греша тук.
Да правя тест, затова не ползвам двата аргумента на функцията, а просто се опитвам да върна число от тип float.
Цитат:
Проблема не идва от това дали се знае , че 3.14 е число с плаваща запетая , ами от това дали операциите , които и прилагаш знаят че е число с плаваща запетая

Ами така е но аз в случая не правя никакви операции, а само искам да изобразя числото и съответно ползвам функцията която има предназначение да преобразува такова число (fload) в стринг и този стринг да го изобрази на ЛЦД, т.е не би трябвало да има проблем защото това са вградени функции. :( . Иначе като код мисля че не бъркам и не мога да си обясня защо получавам такива бози. Ако някой може и при него да го компилира за да види какво излиза ще е добре.
unsigned char oldstate;
int br = 0;
int n = 10; // Number of mesurment
int ctr;
char i_text[13];
float res;

void InitMain() {

ctr = 0;

PORTB = 0; // set PORTB to 0
TRISB = 0; // designate portb pins as output

ADCON1 = 6; // All ADC pins to digital I/O
PORTA = 255;
TRISA = 255; // PORTA is input

TMR0 = 0; // Clear Timer0
OPTION_REG.T0CS = 0;
OPTION_REG.PSA = 0;
OPTION_REG.PS2 = 1;
OPTION_REG.PS1 = 1;
OPTION_REG.PS0 = 1;

INTCON.T0IE = 1;
INTCON.GIE = 1;
}

void interrupt() {
ctr++;
INTCON.T0IF = 0;
}

void start_button() {
TMR0 = 0; ctr = 0; br = 0;
while (br<n) {
if (Button(&PORTA, 0, 1, 1)) oldstate = 1;
if (oldstate && Button(&PORTA, 0, 1, 0)) {
oldstate = 0;
br++;
}
}
}

frequency(int par_1, int par_2) {
float freq;
freq = 3.14;
return freq;
}


void main() {
initMain();

LCD_Init(&PORTB);
LCD_Cmd(LCD_CLEAR);
LCD_Cmd(LCD_CURSOR_OFF);
LCD_Out(1, 1, "Frequency is:");

while(1) {

start_button();
res = frequency(br, ctr);

IntToStr(br,i_text);
LCD_Out(2, 0, i_text);
FloatToStr(res,i_text);
LCD_Out(2, 7, i_text);
}
}


Нед Май 14, 2006 9:08 pm
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Пет Авг 19, 2005 11:38 am
Мнения: 978
Местоположение: Europe -> BG
Мнение 
1.Е какво стана ?

2.Значи аз така разбирам проблема:

res = frequency(br, ctr);

и получаваш res = -217xxxxxx (странната стойност)

Обаче сигурен ли си и как разбираш , че res е равно на толквоа след присвояването (сигурно имаш някакъв watch за променливите като при mplab) ?

3.Щом функцията ще връща стоност float трябва да го каже, т.е точно това имам предвид:


float frequency(int par_1, int par_2) {
float freq;
freq = 3.14;
return freq;
}

Ако след тази промяна пак имаш проблем наистина не знам.

едит:

я осакати програмата само до този момент - т.е направи си теста на проблема само.
По идея да е нещо такова:

Код:

float func(void);

int main(void)
{

        float res=0;

        res = func();

        printf("%f\n", res);

        return 0;

}

float func(void)
{

        float freq = 3.14;
        return freq;
}


И виж какво става

_________________
един факт :-)
Съжалявам , че исках да помогна ...


Последна промяна the_real_maniac на Пон Май 15, 2006 12:12 am, променена общо 1 път



Пон Май 15, 2006 12:07 am
Профил ICQ
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Вто Сеп 20, 2005 10:01 pm
Мнения: 128
Местоположение: София
Мнение 
the_real_maniac написа:
...3.Щом функцията ще връща стоност float трябва да го каже...

А ако не го "каже" според ANSI C по дефаулт се приема ИНТ.

_________________
късото съединение прави силата
-------------------------------
http://www.zahranvane.com/


Пон Май 15, 2006 12:11 am
Профил ICQ WWW
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Пет Авг 19, 2005 11:38 am
Мнения: 978
Местоположение: Europe -> BG
Мнение 
ANSI C - да :-)

MicroC компилатора - не се знае :-D, въпреки това ясно е , че няма по подразбиране да е float.
Според мен или е void или е int (тъй като е embed компилатор и по клоня да е void - default типа, което би означавало че не трябва да връща изобщо стойност :lol:)

Дори и да пише ANSI C съвместим.
Той и CSS (PIC C) се води ANSI C , ама мен ако ме питаш не е ANSI C ;-)
А това ANSI C съвместим се взима с/у какво ... нали някои изадава ала сертификат , който се плаща и нали се сещаш :-)
Който плаща ... :-)

_________________
един факт :-)
Съжалявам , че исках да помогна ...


Пон Май 15, 2006 12:16 am
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30684
Местоположение: София
Мнение 
Ами като гледам какво си писал като код, CCS май е доста по ANSI от това. В крайна сметка ANSI дава стандард, а това че имаш допълниелни функции не е проблем, и не го прави не анси, по коро е че в CCS малко някои неща са ги извратили , ама може би и в това има подони извратени неща. И тази функциа флоат то стринг ... ти ли си я писл, вградена ли си е, и защо не ползваш едно форматирано sprintf ?


Пон Май 15, 2006 8:31 am
Профил
Ранг: Ориентиран
Ранг: Ориентиран
Аватар

Регистриран на: Нед Мар 27, 2005 12:40 am
Мнения: 206
Местоположение: София
Мнение 
the_real_maniac
1. Поставих отпред пред функцията float, но и с това не се оправиха нещата.
2. Абсолютно правилно си разбрал проблема. Точно така получавам това огромно число с отрицателен знак. За стойността съм сигурен, че е тази, защото и тук имам watch за променливите.
Програмата я "осакатих" до там, че буквално изобразявам само числото с плаваща запетая и проблема остана. Още при дефинирането давам стойност (float freq= 3.14;) и пак на променливата се присвоява такова число, което ме кара да си мисля, че проблема не е във функцията, а нещо бъг на компилатора.
tropper
Така е. Това го пише и в хелпа, ама няма кой да чете :) . Сега го направих, но както съм писал по-горе ефекта е нулев.
ToHu
Функцията FloatToStr не съм я писал аз, а я има като екстра с МикроСто. За sprintf мисля, че нестава за този пик, а само за 18та серия. Това го прочетох от хелпа.

Вече не знам какво да пробвам, какво ли не опитах и нестава. Май ще минавам на ССSa :) . Този компилатор добре е направен и е доста удобен, ама поне да му работеха екстрите.
Ако имате идеи, моля помагайте.


Пон Май 15, 2006 10:04 am
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Пет Фев 17, 2006 9:17 am
Мнения: 765
Местоположение: Стара Загора
Мнение 
Ами да... имам една идея. Вземи прочети малко за хардуера, с който се опитваш да работиш. Идея си нямаш какво изнасилване за бедния ПИК е тази плаваща запетая :lol: Спокойно можеш да минеш и без нея за целите, които гониш. Значи най-добре е преди да почнеш да пишеш и да се ядосваш че не става така както го искаш, по-добре първо си обмисли задачата как може да стане НАЙ-ЛЕСНО и за теб и за контролера. Как точно за конкретния случай ти го казахме вече няколко пъти в другата тема. А че функциите на микроС че може и да не работят както трябва - това си е съвсем отделен въпрос :lol: Не съм се занимавал сериозно с него, не ми хареса кода, който прави и освен това не ми стана ясно как въобще става дебъгването с него, но има и колеги които го харесват и ползват....


Пон Май 15, 2006 11:20 am
Профил ICQ
Ранг: Ориентиран
Ранг: Ориентиран
Аватар

Регистриран на: Нед Мар 27, 2005 12:40 am
Мнения: 206
Местоположение: София
Мнение 
setoy, съгласен съм че тази операция е доста сложна като сметки, ама чак пак изнасилване :D . Сметнах времето за което ми се изпълнява функцията флоат то стринг и то е 8,46мс. Това не е чак такъв проблем за този контролер имаики в предвид, че работи на 20МХц. Проблемът е, че още в инициализацията на променливата присвоява такова число, а за това не се иска бързина.
unsigned char oldstate;
int br = 0;
int n = 10; // Number of mesurment
int ctr;
char i_text[13];
float freq = 3.14;
float res;
Осакатих програмата и още тук (в червено) на freq се присвоява -217xxxxxx (шантавата стойност). Освен грешка в програмата или лош крак :D , не виждам каква може да е причината.
Цитат:
Как точно за конкретния случай ти го казахме вече няколко пъти в другата тема.

Наистина имаше много мнения по въпроса, но да си призная честно почти нищо не разбрах. Затова избрах да го направя така както си мисля че ще стане. Мисля, че идейно това което си мисля е вярно макар и доста по сложно за контролера, а и вероятно е най-глупавия начин. Искаше ми се първо така да тръгне, а после ще опитам и други варианти. Абе няма да се откажа докато не тръгне :D, но май ще сменям този компилатор с CCS. Въпреки че ми се вижда на пръв поглед малко неразбираем.
Другото за което се замислям е същия код да го компилирам на 18F452 и да видя тогава какво ще се случи. Възможно е проблемът да е от контролера както казва setoy.


Пон Май 15, 2006 3:06 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Сря Окт 26, 2005 7:17 pm
Мнения: 106
Местоположение: Sofia
Мнение 
аз съм ползвал PCW C Compiler IDE. работи перфектон с float тип данни
.........
float val;
printf(lcd_func,"%f1.3", val);


lcd_func e функция която връща 1 байт (char), който ще се изписва на екрана
и на диспея се появи стойността на val
1.3 означава че има 1 цифра толяво на запетаята и 3 цифри дробна част


гадното беше че числата между (0 и 1) и (-1 и 0) е изписваха без 0 ( .23423 или -.9345)


Пон Май 15, 2006 3:36 pm
Профил ICQ
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пон Апр 17, 2006 1:44 pm
Мнения: 291
Мнение 
В този конекст не може ли да се ползва тогава функцията sprintf за да преобразува float във форматиран низ?


Пон Май 15, 2006 7:11 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран
Аватар

Регистриран на: Нед Мар 27, 2005 12:40 am
Мнения: 206
Местоположение: София
Мнение 
За съжаление при PIC16F877, неможе. Тази функция в MikroCто може да се използва само при 18та серия :wink:


Пон Май 15, 2006 7:36 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 24 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни