fourier.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: fourier.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2008-07-09
  7. 功能说明: 傅立叶函数,每个周波采样32点。
  8. 其它说明:
  9. 1.进行一次计算需要4.47us(ram)。
  10. 2.新写法在采样数据4byte对齐的时候需要3.038us(ram),2byte对齐的时候需要3.775us(ram)。
  11. 在flash上运行时需要的时间分别为4.438us和5.275us.(52259上)
  12. 3.在MCF54418上,只使用acc0,需要1.24us;使用ACC0、ACC1,需要0.781us。
  13. 修改记录:
  14. */
  15. /*------------------------------- 头文件 --------------------------------------
  16. */
  17. #ifndef WIN32 //VC6.0 中定义的宏
  18. #include "bspconfig.h"
  19. #include "rt.h"
  20. #include "fourier.h"
  21. #else
  22. #define CFG_BSP_DEBUG 1
  23. #endif
  24. #define sin(x) (x) // sunxi 20220408 由于找不到编译器的数学库,暂时定义一个宏代替。
  25. /*------------------------------- 宏定义 --------------------------------------
  26. */
  27. #if CFG_BSP_DEBUG
  28. #define _FOURIER_DEBUG
  29. #endif
  30. /*------------------------------ 全局变量 -------------------------------------
  31. */
  32. //用int定义代替short定义,确保这个数组4bytes对齐,以保证函数执行效率。
  33. const int g_fourier_coefficient[3][2][16]=
  34. {
  35. //基波
  36. {
  37. {
  38. //实部系数?(2/32)*cos(k*1*2*pi/32)*65536
  39. ( 4096<<16)|( 4017&0xffff), ( 3784<<16)|( 3406&0xffff), ( 2896<<16)|( 2276&0xffff), ( 1567<<16)|( 799&0xffff),
  40. ( 0<<16)|( -799&0xffff), ((u16)(-1567)<<16)|(-2276&0xffff), ((u16)(-2896)<<16)|(-3406&0xffff), ((u16)(-3784)<<16)|(-4017&0xffff),
  41. ((u16)(-4096)<<16)|(-4017&0xffff), ((u16)(-3784)<<16)|(-3406&0xffff), ((u16)(-2896)<<16)|(-2276&0xffff), ((u16)(-1567)<<16)|( -799&0xffff),
  42. ( 0<<16)|( 799&0xffff), ( 1567<<16)|( 2276&0xffff), ( 2896<<16)|( 3406&0xffff), ( 3784<<16)|( 4017&0xffff),
  43. },
  44. {
  45. //虚部系数?-(2/32)*sin(k*1*2*pi/32)*65536
  46. ( 0<<16)|( (u16)(-799)&0xffff), ((u16)(-1567)<<16)|(-2276&0xffff), ((u16)(-2896)<<16)|(-3406&0xffff), ((u16)(-3784)<<16)|(-4017&0xffff),
  47. ((u16)(-4096)<<16)|(-4017&0xffff), ((u16)(-3784)<<16)|(-3406&0xffff), ((u16)(-2896)<<16)|(-2276&0xffff), ((u16)(-1567)<<16)|( -799&0xffff),
  48. ( 0<<16)|( 799&0xffff), ( 1567<<16)|( 2276&0xffff), ( 2896<<16)|( 3406&0xffff), ( 3784<<16)|( 4017&0xffff),
  49. ( 4096<<16)|( 4017&0xffff), ( 3784<<16)|( 3406&0xffff), ( 2896<<16)|( 2276&0xffff), ( 1567<<16)|( 799&0xffff),
  50. },
  51. },
  52. //二次谐波
  53. {
  54. {
  55. //实部系数?(2/32)*cos(k*2*2*pi/32)*65536
  56. ( 4096<<16)|( 3784&0xffff), ( 2896<<16)|( 1567&0xffff), ( 0<<16)|(-1567&0xffff), ((u16)(-2896)<<16)|(-3784&0xffff),
  57. ((u16)(-4096)<<16)|(-3784&0xffff), ((u16)(-2896)<<16)|(-1567&0xffff), ( 0<<16)|( 1567&0xffff), ( 2896<<16)|( 3784&0xffff),
  58. ( 4096<<16)|( 3784&0xffff), ( 2896<<16)|( 1567&0xffff), ( 0<<16)|(-1567&0xffff), ((u16)(-2896)<<16)|(-3784&0xffff),
  59. ((u16)(-4096)<<16)|(-3784&0xffff), ((u16)(-2896)<<16)|(-1567&0xffff), ( 0<<16)|( 1567&0xffff), ( 2896<<16)|( 3784&0xffff),
  60. },
  61. {
  62. //虚部系数?-(2/32)*sin(k*2*2*pi/32)*65536
  63. ( 0<<16)|(-1567&0xffff), ((u16)(-2896)<<16)|(-3784&0xffff), ((u16)(-4096)<<16)|(-3784&0xffff), ((u16)(-2896)<<16)|(-1567&0xffff),
  64. ( 0<<16)|( 1567&0xffff), ( 2896<<16)|( 3784&0xffff), ( 4096<<16)|( 3784&0xffff), ( 2896<<16)|( 1567&0xffff),
  65. ( 0<<16)|(-1567&0xffff), ((u16)(-2896)<<16)|(-3784&0xffff), ((u16)(-4096)<<16)|(-3784&0xffff), ((u16)(-2896)<<16)|(-1567&0xffff),
  66. ( 0<<16)|( 1567&0xffff), ( 2896<<16)|( 3784&0xffff), ( 4096<<16)|( 3784&0xffff), ( 2896<<16)|( 1567&0xffff),
  67. },
  68. },
  69. //五次谐波
  70. {
  71. {
  72. //实部系数?(2/32)*cos(k*5*2*pi/32)*65536
  73. ( 4096<<16)|( 2276&0xffff), ((u16)(-1567)<<16)|(-4017&0xffff), ((u16)(-2896)<<16)|( 799&0xffff), ( 3784<<16)|( 3406&0xffff),
  74. ( 0<<16)|(-3406&0xffff), ((u16)(-3784)<<16)|( -799&0xffff), ( 2896<<16)|( 4017&0xffff), ( 1567<<16)|(-2276&0xffff),
  75. ((u16)(-4096)<<16)|(-2276&0xffff), ( 1567<<16)|( 4017&0xffff), ( 2896<<16)|( -799&0xffff), ((u16)(-3784)<<16)|(-3406&0xffff),
  76. ( 0<<16)|( 3406&0xffff), ( 3784<<16)|( 799&0xffff), ((u16)(-2896)<<16)|(-4017&0xffff), ((u16)(-1567)<<16)|( 2276&0xffff),
  77. },
  78. {
  79. //虚部系数?-(2/32)*sin(k*5*2*pi/32)*65536
  80. ( 0<<16)|(-3406&0xffff), ((u16)(-3784)<<16)|( -799&0xffff), ( 2896<<16)|( 4017&0xffff), ( 1567<<16)|(-2276&0xffff),
  81. ((u16)(-4096)<<16)|(-2276&0xffff), ( 1567<<16)|( 4017&0xffff), ( 2896<<16)|( -799&0xffff), ((u16)(-3784)<<16)|(-3406&0xffff),
  82. ( 0<<16)|( 3406&0xffff), ( 3784<<16)|( 799&0xffff), ((u16)(-2896)<<16)|(-4017&0xffff), ((u16)(-1567)<<16)|( 2276&0xffff),
  83. ( 4096<<16)|( 2276&0xffff), ((u16)(-1567)<<16)|(-4017&0xffff), ((u16)(-2896)<<16)|( 799&0xffff), ( 3784<<16)|( 3406&0xffff),
  84. },
  85. },
  86. };
  87. /*------------------------------ 外部函数 -------------------------------------
  88. */
  89. /******************************************************************************
  90. 函数名称: fourier32
  91. 函数版本: 01.01
  92. 创建作者: sunxi
  93. 创建日期: 2008-06-26
  94. 函数说明: 32点傅立叶算法。此函数中使用的ACC寄存器在中断处理时不会进行压栈处理,
  95. 所以整个系统中,不能在不同的中断级别调用这个函数。
  96. 注意:d0~d2、a0~a1是scratch register,不需要保存。
  97. d0: 采样点的值
  98. d1: 实部系数值
  99. d2: 实部系数值
  100. a0: 采样点首地址。
  101. a1: 实部首地址。
  102. a2: 虚部首地址。
  103. a3: 返回复数对的地址
  104. 参数说明:
  105. dots: 采样点数据指针,包含32点的采样数据。在本函数中对采样数据的
  106. 地址进行了循环buf的处理,具体做法是将地址和MAC中的MASK
  107. 寄存器相与。所以用户必须注意采样点buf的首地址(不是dots
  108. 的地址)必须是采样点buf长度(以byte为单位)的2倍。
  109. real_image_pair:函数返回的实部/虚部对。
  110. harmonic: 需要计算的谐波次数,用定义好的宏表示。
  111. 返回值: 无
  112. 修改记录:
  113. */
  114. #if 1
  115. void fourier32(short *dots,short * real_image_pair,unsigned int harmonic)
  116. {
  117. long a,b,i;
  118. short *coefficient;
  119. a = 0;
  120. b = 0;
  121. coefficient = (short *)((char *) harmonic);
  122. for(i=0; i<32; i++,dots++)
  123. {
  124. a += (*dots) * coefficient[i];
  125. b += (*dots) * coefficient[i+32];
  126. }
  127. real_image_pair[0] = (short)(a >> 16);
  128. real_image_pair[1] = (short)(b >> 16);
  129. //已综合考虑正数和负数的情况。
  130. if(a&0x8000)
  131. {
  132. real_image_pair[0] += 1;
  133. }
  134. if(b&0x8000)
  135. {
  136. real_image_pair[1] += 1;
  137. }
  138. }
  139. #else
  140. void fourier32(short *dots,struct ri_s16 * ri,unsigned int harmonic)
  141. {
  142. }
  143. #endif
  144. void fourier32_half(short *dots,struct ri_s16 * ri,unsigned int harmonic)
  145. {
  146. }
  147. /*------------------------------ 内部函数 -------------------------------------
  148. */
  149. /*------------------------------ 测试函数 -------------------------------------
  150. */
  151. #ifdef _FOURIER_DEBUG
  152. //由于系数高低byte的不同,目前这个函数在VC下已不能得到正确结果。
  153. static void fourier32_c(short *dots,short * real_image_pair,unsigned int harmonic)
  154. {
  155. long a,b,i;
  156. short *coefficient;
  157. a = 0;
  158. b = 0;
  159. coefficient = (short *)(harmonic);
  160. for(i=0; i<32; i++,dots++)
  161. {
  162. a += (*dots) * coefficient[i];
  163. b += (*dots) * coefficient[i+32];
  164. }
  165. real_image_pair[0] = (short)(a >> 16);
  166. real_image_pair[1] = (short)(b >> 16);
  167. //已综合考虑正数和负数的情况。
  168. if(a&0x8000)
  169. {
  170. real_image_pair[0] += 1;
  171. }
  172. if(b&0x8000)
  173. {
  174. real_image_pair[1] += 1;
  175. }
  176. }
  177. #ifndef WIN32
  178. #include "ustimer.h"
  179. #include "rt.h"
  180. #include "bsp.h"
  181. #if 1
  182. /*
  183. fourier32_c:real=-51,image=-86,us=3934!
  184. fourier32(1):real=-51,image=-86,m=100,p=-120.6846,us=427!
  185. fourier32(2):real=0,image=0,m=0,p=90.0000,us=427!
  186. fourier32(5):real=-234,image=442,m=500,p=117.8720,us=427!
  187. fourier32_half(1):real=-51,image=-86,m=100,p=-120.6846,us=330!
  188. fourier32_half(2):real=-197,image=12,m=197,p=180.0000,us=330!
  189. fourier32_half(5):real=-234,image=442,m=500,p=117.8720,us=330!
  190. */
  191. const short g_fourier_dots[] =
  192. {
  193. -285,-530,-333,149,503,432,13,-365,
  194. -356,43,484,579,244,-226,-418,-172,
  195. 285,530,333,-149,-503,-432,-13,365,
  196. 356,-43,-484,-579,-244,226,418,172,
  197. };
  198. #else
  199. //amplitude=1111.000000,phase=11.000000,count=32
  200. //RESULT(0):real=212,image=-1091
  201. //RESULT(0):amplitude=1111.406766,phase=79.003488
  202. //RESULT(1):real=832,image=-2060
  203. //RESULT(1):amplitude=2221.671443,phase=68.007031
  204. //RESULT(2):real=4551,image=-3186
  205. //RESULT(2):amplitude=5555.375505,phase=34.994555
  206. const short g_fourier_dots[] =
  207. {
  208. 5594,7155,3860,-837,-2490,373,4942,6684,
  209. 3445,-2542,-6542,-5446,-474,3930,4038,107,
  210. -3930,-4041,230,5281,6610,2797,-3206,-6646,
  211. -5109,-572,2452,1002,-3646,-7100,-5774,-145,
  212. };
  213. #endif
  214. #ifndef __KERNEL__
  215. #define PI 3.1415926535897932384626433832795
  216. int fourier_dots(double amp, double phase, int count, short *dots);
  217. int fourier_dots(double amp, double phase, int count, short *dots)
  218. {
  219. int i;
  220. double temp;
  221. for(i=0;i<count; i++)
  222. {
  223. temp = amp*sin(phase + i*(2*PI)/count);
  224. if(temp >= 0)
  225. {
  226. temp += 0.5;
  227. }
  228. else
  229. {
  230. temp -= 0.5;
  231. }
  232. dots[i] = (short)(temp);
  233. #if 0
  234. temp = amp*2*sin(phase*2 + i*2*(2*PI)/count);
  235. if(temp >= 0)
  236. {
  237. temp += 0.5;
  238. }
  239. else
  240. {
  241. temp -= 0.5;
  242. }
  243. dots[i] += (short)(temp);
  244. #endif
  245. temp = amp*5*sin(phase*5 + i*5*(2*PI)/count);
  246. if(temp >= 0)
  247. {
  248. temp += 0.5;
  249. }
  250. else
  251. {
  252. temp -= 0.5;
  253. }
  254. dots[i] += (short)(temp);
  255. }
  256. return 0;
  257. }
  258. #endif
  259. void fourier_test_get_dots(short * dots);
  260. void fourier_test_get_dots(short * dots)
  261. {
  262. #if __KERNEL__
  263. //在Linux中使用以前的数据,因为没有sin函数供调用。
  264. memcpy(dots,g_fourier_dots,sizeof(g_fourier_dots));
  265. #else
  266. // 如果使用半波算法,必须使用生成的数据,不包含二次谐波,否则算不准。
  267. fourier_dots(100.0,100.0,32,(short *)dots);
  268. #endif
  269. return;
  270. }
  271. uint32_t _AmXY(long nRe,long nIm);
  272. long _AngPQ(long P,long Q);
  273. int fourier_test(void)
  274. {
  275. int i,j;
  276. uint32_t us0,us;//,flags;
  277. long phase;
  278. uint32_t magnitude;
  279. struct ri_s16 ri =
  280. {
  281. 0,0
  282. };
  283. int harmonic[3][2] =
  284. {
  285. {1,0},
  286. {2,0},
  287. {5,0},
  288. };
  289. harmonic[0][1] = FOURIER_HARMONIC_1;
  290. harmonic[1][1] = FOURIER_HARMONIC_2;
  291. harmonic[2][1] = FOURIER_HARMONIC_5;
  292. //fourier32_c
  293. rt_irq_save(flags);
  294. fourier_test_get_dots((short *)g_adc_dots);
  295. // 打印采样点
  296. rt_printf("const short g_fourier_dots[] =\r\n{\t");
  297. for(i=0;i<32;i++)
  298. {
  299. if(i%8 == 0)
  300. rt_printf("\r\n\t");
  301. rt_printf("%d,",((short*)g_adc_dots)[i]);
  302. }
  303. rt_printf("\r\n};\r\n");
  304. us0 = ustimer_get_origin();
  305. for(i=0;i<1000;i++)
  306. {
  307. fourier32_c((short *)g_adc_dots,(s16 *)&ri,FOURIER_HARMONIC_1);
  308. }
  309. us = ustimer_get_duration(us0);
  310. rt_irq_restore(flags);
  311. rt_printf("fourier32_c:real=%d,image=%d,us=%lu!\r\n",\
  312. ri.r,ri.i,us);
  313. //fourier32
  314. #if 1
  315. for(j=0;j<128;j++)
  316. {
  317. rt_irq_save(flags);
  318. fourier_test_get_dots((short *)g_adc_dots);
  319. fourier_test_get_dots((short *)g_adc_dots + 32);
  320. fourier_test_get_dots((short *)g_adc_dots + 64);
  321. fourier_test_get_dots((short *)g_adc_dots + 96);
  322. us0 = ustimer_get_origin();
  323. for(i=0;i<1;i++)
  324. {
  325. fourier32((short *)g_adc_dots +j,(short *)&ri,(unsigned int)harmonic[0][1]);
  326. }
  327. us = ustimer_get_duration(us0);
  328. rt_irq_restore(flags);
  329. magnitude = _AmXY(ri.r,ri.i);
  330. phase = _AngPQ(ri.r,ri.i);
  331. rt_printf("fourier32(%d):real=%d,image=%d,m=%lu,p=%s,us=%lu!\r\n",\
  332. j,ri.r,ri.i,magnitude,q16_to_str(phase),us);
  333. }
  334. ustimer_delay(USTIMER_SEC*3);
  335. // 半波傅氏测试
  336. //fourier32_half
  337. for(j=0;j<128;j++)
  338. {
  339. rt_irq_save(flags);
  340. fourier_test_get_dots((short *)g_adc_dots);
  341. fourier_test_get_dots((short *)g_adc_dots + 32);
  342. fourier_test_get_dots((short *)g_adc_dots + 64);
  343. fourier_test_get_dots((short *)g_adc_dots + 96);
  344. us0 = ustimer_get_origin();
  345. for(i=0;i<1;i++)
  346. {
  347. fourier32_half((short *)g_adc_dots +j,&ri,(unsigned int)harmonic[0][1]);
  348. }
  349. us = ustimer_get_duration(us0);
  350. rt_irq_restore(flags);
  351. magnitude = _AmXY(ri.r,ri.i);
  352. phase = _AngPQ(ri.r,ri.i);
  353. rt_printf("fourier32_half(%d):real=%d,image=%d,m=%lu,p=%s,us=%lu!\r\n",\
  354. j,ri.r,ri.i,magnitude,q16_to_str(phase),us);
  355. }
  356. #else
  357. for(j=0;j<3;j++)
  358. {
  359. rt_irq_save(flags);
  360. fourier_test_get_dots((short *)g_adc_dots);
  361. us0 = ustimer_get_origin();
  362. for(i=0;i<1000;i++)
  363. {
  364. fourier32((short *)g_adc_dots,real_image_pair,(unsigned int)harmonic[j][1]);
  365. }
  366. us = ustimer_get_duration(us0);
  367. rt_irq_restore(flags);
  368. magnitude = _AmXY(real_image_pair[0],real_image_pair[1]);
  369. phase = _AngPQ(real_image_pair[0],real_image_pair[1]);
  370. rt_printf("fourier32(%d):real=%d,image=%d,m=%lu,p=%s,us=%lu!\r\n",\
  371. harmonic[j][0],real_image_pair[0],real_image_pair[1],magnitude,q16_to_str(phase),us);
  372. }
  373. // 半波傅氏测试
  374. //fourier32_half
  375. for(j=0;j<3;j++)
  376. {
  377. rt_irq_save(flags);
  378. fourier_test_get_dots((short *)g_adc_dots);
  379. us0 = ustimer_get_origin();
  380. for(i=0;i<1000;i++)
  381. {
  382. fourier32_half((short *)g_adc_dots,real_image_pair,(unsigned int)harmonic[j][1]);
  383. }
  384. us = ustimer_get_duration(us0);
  385. rt_irq_restore(flags);
  386. magnitude = _AmXY(real_image_pair[0],real_image_pair[1]);
  387. phase = _AngPQ(real_image_pair[0],real_image_pair[1]);
  388. rt_printf("fourier32_half(%d):real=%d,image=%d,m=%lu,p=%s,us=%lu!\r\n",\
  389. harmonic[j][0],real_image_pair[0],real_image_pair[1],magnitude,q16_to_str(phase),us);
  390. }
  391. #endif
  392. rt_printf("\r\n");
  393. // ustimer_delay(5*USTIMER_SEC);
  394. return 0;
  395. }
  396. #else
  397. // ***************以下程序在VC中调用,不能在嵌入式环境中使用***********************
  398. #include "stdio.h"
  399. #include "math.h"
  400. #define PI 3.1415926535897932384626433832795
  401. #define AMPLITUDE 1111.0
  402. #define PHASE 11.0
  403. #define COUNT 32
  404. double g_fourier_real32_double[3][32];
  405. double g_fourier_image32_double[3][32];
  406. short g_fourier_coefficient_short[3][2][32];
  407. int aaaa[] =
  408. {
  409. (int)(2.25*65536),(int)(-2.25*65536),(int)(2.75*65536),(int)(-2.75*65536),
  410. };
  411. int fourier_dots(double amp, double phase, int count, short *dots)
  412. {
  413. int i;
  414. double temp;
  415. for(i=0;i<count; i++)
  416. {
  417. temp = amp*sin(phase + i*(2*PI)/count);
  418. if(temp >= 0)
  419. {
  420. temp += 0.5;
  421. }
  422. else
  423. {
  424. temp -= 0.5;
  425. }
  426. dots[i] = (short)(temp);
  427. temp = amp*2*sin(phase*2 + i*2*(2*PI)/count);
  428. if(temp >= 0)
  429. {
  430. temp += 0.5;
  431. }
  432. else
  433. {
  434. temp -= 0.5;
  435. }
  436. dots[i] += (short)(temp);
  437. temp = amp*5*sin(phase*5 + i*5*(2*PI)/count);
  438. if(temp >= 0)
  439. {
  440. temp += 0.5;
  441. }
  442. else
  443. {
  444. temp -= 0.5;
  445. }
  446. dots[i] += (short)(temp);
  447. }
  448. return 0;
  449. }
  450. int fourier_dots_double(double amp, double phase, int count, double *dots)
  451. {
  452. int i;
  453. for(i=0;i<count; i++)
  454. {
  455. dots[i] = amp*sin(phase + i*1*(2*PI)/count);
  456. dots[i] += amp*2*sin(phase*2 + i*2*(2*PI)/count);
  457. dots[i] += amp*5*sin(phase*5 + i*5*(2*PI)/count);
  458. }
  459. return 0;
  460. }
  461. void fourier_coefficient_double(void)
  462. {
  463. int i;
  464. for(i=0;i<32;i++)
  465. {
  466. g_fourier_real32_double[0][i] = cos(11.25*i*1*PI/180)/16*65536;
  467. g_fourier_image32_double[0][i] = sin(11.25*i*1*PI/180)/16*65536;
  468. g_fourier_real32_double[1][i] = cos(11.25*i*2*PI/180)/16*65536;
  469. g_fourier_image32_double[1][i] = sin(11.25*i*2*PI/180)/16*65536;
  470. g_fourier_real32_double[2][i] = cos(11.25*i*5*PI/180)/16*65536;
  471. g_fourier_image32_double[2][i] = sin(11.25*i*5*PI/180)/16*65536;
  472. }
  473. }
  474. void fourier_coefficient_short(void)
  475. {
  476. int i;
  477. double d;
  478. for(i=0;i<32;i++)
  479. {
  480. d = cos(11.25*i*1*PI/180)/16*65536;
  481. d = d>=0 ? d + 0.5 : d - 0.5;
  482. g_fourier_coefficient_short[0][0][i] = (short)d;
  483. d = -sin(11.25*i*1*PI/180)/16*65536;
  484. d = d>=0 ? d + 0.5 : d - 0.5;
  485. g_fourier_coefficient_short[0][1][i] = (short)d;
  486. d= cos(11.25*i*2*PI/180)/16*65536;
  487. d = d>=0 ? d + 0.5 : d - 0.5;
  488. g_fourier_coefficient_short[1][0][i] = (short)d;
  489. d = -sin(11.25*i*2*PI/180)/16*65536;
  490. d = d>=0 ? d + 0.5 : d - 0.5;
  491. g_fourier_coefficient_short[1][1][i] = (short)d;
  492. d = cos(11.25*i*5*PI/180)/16*65536;
  493. d = d>=0 ? d + 0.5 : d - 0.5;
  494. g_fourier_coefficient_short[2][0][i] = (short)d;
  495. d= -sin(11.25*i*5*PI/180)/16*65536;
  496. d = d>=0 ? d + 0.5 : d - 0.5;
  497. g_fourier_coefficient_short[2][1][i] = (short)d;
  498. }
  499. }
  500. void fourier1_sample32_double(double *p,double * real_image_pair,int harmonic)
  501. {
  502. double a,b;
  503. long i;
  504. a = 0;
  505. b = 0;
  506. for(i=0; i<32; i++,p++)
  507. {
  508. a += (*p) * g_fourier_real32_double[harmonic][i];
  509. b += (*p) * g_fourier_image32_double[harmonic][i];
  510. }
  511. real_image_pair[0] = (double)a/65536;
  512. real_image_pair[1] = (double)b/65536;
  513. return;
  514. }
  515. void print_array(FILE *file,short * p)
  516. {
  517. int i,j;
  518. for(i=0; i<4; i++)
  519. {
  520. fprintf(file,"\t");
  521. for(j=0;j<4; j++)
  522. {
  523. fprintf(file,"\t(% 5d<<16)|(% 5d&0xffff),",*p,*(p+1));
  524. // fprintf(file,"\t% 5d,% 5d,",*p,*(p+1));
  525. p += 2;
  526. }
  527. fprintf(file,"\n");
  528. }
  529. }
  530. short g_test_dots[32]=
  531. {
  532. //15152, 13584, 12032, 10632, 9336, 8296, 7536, 7040, 6856, 7008, 7440, 8160, 9144, 10352, 11792, 13288, 14880, 16472, 18040, 19440, 20720, 21736, 22512, 23008, 23200, 23064, 22648, 21880, 20888, 19664, 18264, 16752
  533. 22032, 22704, 23112, 23168, 22936, 22448, 21640, 20512, 19240, 17816, 16248, 14656, 13080, 11568, 10160, 9016, 8040, 7344, 6952, 6880, 7120, 7648, 8440, 9464, 10800, 12232, 13792, 15376, 16992, 18480, 19848, 21088
  534. };
  535. int fourier_test_short(void)
  536. {
  537. short dots[32];
  538. short real_image_pair[2];
  539. double amp,phase,amp_percent,phase_percent;
  540. FILE *file;
  541. int i;
  542. fourier_coefficient_short();
  543. // fourier_dots(AMPLITUDE,PHASE*(PI/180),32,dots);
  544. for(i=0;i<32;i++)
  545. {
  546. dots[i] = g_test_dots[i];
  547. }
  548. file = fopen("f:/fourierdata.c","w");
  549. fprintf(file,"//amplitude=%f,phase=%f,count=%d\n",AMPLITUDE,PHASE,COUNT);
  550. for(i=0;i<3;i++)
  551. {
  552. fourier32_c(dots,real_image_pair,i*sizeof(g_fourier_coefficient[0]));
  553. amp = sqrt((double)(real_image_pair[0]*real_image_pair[0] + real_image_pair[1]*real_image_pair[1]));
  554. amp_percent = (amp - AMPLITUDE)/AMPLITUDE;
  555. phase = atan((double)real_image_pair[1]/real_image_pair[0])*360/(2*PI);
  556. phase_percent = (phase - PHASE)/PHASE;
  557. fprintf(file,"//RESULT(%d):real=%d,image=%d\n",i,real_image_pair[0],real_image_pair[1]);
  558. fprintf(file,"//RESULT(%d):amplitude=%f,phase=%f\n",i,amp,phase);
  559. }
  560. //输出点
  561. fprintf(file,"const short g_fourier_dots[] =\n{\n");
  562. for(i=0;i<COUNT; i++)
  563. {
  564. fprintf(file,"%d,",dots[i]);
  565. if(i%8 == 7)
  566. {
  567. fprintf(file,"\n");
  568. }
  569. }
  570. fprintf(file,"};\n\n");
  571. //输出系数
  572. fprintf(file,"//输出系数\n");
  573. fprintf(file,"const int g_fourier_coefficient[3][2][16]=\n");
  574. fprintf(file,"{\n");
  575. //基波
  576. fprintf(file,"//基波\n");
  577. fprintf(file,"{\n");
  578. fprintf(file," {\n");
  579. fprintf(file," //实部系数?(2/32)*cos(k*1*2*pi/32)*65536\n");
  580. print_array(file,g_fourier_coefficient_short[0][0]);
  581. fprintf(file," },\n");
  582. fprintf(file," {\n");
  583. fprintf(file," //虚部系数?-(2/32)*sin(k*1*2*pi/32)*65536\n");
  584. print_array(file,g_fourier_coefficient_short[0][1]);
  585. fprintf(file," },\n");
  586. fprintf(file,"},\n");
  587. //二次
  588. fprintf(file,"//二次谐波\n");
  589. fprintf(file,"{\n");
  590. fprintf(file," {\n");
  591. fprintf(file," //实部系数?(2/32)*cos(k*2*2*pi/32)*65536\n");
  592. print_array(file,g_fourier_coefficient_short[1][0]);
  593. fprintf(file," },\n");
  594. fprintf(file," {\n");
  595. fprintf(file," //虚部系数?-(2/32)*sin(k*2*2*pi/32)*65536\n");
  596. print_array(file,g_fourier_coefficient_short[1][1]);
  597. fprintf(file," },\n");
  598. fprintf(file,"},\n");
  599. //五次
  600. fprintf(file,"//五次谐波\n");
  601. fprintf(file,"{\n");
  602. fprintf(file," {\n");
  603. fprintf(file," //实部系数?(2/32)*cos(k*5*2*pi/32)*65536\n");
  604. print_array(file,g_fourier_coefficient_short[2][0]);
  605. fprintf(file," },\n");
  606. fprintf(file," {\n");
  607. fprintf(file," //虚部系数?-(2/32)*sin(k*5*2*pi/32)*65536\n");
  608. print_array(file,g_fourier_coefficient_short[2][1]);
  609. fprintf(file," },\n");
  610. fprintf(file,"},\n");
  611. fprintf(file,"};\n\n");
  612. fclose(file);
  613. return 0;
  614. }
  615. int fourier_test_double(void)
  616. {
  617. double dots[32];
  618. double real_image_pair[2];
  619. double amp,phase,amp_percent,phase_percent;
  620. int i;
  621. // fourier_dots_double(AMPLITUDE,PHASE*(PI/180),32,dots);
  622. for(i=0;i<32;i++)
  623. {
  624. dots[i] = (double)g_test_dots[i];
  625. }
  626. fourier_coefficient_double();
  627. for(i=0;i<3;i++)
  628. {
  629. fourier1_sample32_double(dots,real_image_pair,i);
  630. amp = sqrt((double)(real_image_pair[0]*real_image_pair[0] + real_image_pair[1]*real_image_pair[1]));
  631. amp_percent = (amp - AMPLITUDE)/AMPLITUDE;
  632. phase = atan((double)real_image_pair[1]/real_image_pair[0])*360/(2*PI);
  633. phase_percent = (phase - PHASE)/PHASE;
  634. }
  635. return 0;
  636. }
  637. int fourier_test_vc(void)
  638. {
  639. fourier_test_short();
  640. fourier_test_double();
  641. return 0;
  642. }
  643. #endif
  644. #endif