The problems:
1. Including math.h and tan(x) into your code takes about 14KB of code space. When your total is 64KB, this is a problem.
2. Running tan(x) 90 times takes about 10 seconds on a microblaze. That is, each angle calculation takes about 100ms, or to populate a look up table at the start of your program will take a long time, even for just 1 degree resolution.
My solution:
I wrote a java program that wrote a look up table for me. I decided on 1 degree resolution, and had the program output me a list of array values complete with assignment statements and semicolons. In the end I could copy and paste this into my c code:
tanLUT[1] = 0.0174
tanLUT[2] = 0.0349
...
Next I wrote a function in C that took my ratio (opposite over adjacent) and did a binary search on the LUT, comparing my ratio to the LUT values. While a more sophisticated search would be necessary for a larger table, it was fine for mine (especially since tan is monotonically increasing over the range 1-89 degrees).
Finally, to save on calculation time, I decided to use fixed point representation for all my numbers. To do so, I multiplied my LUT values by 1000, and my ratio by 1000. This meant I could use integer calculations which are much faster than floating point calculations with almost no extra effort.
Huge savings in both code space and access time, and it took me less than an hour to implement (fairly junior programming skills).
Other solutions:
A quick look on the net will give you some more ideas of how to implement trig functions on an embedded platform. Your decision will depend on the necessary accuracy and speed requirements
- Polynomial approximation. Can be single, or multiple polynomials over the range
- Huge LUT computed at run time
- LUT with linear or polynomial interpolation
