View previous topic :: View next topic |
Author |
Message |
mayler
Joined: 13 Nov 2008 Posts: 10
|
_fixed(n) bugged? |
Posted: Thu Nov 13, 2008 4:20 pm |
|
|
Hi,
I'm trying to use the _fixed(n) qualifier but I'm having serious problems. When I declare the variable in main(), it works normally. When I use a variable in a function, simply the values are not loaded correctly.
The assembly code is totally wrong...
Using : CCS 4.074 / 18Fxxx
Here is a variable in main() :
Code: | .................... unsigned int16 _fixed(3) point = 12.354;
1D54: MOVLW 30
1D56: MOVLB 3
1D58: MOVWF point+1
1D5A: MOVLW 42
1D5C: MOVWF point
|
Here the code generated is ok.
But here...
Code: | .................... long binary_search_K(unsigned int16 _fixed(3) key)
.................... {
.................... long low, high, mid;
.................... unsigned int16 _fixed(3) test=12.23;
*
0E94: MOVLB 4
0E96: CLRF test
0E98: CLRF test+1
|
It clears the variable without reason.
Is it something I'm doing wrong?
If it's bugged, what can I do to contour this problem (without using float solution) because I have two tables with almost 4000 values.
Thanks for the help! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Nov 13, 2008 5:29 pm |
|
|
You didn't post a test program, so I tried to make one for the 18F452
using your code fragments. With vs. 4.081 or 4.082 it caused a GPF if
"_fixed" is used. So I give up. |
|
|
mayler
Joined: 13 Nov 2008 Posts: 10
|
|
Posted: Thu Nov 13, 2008 5:54 pm |
|
|
Thanks for the reply PCM
Here is the code :
main.h
Code: | #include <18F452.h>
#device adc=8
#case
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV27 //Brownout reset at 2.7V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOCPB //No Boot Block code protection
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#ZERO_RAM
#use delay(clock=20M) |
main.c
Code: |
#include "main.h"
unsigned int16 _fixed(3) const tableK[] = {0.000,0.039,0.079,0.119,0.158}; // there are 1500 values here. I put only 5 for simplicity.
long binary_search_K(unsigned int16 _fixed(3) key)
{
long low, high, mid;
low = 0; high = 5-1;
while(low <= high)
{
mid = (low+high)/2;
if(key<tableK[mid]) high = mid-1;
else if(key > tableK[mid]) low = mid+1;
else return mid;
}
printf(lcd_putc,"\a\b%02.3w",tableK[mid]); //debug purpose.
return -1;
}
void main()
{
int temp=0;
long count=0;
float result;
int1 ch=0;
float avg[250];
unsigned int iter=0;
signed int16 bug;
unsigned int16 _fixed(3) point;
bool full=false;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
//setup_comparator(NC_NC_NC_NC);
//setup_vref(FALSE);
delay_ms(1000);
point = 2.354;
printf("%02.3w",point);
binary_search_K(10457);
} |
Basically this is the code... The most important part.
About the GPF... Randomly the compiler rejects to compile, giving error -200 (Compiler internal error). If I put another variable, or change something (last time i changed to _fixed(2) in table) and worked... After the first successfull compilation, I can go back what i want ( _fixed(3) ) and it will compile normally... But this problem with _fixed occurs with any 18F ( Tried with 18F458 and 18F4550 and the same ).
If you can test for me, i will appreciate.
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Nov 13, 2008 6:09 pm |
|
|
It still GPF's. If I delete all the _fixed() keywords, then it doesn't GPF.
This is with vs. 4.081. I don't believe it works. I don't want to spend
any more time on it. |
|
|
mayler
Joined: 13 Nov 2008 Posts: 10
|
|
Posted: Thu Nov 13, 2008 6:16 pm |
|
|
So, it´s bugged (much more in newer versions). I transformed all variables in table in long and adapted some parts to continue my program. I am using %w (still working )
Thanks PCM! |
|
|
Guest
|
|
Posted: Sat Nov 15, 2008 11:19 am |
|
|
Funny (or not if you are wasting time on this) but the Bug gets WORSE as the versions increase.....
I have version 4.032 and when I tested the fixed stuff when this version came out I saw that it at least appeared to work. But I eventually felt that it did not do what I wanted it to do so I still use my own fixed routines.
Still an interesting feature of this compiler.... If it only worked.
Sthev H. |
|
|
Guest
|
|
Posted: Sat Nov 15, 2008 3:24 pm |
|
|
Hi
Maybe make your lookup list mul. with 1000 without _fixed...? |
|
|
mayler
Joined: 13 Nov 2008 Posts: 10
|
|
Posted: Sat Nov 15, 2008 7:02 pm |
|
|
Yeah... When i used the 4.037, the _fixed was working properly... Now is totally broken...
I found another bug, when I used (int var[8]) as parameter... It´s pointing to wrong address and making error. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Nov 15, 2008 7:41 pm |
|
|
Post a short, compilable program that shows the problem. Post the
compiler version that you are using for this test. |
|
|
eskachig
Joined: 27 Mar 2009 Posts: 8
|
|
Posted: Fri May 15, 2009 6:45 pm |
|
|
Has anyone else played around with this? I'm using 4.084 and it seems like addition and subtraction works ok, but multiplication and division are all messed up.
Debugger integration is pretty horrendous too - reported values are frequently incorrect.
Come to think of it, if anyone knows of an easy fixed point number implementation I'd love a link.
Oh, and here's my little test stub, ignore the names. My dev board doesn't support sending RS232 to the debugger so I just add result to the watch list and single step through.
Code: |
#include <18f8722.h>
#device ICD=TRUE
#fuses DEBUG
#use delay(clock=24MHZ, crystal=6MHZ)
#use RS232(DEBUGGER)
int result = 0;
int i = 5;
int32 _fixed(2) dollars = 0;
int32 _fixed(2) cents = 0;
int32 _fixed(2) resultF = 0;
void main (){
cents = 3.56;
dollars = 2.30;
resultF = 0;
result = (int) dollars;
result = (int) cents;
result = (int)(dollars + cents);
result = (int)(cents - dollars);
result = (int)(dollars * cents);
result = (int)(dollars + cents);
result = (int)(dollars + i);
result = (int)(dollars * 5);
result = (int)(dollars * 5.9);
result = (int)(dollars * i);
result = (int)(dollars * 5);
resultF = cents + dollars;
result = (int) resultF;
resultF = cents - dollars;
result = (int) resultF;
resultF = cents * dollars;
result = (int) resultF;
resultF = cents + dollars;
result = (int) resultF;
}
|
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat May 16, 2009 12:40 am |
|
|
A general comment first: As far as I see, the CCS _fixed() operation is only mentioned in a single sentence in the manual.
Quote: | _fixed(n) Creates a fixed point decimal number where n is how many decimal places to implement. |
Do you know from this specification, how it's supposed to work?
1. In your example, you are assigning int32 _fixed(2) to int, which is int8 implicitely. Also if you use int32, I wonder, which result should be expected from this operation. I don't see an obvious meaning.
2. If you understand _fixed basically as a interpretation of an integer value with additional operations for constants and (hopefully) for scanf() and printf(), it's clear that addition and substraction should always work, and they do.
3. But how about multiply and division? In the internal numerical operation, a scaling would be necessary. In the assembler code, you can see additional operations, involving a factor of 100, but the result is incorrect anyway. But even, if the scaling would work correctly, what do you expect for the number range? If you have int16 _fixed(2) 1.00 * 10.00, the multiply goes beyond the int16 range. Will the operation use an intermediate int32 result, as necessary?
Seriously, I'm not motivated to evaluate the CCS _fixed() feature without a specification. Or do you know a specification, e.g. from a C standard that should be assumed in this case.
The usual term for this kind of software features is unsupported, I think.
P.S.: For printf of _fixed values, only the w type specifier seems to be accepted by PCH. No signed print specifier available. |
|
|
|