Sunday, January 29

Mikro C floating point from Microchip to PC

Many people out there have done this in many ways, I'd like to show how I have implemented it in Mikro C Pro.

The IEEE754 standard says:
1 bit sign
8 bit exponent
23 bit mantissa

Microchip variation:
8 bit exponent
1 bit sign
23 bit mantissa

so a number like -4.4 in Microchip hexadecimal representation would look like:

81 8C CC CD 

which in memory is stored CD CC 8C 81 as you can see below starting at location 0x45 from a RAM Window in Mikro C Pro debugger.


Which in binary would be:

10000001 10001100 11001100 11001101

Now if you are not extremely familiar with how to convert floating point numbers to binary and back, you might like to use this tool from Harald Schmidt which will do it for you.
According to the standard -4.4 in binary is

11000000 10001100 11001100 11001101 

and in Hex: 

C0 8C CC CD


The first thing to notice (quite obviously really) is that the last two bytes are the same in both representations CC CD hence we don't need to touch them, great! Now let's see what we would need to do in order to "adjust" the other two bytes to match the IEEE754 standard.
The green digit needs to "fly" in front of the blues which in turn need to move down the bench and the reds do not move at all! This is it.

Now let's see how could this be done in Mikro C code.
Assume we have declared

float number = -4.4;

we would need to be able to access each of the four bytes representing the number so to be able to manipulate them. There are essentially two ways I can think of:
Use the built in routines Lo, Hi, Higher, Highest or use a pointer "creatively".
I like the second better. 

For option 1 you need to remember to

#include "built_in.h"

then declare four byte-size variables

unsigned char one, two, three, four;

after which you can distribute the 4 bytes of floating point number. Three and four will not be needed for this example but it might be handy to have them for example depending on how we intend to get the floating number to the PC (e.g over a serial line).

one =Lo(number); 0x81 0b10000001
two = Hi(number); 0x8C 0b10001100
three = Higher(number); 0xCC 0b11001100
four = Highest(number); 0xCD 0b11001101

Option 2 instead needs a pointer like

unsigned char *numberPoint = &number;

Now the compiler will warn "Suspicious pointer conversion", but doing so will allow us to "scan" the floating point bytes as in

one = *(numberPoint + 3); 0x81 0b10000001
two = *(numberPoint + 2); 0x8C 0b10001100
three = *(numberPoint + 1); 0xCC 0b11001100
four = *numberPoint; 0xCD 0b11001101

looking at the RAM window above, if we had defined the pointer as float *(numberPoint + 1) it would have returned the value BC at location 0x49. That is because 1 in this case is 1 size of floating point numbers, in fact 4 bytes! By declaring our pointer of a type char, which is stored in one byte, we gain the necessary granularity we need to move one byte at a time in the floating point binary representation.

All right, we haven't finished yet but we are nearly there. Now we need to do our flying and shifting of bits.
A really useful thing that you can do in C is that it can embed Assembler code in your program.
Now, whatever the CPU architecture. you will always have Assembler instructions for shifting, rotating or both shifting and rotating. They are very similar commands and essentially they tell the CPU to "move" all the bits to the right or to the left. What happens to the leftmost bit when rotating to the left? It "moves" to a particular location called the carry flag (CF), if you then rotate to the right the carry flag gets back on the leftmost bit of the byte. This is what we need to know. If you really really want to know more, there is just about a ton of stuff on the Internet, just Google it.

So coming back to our bytes, we would need to rotate to the left (rlf) byte two, push the CF bit back into byte one by rotating to the right (rrf) and finally rrf the new CF to byte two. That's it!

rlf two 10001100 CF=1 two=0001100x (the x because it does not matter what was in the CF)
rrf one 10000001 CF=1 one=11000000
rrf two 0001100x CF=x two=10001100

this is how you write it in Assembler in your Mikro C editor

asm {
          bsf STATUS, C
          rlf _two, 1
          rrf _one, 1
          rrf _two, 1
      }

so now we have our 11000000 10001100 11001100 11001101 hurrah!  

I hope you found this useful, it turns out I did not need to do this for the project I was working on and that generally there are better ways to get values that are represented with floating point numbers to a PC but maybe this is for another post.  
     


Wednesday, January 25

EasyPIC6 configuration backup

If you are anything like me you might want to work on several projects at the same time with your EasyPIC. I needed to come up with a "snapshot" of the board configuration an thought MS Visio could come in handy.
For the time being there is only an EasyPIC6 version but I should shortly make an EasyPIC v7 one!



Some tips on how to use it:


Switches: Each of the switch is a separate Visio element made so that if you flip it the yellow and the white part will swap places. Simply select one and use the shortcut CTRL + j for the vertical oriented switches and CTRL + h for the horizontal ones.


Jumpers: The best method is to move jumpers bu simply selecting them and move them with the arrow keys.
Port Connectors: I have added 10 connector points to them so that it makes it easier to attach something to them, maybe a simple circuit.


Microchips: Just delete or move away the ones that are not needed :)

Saturday, January 21

Robo PICA Overview


This video gives a brief overview of the Robo-PICA from iNex. As soon as I have a bit more time I should try to dive into some code.

Here are a few links about the things I mentioned in the video.
The iNex website and the Robo-PICA section
The original examples source code for Mikro C and the one for Mikro C Pro
Here you can find the original program the Robo-PICA came with.
Documentation from iNex
PICKit 2 software and documentation from Microchip