| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| FloatToString в MikroC http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=2362 |
Страница 1 от 2 |
| Автор: | daniel_stefanov [ Нед Май 14, 2006 4:46 pm ] |
| Заглавие: | 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); } } |
|
| Автор: | milenjs [ Нед Май 14, 2006 6:26 pm ] |
| Заглавие: | |
Не се бъркам защото не чувам С-то, но защо си се спрял на това С. Продуктите на Микроелектроника са супер, гледам по форумите че при новите версии генерирания код е доста намален, ИДЕ-то е супер, да не говорим за вградените функции примерно като за работа с PS-2 клавиатура. Моето мнение за начинаещ /субективно/ е Протон бейсика + Протеуса. И малко по темата - защо си се спрял на число с плаваща запетая - излишно и забавящо според мен. За измерване на честота е достатъчно и целочислено - аз ползвам четирибайтово а запетаята си я слагам сам където ми е необходимо - за времеинтервали използвам 1 и 0.1 сек и спрямо това дали искам да ми показва резултата в Hz, Khz, Mhz позиционирам запетайката там където трябва. Не се отказвай и успех! |
|
| Автор: | daniel_stefanov [ Нед Май 14, 2006 7:17 pm ] |
| Заглавие: | |
Ами спрях се на това 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то. Незнам дали успях да обясна добре ама това ми е идеята. Друг метод за измерване на честота засега не мога да се сетя. Как измерването става целочислено с четирибайтово число не мога да разбера, както и какви са тези времеинтервали - съжалявам. Иначе няма да се откажа докато не го направя. Благодаря ти. |
|
| Автор: | the_real_maniac [ Нед Май 14, 2006 8:17 pm ] |
| Заглавие: | |
Абе аз ужким съм добре със С-то , ама нещо ми се губи идеята 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 бита определяше знака , а другото е числото). Нещо от сорта мисля че се случва. Успех ! |
|
| Автор: | daniel_stefanov [ Нед Май 14, 2006 9:08 pm ] | |||||||||
| Заглавие: | ||||||||||
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); } } |
||||||||||
| Автор: | the_real_maniac [ Пон Май 15, 2006 12:07 am ] | |||||||||
| Заглавие: | ||||||||||
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; } Ако след тази промяна пак имаш проблем наистина не знам. едит: я осакати програмата само до този момент - т.е направи си теста на проблема само. По идея да е нещо такова:
И виж какво става |
||||||||||
| Автор: | tropper [ Пон Май 15, 2006 12:11 am ] | |||||||||
| Заглавие: | ||||||||||
А ако не го "каже" според ANSI C по дефаулт се приема ИНТ. |
||||||||||
| Автор: | the_real_maniac [ Пон Май 15, 2006 12:16 am ] |
| Заглавие: | |
ANSI C - да MicroC компилатора - не се знае Според мен или е void или е int (тъй като е embed компилатор и по клоня да е void - default типа, което би означавало че не трябва да връща изобщо стойност Дори и да пише ANSI C съвместим. Той и CSS (PIC C) се води ANSI C , ама мен ако ме питаш не е ANSI C А това ANSI C съвместим се взима с/у какво ... нали някои изадава ала сертификат , който се плаща и нали се сещаш Който плаща ... |
|
| Автор: | ToHu [ Пон Май 15, 2006 8:31 am ] |
| Заглавие: | |
Ами като гледам какво си писал като код, CCS май е доста по ANSI от това. В крайна сметка ANSI дава стандард, а това че имаш допълниелни функции не е проблем, и не го прави не анси, по коро е че в CCS малко някои неща са ги извратили , ама може би и в това има подони извратени неща. И тази функциа флоат то стринг ... ти ли си я писл, вградена ли си е, и защо не ползваш едно форматирано sprintf ? |
|
| Автор: | daniel_stefanov [ Пон Май 15, 2006 10:04 am ] |
| Заглавие: | |
the_real_maniac 1. Поставих отпред пред функцията float, но и с това не се оправиха нещата. 2. Абсолютно правилно си разбрал проблема. Точно така получавам това огромно число с отрицателен знак. За стойността съм сигурен, че е тази, защото и тук имам watch за променливите. Програмата я "осакатих" до там, че буквално изобразявам само числото с плаваща запетая и проблема остана. Още при дефинирането давам стойност (float freq= 3.14;) и пак на променливата се присвоява такова число, което ме кара да си мисля, че проблема не е във функцията, а нещо бъг на компилатора. tropper Така е. Това го пише и в хелпа, ама няма кой да чете ToHu Функцията FloatToStr не съм я писал аз, а я има като екстра с МикроСто. За sprintf мисля, че нестава за този пик, а само за 18та серия. Това го прочетох от хелпа. Вече не знам какво да пробвам, какво ли не опитах и нестава. Май ще минавам на ССSa Ако имате идеи, моля помагайте. |
|
| Автор: | setoy [ Пон Май 15, 2006 11:20 am ] |
| Заглавие: | |
Ами да... имам една идея. Вземи прочети малко за хардуера, с който се опитваш да работиш. Идея си нямаш какво изнасилване за бедния ПИК е тази плаваща запетая |
|
| Автор: | daniel_stefanov [ Пон Май 15, 2006 3:06 pm ] | |||||||||
| Заглавие: | ||||||||||
setoy, съгласен съм че тази операция е доста сложна като сметки, ама чак пак изнасилване 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 (шантавата стойност). Освен грешка в програмата или лош крак
Наистина имаше много мнения по въпроса, но да си призная честно почти нищо не разбрах. Затова избрах да го направя така както си мисля че ще стане. Мисля, че идейно това което си мисля е вярно макар и доста по сложно за контролера, а и вероятно е най-глупавия начин. Искаше ми се първо така да тръгне, а после ще опитам и други варианти. Абе няма да се откажа докато не тръгне Другото за което се замислям е същия код да го компилирам на 18F452 и да видя тогава какво ще се случи. Възможно е проблемът да е от контролера както казва setoy. |
||||||||||
| Автор: | denis_hasan [ Пон Май 15, 2006 3:36 pm ] |
| Заглавие: | |
аз съм ползвал 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) |
|
| Автор: | perlsite [ Пон Май 15, 2006 7:11 pm ] |
| Заглавие: | |
В този конекст не може ли да се ползва тогава функцията sprintf за да преобразува float във форматиран низ? |
|
| Автор: | daniel_stefanov [ Пон Май 15, 2006 7:36 pm ] |
| Заглавие: | |
За съжаление при PIC16F877, неможе. Тази функция в MikroCто може да се използва само при 18та серия |
|
| Страница 1 от 2 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|