/****************************************************************************** 版权所有: 文件名称: freq.c 文件版本: 01.01 创建作者: sunxi 创建日期: 2008-06-26 功能说明: DMA定时器驱动程序。目前只使用了DTIM0,作为延时函数的参考定时器用。 DTIM0的时钟周期为1us。延时函数的最大时间长度为1个小时。 其它说明: DTIM模块的输入时钟频率DATASHEET上说是 internal bus clock,这个应该 是fsys/2,但是实际是fsys(即80M)。 修改记录: */ #include "bsp.h" #include "rt.h" #include "head.h" #include "shm_comm_packet.h" /*------------------------------- 宏定义 -------------------------------------- */ /* BSP调试宏定义 */ #if CFG_BSP_DEBUG #define DTIM_FREQ_DEBUG #endif // 频率数据结构体 typedef struct SHM_F_T { uint16_t A; uint16_t B; struct timespec ts; // 时间戳 uint16_t freq[2]; // 放大1000倍 uint16_t crc; } SHM_F_T; /*------------------------------ 全局变量 ------------------------------------- */ float g_freqency[CFG_FREQ_NUM]; // 最后测量出的频率值。 struct rt_stat g_stat_freq[CFG_FREQ_NUM]; /*------------------------------ 外部函数 ------------------------------------- */ /****************************************************************************** 函数名称: freq_init 函数版本: 01.00 创建作者: 创建日期: 2010-05-26 函数说明: dtim初始化。 1. 使用dtim0做为延时函数参考定时器; 2. 使用DTIM2、DTIM3用于两路硬件测频; 参数说明: 无 返回值: 无 修改记录: */ int freq_init(void) { return 0; } int freq_exit(void) { return 0; } static int get_shm_f(uint8_t *out_data) { struct t_shmdata_freq sample; int ret = 0; int cnt = 0; if (out_data == NULL) return -1; while (1) { ret = shm_packet_read_v2(SHM_ADDR_W_FREQ, sizeof(sample), out_data, sizeof(sample)); if (ret > 0) { break; } if (++cnt > 3) break; usleep(30); } return ret; } /****************************************************************************** 函数名称: freq_get 函数版本: 01.01 创建作者: sunxi 创建日期: 2008-10-17 函数说明: 得到测量频率的值。 参数说明: 无 返回值: 返回测量的频率。 修改记录: */ float freq_get(unsigned int index) { u32 e; float freq = 50.0; struct t_shmdata_freq shm_f; int ret = 0; #ifdef DTIM_FREQ_DEBUG // added by sunxi: for FUXI static int start_stat_flag = 0; if (start_stat_flag == 0) { start_stat_flag++; freq_stat_reset(); } #endif if (index >= CFG_FREQ_NUM) { return 0.0; } if (g_ui_freq[index] == UI_NUM) { return 0.0; } // 额定值100V的20%是20V(20%一般是一个测试点),保证测试点频率可用,所以选19V。 // 20160825:测试发现只要能够测到频率,就基本是准的,所以将门槛降低到5v,满足电子互感器 // 额定值57.735v的要求。 e = _Mul_Div_U(sqrt_32fix(g_ui[g_ui_freq[index]].m2[0]), 256, g_ui[g_ui_freq[index]].m2_factor_k); if (e < Q16_BASE * 5) { return 0.0; } //==============> // added by sunxi: for FUXI // 从共享内存中读取频率到freq ret = get_shm_f((uint8_t *)&shm_f); // printf("ret=%d, us_updata=%u, us_op=%u, us_op_bk=%u, freq0=%u, freq0=%u, crc=%u\n\n", // 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); if (ret < 0) return 0.0; // freq = (float)shm_f.us_freq[index]/1000; freq = (float)shm_f.us_freq[index] * 0.001f; #ifdef DTIM_FREQ_DEBUG rt_stat_in(&g_stat_freq[index], rt_round(shm_f.us_freq[index] * Q16_BASE)); #endif // 将频率范围限定在45hz到55hz。 if (freq >= 44.0 && freq <= 56.0) { g_freqency[index] = freq; } //<================= return g_freqency[index]; } int freq_stat_reset(void) { int i; for (i = 0; i < CFG_FREQ_NUM; i++) { if (i == 0) { rt_stat_init(&g_stat_freq[0], "freq0"); } else { rt_stat_init(&g_stat_freq[1], "freq1"); } } return 0; } int freq_stat_printf(void) { int i; rt_printf("\r\n[频率测量统计]\r\n"); for (i = 0; i < CFG_FREQ_NUM; i++) { rt_printf("g_ui_freq[%d]=%d.\r\n", i, g_ui_freq[i]); rt_printf("g_freqency[%d]=%f.\r\n", i, g_freqency[i]); // sunxi 20190830 addd rt_stat_printf_q16(&g_stat_freq[i]); } return 0; } /*------------------------------ 测试函数 ------------------------------------- */ #ifdef DTIM_DEBUG int freq_test(void) { return 0; } #endif /*------------------------------ 文件结束 ------------------------------------- */