|
Виж темите без отговор | Виж активните теми
Дата и час: Пон Юли 27, 2026 7:46 pm
| Автор |
Съобщение |
|
daniel_stefanov
Ранг: Ориентиран
Регистриран на: Нед Мар 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. Е немога да си обясня защо. Ето го целия сорс. Това след време трябва да е честотомер. ......... Не се смейте  . Първа програма ми е на Ц. Тази готова функция вместо да ме улесни, тя ме забави много. Вече бях решил сам да си пиша тази функция.
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 |
|
 |
|
milenjs
Ранг: Форумен бог
Регистриран на: Сря Мар 08, 2006 2:12 pm Мнения: 2017 Местоположение: Котел
|
Не се бъркам защото не чувам С-то, но защо си се спрял на това С. Продуктите на Микроелектроника са супер, гледам по форумите че при новите версии генерирания код е доста намален, ИДЕ-то е супер, да не говорим за вградените функции примерно като за работа с PS-2 клавиатура.
Моето мнение за начинаещ /субективно/ е Протон бейсика + Протеуса.
И малко по темата - защо си се спрял на число с плаваща запетая - излишно и забавящо според мен. За измерване на честота е достатъчно и целочислено - аз ползвам четирибайтово а запетаята си я слагам сам където ми е необходимо - за времеинтервали използвам 1 и 0.1 сек и спрямо това дали искам да ми показва резултата в Hz, Khz, Mhz позиционирам запетайката там където трябва.
Не се отказвай и успех!
|
| Нед Май 14, 2006 6:26 pm |
|
 |
|
daniel_stefanov
Ранг: Ориентиран
Регистриран на: Нед Мар 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 |
|
 |
|
the_real_maniac
Ранг: Почетен член
Регистриран на: Пет Авг 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 |
|
 |
|
daniel_stefanov
Ранг: Ориентиран
Регистриран на: Нед Мар 27, 2005 12:40 am Мнения: 206 Местоположение: София
|
float frequency(int par_1, int par_2) {
float freq;
freq = 3.14;
return freq;
}
Предполагам имаш в предвид това. Сега ще опитам за да видя дали не греша тук.
Да правя тест, затова не ползвам двата аргумента на функцията, а просто се опитвам да върна число от тип float.
Ами така е но аз в случая не правя никакви операции, а само искам да изобразя числото и съответно ползвам функцията която има предназначение да преобразува такова число (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 |
|
 |
|
the_real_maniac
Ранг: Почетен член
Регистриран на: Пет Авг 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;
}
Ако след тази промяна пак имаш проблем наистина не знам.
едит:
я осакати програмата само до този момент - т.е направи си теста на проблема само.
По идея да е нещо такова:
И виж какво става
Последна промяна the_real_maniac на Пон Май 15, 2006 12:12 am, променена общо 1 път
|
| Пон Май 15, 2006 12:07 am |
|
 |
|
tropper
Ранг: Новодошъл
Регистриран на: Вто Сеп 20, 2005 10:01 pm Мнения: 128 Местоположение: София
|
А ако не го "каже" според ANSI C по дефаулт се приема ИНТ.
_________________късото съединение прави силата ------------------------------- http://www.zahranvane.com/
|
| Пон Май 15, 2006 12:11 am |
|
 |
|
the_real_maniac
Ранг: Почетен член
Регистриран на: Пет Авг 19, 2005 11:38 am Мнения: 978 Местоположение: Europe -> BG
|
ANSI C - да
MicroC компилатора - не се знае  , въпреки това ясно е , че няма по подразбиране да е float.
Според мен или е void или е int (тъй като е embed компилатор и по клоня да е void - default типа, което би означавало че не трябва да връща изобщо стойност  )
Дори и да пише ANSI C съвместим.
Той и CSS (PIC C) се води ANSI C , ама мен ако ме питаш не е ANSI C
А това ANSI C съвместим се взима с/у какво ... нали някои изадава ала сертификат , който се плаща и нали се сещаш
Който плаща ... 
|
| Пон Май 15, 2006 12:16 am |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30686 Местоположение: София
|
Ами като гледам какво си писал като код, CCS май е доста по ANSI от това. В крайна сметка ANSI дава стандард, а това че имаш допълниелни функции не е проблем, и не го прави не анси, по коро е че в CCS малко някои неща са ги извратили , ама може би и в това има подони извратени неща. И тази функциа флоат то стринг ... ти ли си я писл, вградена ли си е, и защо не ползваш едно форматирано sprintf ?
|
| Пон Май 15, 2006 8:31 am |
|
 |
|
daniel_stefanov
Ранг: Ориентиран
Регистриран на: Нед Мар 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 |
|
 |
|
setoy
Ранг: Почетен член
Регистриран на: Пет Фев 17, 2006 9:17 am Мнения: 765 Местоположение: Стара Загора
|
Ами да... имам една идея. Вземи прочети малко за хардуера, с който се опитваш да работиш. Идея си нямаш какво изнасилване за бедния ПИК е тази плаваща запетая  Спокойно можеш да минеш и без нея за целите, които гониш. Значи най-добре е преди да почнеш да пишеш и да се ядосваш че не става така както го искаш, по-добре първо си обмисли задачата как може да стане НАЙ-ЛЕСНО и за теб и за контролера. Как точно за конкретния случай ти го казахме вече няколко пъти в другата тема. А че функциите на микроС че може и да не работят както трябва - това си е съвсем отделен въпрос  Не съм се занимавал сериозно с него, не ми хареса кода, който прави и освен това не ми стана ясно как въобще става дебъгването с него, но има и колеги които го харесват и ползват....
|
| Пон Май 15, 2006 11:20 am |
|
 |
|
daniel_stefanov
Ранг: Ориентиран
Регистриран на: Нед Мар 27, 2005 12:40 am Мнения: 206 Местоположение: София
|
setoy, съгласен съм че тази операция е доста сложна като сметки, ама чак пак изнасилване  . Сметнах времето за което ми се изпълнява функцията флоат то стринг и то е 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 (шантавата стойност). Освен грешка в програмата или лош крак  , не виждам каква може да е причината.
Наистина имаше много мнения по въпроса, но да си призная честно почти нищо не разбрах. Затова избрах да го направя така както си мисля че ще стане. Мисля, че идейно това което си мисля е вярно макар и доста по сложно за контролера, а и вероятно е най-глупавия начин. Искаше ми се първо така да тръгне, а после ще опитам и други варианти. Абе няма да се откажа докато не тръгне  , но май ще сменям този компилатор с CCS. Въпреки че ми се вижда на пръв поглед малко неразбираем.
Другото за което се замислям е същия код да го компилирам на 18F452 и да видя тогава какво ще се случи. Възможно е проблемът да е от контролера както казва setoy.
|
| Пон Май 15, 2006 3:06 pm |
|
 |
|
denis_hasan
Ранг: Новодошъл
Регистриран на: Сря Окт 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 |
|
 |
|
perlsite
Ранг: Ориентиран
Регистриран на: Пон Апр 17, 2006 1:44 pm Мнения: 291
|
В този конекст не може ли да се ползва тогава функцията sprintf за да преобразува float във форматиран низ?
|
| Пон Май 15, 2006 7:11 pm |
|
 |
|
daniel_stefanov
Ранг: Ориентиран
Регистриран на: Нед Мар 27, 2005 12:40 am Мнения: 206 Местоположение: София
|
За съжаление при PIC16F877, неможе. Тази функция в MikroCто може да се използва само при 18та серия 
|
| Пон Май 15, 2006 7:36 pm |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 1 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|