freq.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: freq.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2008-06-26
  7. 功能说明: DMA定时器驱动程序。目前只使用了DTIM0,作为延时函数的参考定时器用。
  8. DTIM0的时钟周期为1us。延时函数的最大时间长度为1个小时。
  9. 其它说明: DTIM模块的输入时钟频率DATASHEET上说是 internal bus clock,这个应该
  10. 是fsys/2,但是实际是fsys(即80M)。
  11. 修改记录:
  12. */
  13. #include "bsp.h"
  14. #include "rt.h"
  15. #include "head.h"
  16. #include "shm_comm_packet.h"
  17. /*------------------------------- 宏定义 --------------------------------------
  18. */
  19. /* BSP调试宏定义 */
  20. #if CFG_BSP_DEBUG
  21. #define DTIM_FREQ_DEBUG
  22. #endif
  23. // 频率数据结构体
  24. typedef struct SHM_F_T
  25. {
  26. uint16_t A;
  27. uint16_t B;
  28. struct timespec ts; // 时间戳
  29. uint16_t freq[2]; // 放大1000倍
  30. uint16_t crc;
  31. } SHM_F_T;
  32. /*------------------------------ 全局变量 -------------------------------------
  33. */
  34. float g_freqency[CFG_FREQ_NUM]; // 最后测量出的频率值。
  35. struct rt_stat g_stat_freq[CFG_FREQ_NUM];
  36. /*------------------------------ 外部函数 -------------------------------------
  37. */
  38. /******************************************************************************
  39. 函数名称: freq_init
  40. 函数版本: 01.00
  41. 创建作者:
  42. 创建日期: 2010-05-26
  43. 函数说明: dtim初始化。
  44. 1. 使用dtim0做为延时函数参考定时器;
  45. 2. 使用DTIM2、DTIM3用于两路硬件测频;
  46. 参数说明: 无
  47. 返回值: 无
  48. 修改记录:
  49. */
  50. int freq_init(void)
  51. {
  52. return 0;
  53. }
  54. int freq_exit(void)
  55. {
  56. return 0;
  57. }
  58. static int get_shm_f(uint8_t *out_data)
  59. {
  60. struct t_shmdata_freq sample;
  61. int ret = 0;
  62. int cnt = 0;
  63. if (out_data == NULL)
  64. return -1;
  65. while (1)
  66. {
  67. ret = shm_packet_read_v2(SHM_ADDR_W_FREQ, sizeof(sample), out_data, sizeof(sample));
  68. if (ret > 0)
  69. {
  70. break;
  71. }
  72. if (++cnt > 3)
  73. break;
  74. usleep(30);
  75. }
  76. return ret;
  77. }
  78. int freq_get_shm_data(void)
  79. {
  80. float freq = 50.0;
  81. struct t_shmdata_freq shm_f;
  82. int ret = 0;
  83. #ifdef DTIM_FREQ_DEBUG
  84. static int start_stat_flag = 0;
  85. if (start_stat_flag == 0)
  86. {
  87. start_stat_flag++;
  88. freq_stat_reset();
  89. }
  90. #endif
  91. // 从共享内存中读取频率到freq
  92. // ret = get_shm_f((uint8_t *)&shm_f);
  93. ret = shm_packet_read_v2(SHM_ADDR_W_FREQ, sizeof(shm_f), (uint8_t *)&shm_f, sizeof(shm_f));
  94. if (ret > 0)
  95. {
  96. for (uint8_t i = 0; i < CFG_FREQ_NUM; i++)
  97. {
  98. freq = (float)shm_f.us_freq[i] * 0.001f;
  99. #ifdef DTIM_FREQ_DEBUG
  100. rt_stat_in(&g_stat_freq[i], rt_round(freq * Q16_BASE));
  101. #endif
  102. // 将频率范围限定在45hz到55hz。
  103. if (freq >= 44.0 && freq <= 56.0)
  104. {
  105. g_freqency[i] = freq;
  106. }
  107. }
  108. }
  109. return ret;
  110. }
  111. /******************************************************************************
  112. 函数名称: freq_get
  113. 函数版本: 01.01
  114. 创建作者: sunxi
  115. 创建日期: 2008-10-17
  116. 函数说明: 得到测量频率的值。
  117. 参数说明: 无
  118. 返回值: 返回测量的频率。
  119. 修改记录:
  120. */
  121. float freq_get(unsigned int index)
  122. {
  123. #if !defined CPU_FUXI
  124. u32 e;
  125. float freq = 50.0;
  126. struct t_shmdata_freq shm_f;
  127. int ret = 0;
  128. #ifdef DTIM_FREQ_DEBUG // added by sunxi: for FUXI
  129. static int start_stat_flag = 0;
  130. if (start_stat_flag == 0)
  131. {
  132. start_stat_flag++;
  133. freq_stat_reset();
  134. }
  135. #endif
  136. if (index >= CFG_FREQ_NUM)
  137. {
  138. return 0.0;
  139. }
  140. if (g_ui_freq[index] == UI_NUM)
  141. {
  142. return 0.0;
  143. }
  144. // 额定值100V的20%是20V(20%一般是一个测试点),保证测试点频率可用,所以选19V。
  145. // 20160825:测试发现只要能够测到频率,就基本是准的,所以将门槛降低到5v,满足电子互感器
  146. // 额定值57.735v的要求。
  147. e = _Mul_Div_U(sqrt_32fix(g_ui[g_ui_freq[index]].m2[0]), 256, g_ui[g_ui_freq[index]].m2_factor_k);
  148. if (e < Q16_BASE * 5)
  149. {
  150. if (g_run_stu.yf)
  151. {
  152. dp_info_nt_rt("index = %d", index);
  153. }
  154. return 0.0;
  155. }
  156. //==============>
  157. // added by sunxi: for FUXI
  158. // 从共享内存中读取频率到freq
  159. ret = get_shm_f((uint8_t *)&shm_f);
  160. if (g_run_stu.yf)
  161. {
  162. dp_info_nt_rt("ret = %d", ret);
  163. }
  164. // printf("ret=%d, us_updata=%u, us_op=%u, us_op_bk=%u, freq0=%u, freq0=%u, crc=%u\n\n",
  165. // ret, shm_f.us_updata, shm_f.us_op, shm_f.us_op_bk, shm_f.us_freq[0], shm_f.us_freq[1], shm_f.us_crc);
  166. if (ret < 0)
  167. return 0.0;
  168. // freq = (float)shm_f.us_freq[index]/1000;
  169. freq = (float)shm_f.us_freq[index] * 0.001f;
  170. #ifdef DTIM_FREQ_DEBUG
  171. rt_stat_in(&g_stat_freq[index], rt_round(shm_f.us_freq[index] * Q16_BASE));
  172. #endif
  173. // 将频率范围限定在45hz到55hz。
  174. if (freq >= 44.0 && freq <= 56.0)
  175. {
  176. g_freqency[index] = freq;
  177. }
  178. //<=================
  179. return g_freqency[index];
  180. #else
  181. u32 e;
  182. if (index >= CFG_FREQ_NUM)
  183. {
  184. return 0.0;
  185. }
  186. if (g_ui_freq[index] == UI_NUM)
  187. {
  188. return 0.0;
  189. }
  190. // 20160825:测试发现只要能够测到频率,就基本是准的,所以将门槛降低到5v,满足电子互感器
  191. // 额定值57.735v的要求。
  192. e = _Mul_Div_U(sqrt_32fix(g_ui[g_ui_freq[index]].m2[0]), 256, g_ui[g_ui_freq[index]].m2_factor_k);
  193. if (e < Q16_BASE * 5)
  194. {
  195. return 0.0;
  196. }
  197. return g_freqency[index];
  198. #endif
  199. }
  200. int freq_stat_reset(void)
  201. {
  202. int i;
  203. for (i = 0; i < CFG_FREQ_NUM; i++)
  204. {
  205. if (i == 0)
  206. {
  207. rt_stat_init(&g_stat_freq[0], "freq0");
  208. }
  209. else
  210. {
  211. rt_stat_init(&g_stat_freq[1], "freq1");
  212. }
  213. }
  214. return 0;
  215. }
  216. int freq_stat_printf(void)
  217. {
  218. int i;
  219. rt_printf("\r\n[频率测量统计]\r\n");
  220. for (i = 0; i < CFG_FREQ_NUM; i++)
  221. {
  222. rt_printf("g_ui_freq[%d]=%d.\r\n", i, g_ui_freq[i]);
  223. rt_printf("g_freqency[%d]=%f.\r\n", i, g_freqency[i]); // sunxi 20190830 addd
  224. rt_stat_printf_q16(&g_stat_freq[i]);
  225. }
  226. return 0;
  227. }
  228. /*------------------------------ 测试函数 -------------------------------------
  229. */
  230. #ifdef DTIM_DEBUG
  231. int freq_test(void)
  232. {
  233. return 0;
  234. }
  235. #endif
  236. /*------------------------------ 文件结束 -------------------------------------
  237. */