View previous topic :: View next topic |
Author |
Message |
Eddy71ua
Joined: 23 Sep 2009 Posts: 55 Location: Ukraine
|
Dividend not work v5.021 SOLVED |
Posted: Sun Mar 09, 2014 7:51 am |
|
|
I try this: Tmp16 = (int16)(Tmp16 / 100);
And get this: Code: |
....................
00F7: MOVF 59,W
00F8: MOVWF 5B
00F9: MOVF 58,W
00FA: MOVWF 5A
00FB: CLRF 5D
00FC: MOVLW 64
00FD: MOVWF 5C
*
0122: MOVF 22,W
0123: MOVWF 59
0124: MOVF 21,W
0125: MOVWF 58
|
Function not work?
Last edited by Eddy71ua on Mon Mar 10, 2014 3:42 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Mar 09, 2014 9:30 am |
|
|
You really need to post a short, compilable program that shows the problem!
Posting 11 lines of assembler just doesn't show us what is going on or HOW it was created.
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Mar 09, 2014 12:02 pm |
|
|
In the include file for the processor, rem out the line near the top 'nolist'. Recompile. You will suddenly find that the code for internal functions like division will appear in the listing. Currently the actual division is the '*' part....
Test with a simple test using printf.
Print Tmp16. Then divide it, and print the result.
Your cast does nothing. Tmp16 is already an int16, and as such the result from the sum will be an int16. I'd suspect your actual problem is somewhere else with what is in the variable or what you 'expect'. Remember 99/100 for example will give 0.
Best Wishes |
|
|
Eddy71ua
Joined: 23 Sep 2009 Posts: 55 Location: Ukraine
|
|
Posted: Mon Mar 10, 2014 2:39 am |
|
|
Quote: | In the include file for the processor, rem out the line near the top 'nolist'. Recompile. |
I do this:
Code: |
#device PIC16F676
//#nolist
//////// Program memory: 1024x14 Data RAM: 64 Stack: 8
|
Quote: | Recompile. You will suddenly find that the code for internal functions like division will appear in the listing. Currently the actual division is the '*' part....
|
Okay..
Code: |
.................... Tmp16 = Tmp16 + 50;
00F3: MOVLW 32
00F4: ADDWF 58,F
00F5: BTFSC 03.0
00F6: INCF 59,F
.................... Tmp16 = (int16)(Tmp16 / 100);
00F7: MOVF 59,W
00F8: MOVWF 5B
00F9: MOVF 58,W
00FA: MOVWF 5A
00FB: CLRF 5D
00FC: MOVLW 64
00FD: MOVWF 5C
*
0122: MOVF 22,W
0123: MOVWF 59
0124: MOVF 21,W
0125: MOVWF 58 |
Any changes..
Quote: | Test with a simple test using printf.
Print Tmp16. Then divide it, and print the result. |
First did so, I found the problem and wrote on the forum.
After dividing the 16-bit number (0 - 10000, not more than) / 100, I get a rezult number 0-1-2.
Code: |
int8 SensorLvl, TriggerLevel;
int16 Tmp16;
Tmp16 = (int16)(SensorLvl * 43);
Tmp16 = Tmp16 + 50;
Tmp16 = (int16)(Tmp16 / 100);
TriggerLevel = make8(Tmp16,0);
|
SensorLvl and TriggerLevel is global variables. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Mar 10, 2014 2:45 am |
|
|
Your casting is wrong:
Code: |
Tmp16 = (int16)(SensorLvl * 43);
|
SensorLyl is an int8.
So is '43'.
So the multiplication is done using int8 arithmetic.
You then cast the int8 _result_ to int16.
You need:
Code: |
Tmp16 = (int16)SensorLvl * 43;
//or
Tmp16 = SensorLvl * 43L;
|
The first converts SensorLvl to an int16 _before_ the multiplication, so int16 arithmetic is used. The second tells the compiler to treat '43' as an int16, so again int16 arithmetic is used.
Again the cast on your division is 'pointless'. Tmp16 is already an int16.
Brackets mean (effectively), 'do what is inside first'. So your layout does the multiplication 'first', then casts the result. But you need to do the cast _first_. |
|
|
Eddy71ua
Joined: 23 Sep 2009 Posts: 55 Location: Ukraine
|
|
Posted: Mon Mar 10, 2014 3:40 am |
|
|
Thanks, you're right, I was wrong. Thank you very much for your help! |
|
|
|