//***************************************************************************** // // sine.c - Fixed point sine trigonometric function. // // Copyright (c) 2006-2014 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Texas Instruments (TI) is supplying this software for use solely and // exclusively on TI's microcontroller products. The software is owned by // TI and/or its suppliers, and is protected under applicable copyright // laws. You may not combine this software with "viral" open-source // software in order to form a larger program. // // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL // DAMAGES, FOR ANY REASON WHATSOEVER. // // This is part of revision 2.1.0.12573 of the Tiva Utility Library. // //***************************************************************************** #include #include "utils/sine.h" //***************************************************************************** // //! \addtogroup sine_api //! @{ // //***************************************************************************** //***************************************************************************** // // A table of the value of the sine function for the first ninety degrees with // 129 entries (that is, [0] = 0 degrees, [128] = 90 degrees). Each entry is // in 0.16 fixed point notation. // //***************************************************************************** static const uint16_t g_pui16FixedSineTable[] = { 0x0000, 0x0324, 0x0648, 0x096C, 0x0C8F, 0x0FB2, 0x12D5, 0x15F6, 0x1917, 0x1C37, 0x1F56, 0x2273, 0x2590, 0x28AA, 0x2BC4, 0x2EDB, 0x31F1, 0x3505, 0x3817, 0x3B26, 0x3E33, 0x413E, 0x4447, 0x474D, 0x4A50, 0x4D50, 0x504D, 0x5347, 0x563E, 0x5931, 0x5C22, 0x5F0E, 0x61F7, 0x64DC, 0x67BD, 0x6A9B, 0x6D74, 0x7049, 0x7319, 0x75E5, 0x78AD, 0x7B70, 0x7E2E, 0x80E7, 0x839C, 0x864B, 0x88F5, 0x8B9A, 0x8E39, 0x90D3, 0x9368, 0x95F6, 0x987F, 0x9B02, 0x9D7F, 0x9FF6, 0xA267, 0xA4D2, 0xA736, 0xA994, 0xABEB, 0xAE3B, 0xB085, 0xB2C8, 0xB504, 0xB73A, 0xB968, 0xBB8F, 0xBDAE, 0xBFC7, 0xC1D8, 0xC3E2, 0xC5E4, 0xC7DE, 0xC9D1, 0xCBBB, 0xCD9F, 0xCF7A, 0xD14D, 0xD318, 0xD4DB, 0xD695, 0xD848, 0xD9F2, 0xDB94, 0xDD2D, 0xDEBE, 0xE046, 0xE1C5, 0xE33C, 0xE4AA, 0xE60F, 0xE76B, 0xE8BF, 0xEA09, 0xEB4B, 0xEC83, 0xEDB2, 0xEED8, 0xEFF5, 0xF109, 0xF213, 0xF314, 0xF40B, 0xF4FA, 0xF5DE, 0xF6BA, 0xF78B, 0xF853, 0xF912, 0xF9C7, 0xFA73, 0xFB14, 0xFBAC, 0xFC3B, 0xFCBF, 0xFD3A, 0xFDAB, 0xFE13, 0xFE70, 0xFEC4, 0xFF0E, 0xFF4E, 0xFF84, 0xFFB1, 0xFFD3, 0xFFEC, 0xFFFB, 0xFFFF }; //***************************************************************************** // //! Computes an approximation of the sine of the input angle. //! //! \param ui32Angle is an angle expressed as a 0.32 fixed-point value that is //! the percentage of the way around a circle. //! //! This function computes the sine for the given input angle. The angle is //! specified in 0.32 fixed point format, and is therefore always between 0 and //! 360 degrees, inclusive of 0 and exclusive of 360. //! //! \return Returns the sine of the angle, in 16.16 fixed point format. // //***************************************************************************** int32_t sine(uint32_t ui32Angle) { uint32_t ui32Idx; // // Add 0.5 to the angle. Since only the upper 9 bits are used to compute // the sine value, adding one to the tenth bit is 0.5 from the point of // view of the sine table. // ui32Angle += 0x00400000; // // Get the index into the sine table from bits 30:23. // ui32Idx = (ui32Angle >> 23) & 255; // // If bit 30 is set, the angle is between 90 and 180 or 270 and 360. In // these cases, the sine value is decreasing from one instead of increasing // from zero. The indexing into the table needs to be reversed. // if(ui32Angle & 0x40000000) { ui32Idx = 256 - ui32Idx; } // // Get the value of the sine. // ui32Idx = g_pui16FixedSineTable[ui32Idx]; // // If bit 31 is set, the angle is between 180 and 360. In this case, the // sine value is negative; otherwise it is positive. // if(ui32Angle & 0x80000000) { return(0 - ui32Idx); } else { return(ui32Idx); } } //***************************************************************************** // // Close the Doxygen group. //! @} // //*****************************************************************************