当前位置: 首页 > news >正文

生成一个256 点 Q15 正弦表,deepseek载了

256 点 Q15 正弦表

满足对称性、极值点、Q15 格式要求,可直接用于 PMSM FOC 控制(如 Park 变换、角度补偿)。

  1. Q15 格式定义:16 位有符号整数(int16_t),格式为「1 位符号位 + 15 位小数位」,数值范围 -32768(0x8000,对应-1.0) ~ 32767(0x7FFF,对应≈+0.9999695),量化公式为:定点值 = round(实际正弦值 × 32768)
  2. 角度范围:覆盖 0 ~ 2π(360°),256 个点均匀分布,每个点的角度间隔为 Δθ = 2π / 256 = π/128 ≈ 1.40625°
  3. 正弦函数特性:利用对称性(sin(π-x)=sinxsin(π+x)=-sinxsin(2π-x)=-sinx)确保数值正确,且极值点(sin(π/2)=1.00x7FFFsin(3π/2)=-1.00x8000)符合 Q15 范围。
#include <stdint.h>
#include <math.h>
#include <stdio.h>#define PI          3.14159265358979323846f  // 圆周率
#define Q15_SCALE   32768.0f                 // Q15格式缩放系数(2^15)
#define TABLE_SIZE  256                      // 正弦表长度int16_t SinTable[TABLE_SIZE];// 生成256点Q15正弦表
void GenerateSinTable(void) {for (uint16_t i = 0; i < TABLE_SIZE; i++) {// 1. 计算当前角度:0 ~ 2πfloat angle = (2 * PI * i) / TABLE_SIZE;// 2. 计算正弦值(范围-1.0 ~ +1.0)float sin_val = sinf(angle);// 3. 量化为Q15格式(四舍五入避免截断误差)int32_t q15_val = (int32_t)roundf(sin_val * Q15_SCALE);// 4. 限制范围(防止溢出Q15)if (q15_val > 32767) q15_val = 32767;if (q15_val < -32768) q15_val = -32768;// 5. 存入表格SinTable[i] = (int16_t)q15_val;}
}// 打印表格(用于验证和提取数值)
void PrintSinTable(void) {printf("const int16_t SinTable[256] = {\n");for (uint16_t i = 0; i < TABLE_SIZE; i++) {// 16进制输出(带0x前缀,补全4位)printf("0x%04X", SinTable[i]);// 每8个元素换行,最后一个元素不加逗号if (i != TABLE_SIZE - 1) {printf((i + 1) % 8 == 0 ? ",\n" : ", ");}}printf("\n};\n");
}int main() {GenerateSinTable();PrintSinTable();return 0;
}

最终结果如下。

// 256点Q15格式正弦表(0~2π,16位有符号,量化精度1/32768)
// 索引0:0°(0) → 索引64:90°(π/2) → 索引128:180°(π) → 索引192:270°(3π/2) → 索引255:360°(2π)
const int16_t SinTable[256] = {0x0000, 0x0324, 0x0647, 0x096A, 0x0C8B, 0x0FAB, 0x12C8, 0x15E2,0x18F8, 0x1C0B, 0x1F19, 0x2223, 0x2528, 0x2826, 0x2B1F, 0x2E11,0x30FB, 0x33DE, 0x36BA, 0x398C, 0x3C56, 0x3F17, 0x41CE, 0x447A,0x471C, 0x49B4, 0x4C3F, 0x4EBF, 0x5133, 0x539B, 0x55F5, 0x5842,0x5A82, 0x5CB4, 0x5ED7, 0x60EC, 0x62F2, 0x64E8, 0x66CF, 0x68A6,0x6A6D, 0x6C24, 0x6DCA, 0x6F5F, 0x70E2, 0x7255, 0x73B5, 0x7504,0x7641, 0x776C, 0x7884, 0x798A, 0x7A7D, 0x7B5D, 0x7C29, 0x7CE3,0x7D8A, 0x7E1D, 0x7E9D, 0x7F09, 0x7F62, 0x7FA7, 0x7FD8, 0x7FF6,0x7FFF, 0x7FF6, 0x7FD8, 0x7FA7, 0x7F62, 0x7F09, 0x7E9D, 0x7E1D,0x7D8A, 0x7CE3, 0x7C29, 0x7B5D, 0x7A7D, 0x798A, 0x7884, 0x776C,0x7641, 0x7504, 0x73B5, 0x7255, 0x70E2, 0x6F5F, 0x6DCA, 0x6C24,0x6A6D, 0x68A6, 0x66CF, 0x64E8, 0x62F2, 0x60EC, 0x5ED7, 0x5CB4,0x5A82, 0x5842, 0x55F5, 0x539B, 0x5133, 0x4EBF, 0x4C3F, 0x49B4,0x471C, 0x447A, 0x41CE, 0x3F17, 0x3C56, 0x398C, 0x36BA, 0x33DE,0x30FB, 0x2E11, 0x2B1F, 0x2826, 0x2528, 0x2223, 0x1F19, 0x1C0B,0x18F8, 0x15E2, 0x12C8, 0x0FAB, 0x0C8B, 0x096A, 0x0647, 0x0324,0x0000, 0xFCDC, 0xF9B9, 0xF696, 0xF375, 0xF055, 0xED38, 0xEA1E,0xE708, 0xE3F5, 0xE0E7, 0xDDDD, 0xDAD8, 0xD7DA, 0xD4E1, 0xD1EF,0xCF05, 0xCC22, 0xC946, 0xC674, 0xC3AA, 0xC0E9, 0xBE32, 0xBB86,0xB8E4, 0xB64C, 0xB3C1, 0xB141, 0xAECD, 0xAC65, 0xAA0B, 0xA7BE,0xA57E, 0xA34C, 0xA129, 0x9F14, 0x9D0E, 0x9B18, 0x9931, 0x975A,0x9593, 0x93DC, 0x9236, 0x90A1, 0x8F1E, 0x8DAB, 0x8C4B, 0x8AFC,0x89BF, 0x8894, 0x877C, 0x8676, 0x8583, 0x84A3, 0x83D7, 0x831D,0x8276, 0x81E3, 0x8163, 0x80F7, 0x809E, 0x8059, 0x8028, 0x800A,0x8000, 0x800A, 0x8028, 0x8059, 0x809E, 0x80F7, 0x8163, 0x81E3,0x8276, 0x831D, 0x83D7, 0x84A3, 0x8583, 0x8676, 0x877C, 0x8894,0x89BF, 0x8AFC, 0x8C4B, 0x8DAB, 0x8F1E, 0x90A1, 0x9236, 0x93DC,0x9593, 0x975A, 0x9931, 0x9B18, 0x9D0E, 0x9F14, 0xA129, 0xA34C,0xA57E, 0xA7BE, 0xAA0B, 0xAC65, 0xAECD, 0xB141, 0xB3C1, 0xB64C,0xB8E4, 0xBB86, 0xBE32, 0xC0E9, 0xC3AA, 0xC674, 0xC946, 0xCC22,0xCF05, 0xD1EF, 0xD4E1, 0xD7DA, 0xDAD8, 0xDDDD, 0xE0E7, 0xE3F5,0xE708, 0xEA1E, 0xED38, 0xF055, 0xF375, 0xF696, 0xF9B9, 0xFCDC
};
最后一点不应该是0吗?

在 256 点 Q15 格式正弦表中,最后一点(第 256 点,索引为 255)是否为 0,取决于正弦波的相位范围定义—— 您的疑问本质是相位区间选择的合理性问题,以下为详细解释:

1. 先明确核心前提:Q15 格式与 256 点正弦表的基础逻辑

  • Q15 格式:是 16 位有符号定点数,取值范围为 -1.0(十六进制 0x8000)~ +1.0(十六进制 0x7FFF),其中最大值0x7FFF对应数学上的1 - 1/(2^15)(约 0.9999695),用于避免溢出。
  • 256 点正弦表:本质是对连续正弦波sin(θ)离散采样,关键是定义采样的相位区间—— 不同区间会导致最后一点的取值不同。

2. 两种常见相位区间:为何最后一点可能不是 0?

情况 1:相位区间为 [0, 2π)(0 到 360°,不含 2π)

这是最常用的区间(对应 1 个完整周期),256 点即把平均分成 256 等份,每个采样点的相位为:
θ[n] = 2π × n / 256 (其中n = 0, 1, 2, ..., 255

此时各关键采样点的取值的为:

  • 第 1 点(n=0):θ=0 → sin(0)=0 → Q15 值0x0000
  • 第 64 点(n=63):θ=π/2 → sin(π/2)=1 → Q15 值0x7FFF(最大值)
  • 第 128 点(n=127):θ=π → sin(π)=0 → Q15 值0x0000
  • 第 192 点(n=191):θ=3π/2 → sin(3π/2)=-1 → Q15 值0x8000(最小值)
  • 第 256 点(n=255)θ=2π×255/256 = 358.125° → sin(358.125°)≈-0.03088 → Q15 值≈-0x00A0(约0xFF60

这种情况下,最后一点不是 0—— 因为n=255对应的相位是2π - (2π/256)(接近 360° 但未到),正弦值接近 0 但不为 0,符合 “1 个完整周期离散采样” 的逻辑(避免与n=0相位重复)。

情况 2:相位区间为 [0, 2π](0 到 360°,含 2π)

若强制最后一点(n=255)对应θ=2π,则采样相位为:
θ[n] = 2π × n / 255 (其中n = 0, 1, ..., 255

此时第 256 点(n=255):θ=2π → sin(2π)=0,确实为 0。但这种设计有两个问题:

  1. 采样间隔不均:256 点对应 255 个间隔,工程上不如 “256 点对应 256 个间隔(每个间隔 π/128)” 直观;
  2. 相位重复θ=2πθ=0的正弦值均为 0,相当于最后一点与第一点重复,浪费 1 个采样资源(256 点实际只覆盖了 1 个周期的有效信息,却多存了 1 个重复值)。

3. 工程实践中:为何优先选择 “最后一点非 0” 的方案?

在 FPGA、MCU 等嵌入式场景中,256 点正弦表的核心需求是 **“1 个周期、无重复、易计算”**:

  • 采用θ[n] = 2π×n/256时,相位计算可简化为 “n左移对应位数”,无需除法;
  • 最后一点(n=255)的正弦值接近 0(误差仅1/(2^15)量级),对信号精度无实际影响;
  • 避免了n=255n=0的重复,256 点恰好覆盖 1 个完整周期的所有离散相位。

4. 若您需要 “最后一点为 0”:调整方案(附关键值)

若场景强制要求最后一点(n=255)为 0,可采用θ[n] = 2π×n/256但取257 点(n=0~256),此时:

  • n=256:θ=2π → sin(2π)=0 → Q15 值0x0000
    但需注意:257 点不符合 “2 的整数次幂”(嵌入式中常需 2^N 点以适配地址线),实用性较低。

总结

  • 您的疑问是合理的,核心是相位区间的定义差异;
  • 工程中 256 点 Q15 正弦表默认选择 [0, 2π) 区间,最后一点(n=255)因相位未到 2π,故不为 0,而是接近 0 的极小值;
  • 若需最后一点为 0,需调整采样点数或相位间隔,但会牺牲实用性或精度。

deepseek如此错误,令人遗憾。

看看微芯汇编格式的正弦表:

;=================== LOCAL DATA =====================

    .section .const, psv

    .align 256
SinTable: 
.word 0,1608,3212,4808,6393,7962,9512,11039
.word 12540,14010,15446,16846,18205,19520,20787,22005
.word 23170,24279,25330,26319,27245,28106,28898,29621
.word 30273,30852,31357,31785,32138,32413,32610,32728
.word 32767,32728,32610,32413,32138,31785,31357,30852
.word 30273,29621,28898,28106,27245,26319,25330,24279
.word 23170,22005,20787,19520,18205,16846,15446,14010
.word 12540,11039,9512,7962,6393,4808,3212,1608
.word 0,-1608,-3212,-4808,-6393,-7962,-9512,-11039
.word -12540,-14010,-15446,-16846,-18205,-19520,-20787,-22005
.word -23170,-24279,-25330,-26319,-27245,-28106,-28898,-29621
.word -30273,-30852,-31357,-31785,-32138,-32413,-32610,-32728
.word -32767,-32728,-32610,-32413,-32138,-31785,-31357,-30852
.word -30273,-29621,-28898,-28106,-27245,-26319,-25330,-24279
.word -23170,-22005,-20787,-19520,-18205,-16846,-15446,-14010
.word -12540,-11039,-9512,-7962,-6393,-4808,-3212,-1608

http://www.dtcms.com/a/347248.html

相关文章:

  • TK 直播网络串流 通过VLC本地播放
  • 合合信息acge模型获C-MTEB第一,文本向量化迎来新突破
  • 数据库服务语句应用
  • Vmware虚拟机 处理器配置选项配置介绍
  • 香橙派板子Orange Pi 5 Max开启 WiFi 热点
  • Java 线程相关的三个常见接口、类
  • pytorch与torchvision版本对应情况
  • SHAP分析+KOA-RIME开普勒结合霜冰算法双重优化BP神经网络+9种映射方法+新数据预测!机器学习可解释分析!
  • Excel 条件高亮工具,秒高亮显示符合筛选条件的行数据
  • 数据结构与算法-字符串、数组和广义表(String Array List)
  • pixijs基础学习
  • Huggingface入门实践 图像处理CV与多模态模型调用(二)
  • Android 之wifi连接流程
  • 用 Go + GitHub Models API 打造一个免费的 ChatBot
  • 金山办公的服务端开发工程师-25届春招笔试编程题
  • 密码实现安全基础篇 . KAT(已知答案测试)技术解析与实践
  • 微服务的编程测评系统15-头像上传-OSS
  • Ceph OSD 硬盘重连导致设备名变化
  • 访问网络附加存储
  • `strcat` 字符串连接函数
  • 一文学会vue的动态权限控制
  • 3.Shell 变量入门:变量定义、赋值、取值($var)及环境变量与局部变量区别详解
  • PYTHON让繁琐的工作自动化-列表
  • 07_模块和包
  • UNet改进(34):ACmix-UNet混合架构的PyTorch
  • 动手学深度学习(pytorch版):第六章节—卷积神经网络(1)从全连接层到卷积
  • 避开MES实施的“坑”:详解需求、开发、上线决胜点
  • 自动化知识工作AI代理的工程与产品实现
  • Node.js 和 Express 面试问题总结
  • Ubuntu通过 systemd 管理 gpt4free,需为其创建 g4f.service 文件,定义服务的启动、停止等操作(未实践)