标题: HLW8012的STM32单片机源码-pfc功率因数测试制作及固件下载 [打印本页]

作者: 清流水银    时间: 2017-9-3 08:41
标题: HLW8012的STM32单片机源码-pfc功率因数测试制作及固件下载
基于HLW8012芯片的pfc功率因数测试仪制作资料,下面是stm32工程元源码.


单片机源程序如下:
  1. #include "stm32_usart.h"
  2. #include "stm32_delay.h"
  3. #include "stm32_led.h"
  4. #include "stm32_key.h"
  5. #include "sys.h"
  6. #include "stm32_oled.h"
  7. #include "stm32_timer.h"

  8. char tempStr[30];
  9. int tempStrLen;
  10. int tempI;

  11. float hlw8012_f;
  12. float hlw8012_P;
  13. float hlw8012_Pp = 103.5 / 21.6;

  14. extern  recType     tRecType;
  15.         u32         countTotal;
  16.         float       hlw8012_f;
  17.         u32         freq_arr;

  18. #define CNT_TO_US(cnt)      (u32)((cnt +         (TIM4_FREQ / 2000000)) / (TIM4_FREQ / 1000000) )   // 获取周期     ((cnt + 36) / 72)   (cnt / 72)          四舍五入    u16 or u32
  19. #define CNT_TO_FREQ(cnt)    (u32)((TIM1_FREQ +   (cnt       / 2      )) / cnt                   )   // 获取频率                         (72000000 / cnt)    四舍五入    u32
  20. #define FREQ_TO_CNT(freq)   (u32)((TIM1_FREQ +   (freq      / 2      )) / freq                  )   // 获取计数值                       (72000000 / freq)   四舍五入    u32
  21. #define US_TO_CNT(us)       (u32)((TIM1_FREQ / 1000000) * us                                    )   // 获取技术值                       (72 * us)                       u32

  22. #define U16_TO_U32(H, L)    (u32)((u32)(H << 16) + L)

  23. unsigned char data_check (recType *pRec, float *modePow);

  24. int main(void)
  25. {
  26.     float Pow_mode;
  27.     delay_init();                //延时初始化
  28.     NVIC_Configuration();   //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  29.     uart_init(115200);
  30.    
  31.     keyInit();
  32.     OLED_Init();
  33.    
  34.     LED_Init();
  35.     TIM3_Int_Init(5000, 7200-1);
  36.    
  37.     OLED_Clear();
  38. //   OLED_ShowString(10 * 8,6," KEY  ");
  39.     OLED_ShowCHinese(28 + 0,0,0);
  40.     OLED_ShowCHinese(28 + 16,0,1);
  41.     OLED_ShowCHinese(28 + 32,0,2);
  42.     OLED_ShowCHinese(28 + 48,0,3);
  43.    
  44. //    //OLED_ShowString(0,3," www.szlcsc.com");
  45. //    OLED_ShowString(16,6,"1234");
  46.    
  47.     TIM1_Cap_Init(65536 - 1, TIM1_PSC);
  48.    
  49.    
  50.     RCC_ClocksTypeDef RCC_ClocksStatus;
  51.     RCC_GetClocksFreq(&RCC_ClocksStatus);
  52.     printf("SYSCLK_Frequency: %d Hz\r\n", RCC_ClocksStatus.SYSCLK_Frequency);
  53.     printf("HCLK_Frequency:   %d Hz\r\n", RCC_ClocksStatus.HCLK_Frequency);
  54.     printf("PCLK1_Frequency:  %d Hz\r\n", RCC_ClocksStatus.PCLK1_Frequency);
  55.     printf("PCLK2_Frequency:  %d Hz\r\n", RCC_ClocksStatus.PCLK2_Frequency);
  56.    
  57.    
  58.         while(1) {
  59.                
  60.         TIM1->SR = (uint16_t)~TIM_IT_CC1;                       // 清中断
  61.         TIM1->SR = (uint16_t)~TIM_IT_Update;                    // 清中断
  62.         TIM_ITConfig(TIM1, TIM_IT_Update | TIM_IT_CC1, ENABLE);
  63.         TIM_Cmd(TIM1, ENABLE);
  64.         
  65.         // 捕捉超过3秒
  66.         if ((tRecType.currOverCnt > (TIM1_FREQ / 65536) * 3) || (tRecType.size > 10)) {
  67.             TIM_ITConfig(TIM1, TIM_IT_Update | TIM_IT_CC1, DISABLE);
  68.             TIM_Cmd(TIM1, DISABLE);
  69.             
  70.             data_check(&tRecType, &Pow_mode);
  71.             tRecType.size = 0;
  72.             tRecType.currOverCnt = 0;
  73.             
  74.             if (Pow_mode > 5)
  75.                 showPower(1, Pow_mode);
  76.             else
  77.                 showPower(1, 20000);
  78.         }
  79.         }
  80.    
  81.     return 1;
  82. }

  83. //u32 mYverage (u)          递归法:假设前n个数的平均数为avg, 那么前n+1个数的平均数avg = ((avg * n) + X) / (n + 1) = avg - avg / (n + 1) + X / (n + 1) = avg + (X - avg) / (n + 1)
  84. float mYverage (float avg, float X, u32 n)
  85. {
  86.     if (n == 0) {
  87.         return 0;
  88.     } else if (n == 1) {
  89.         return X;
  90.     } else if (n > 1) {
  91.         if (X > avg) {
  92.             return (avg + (X - avg) / n);
  93.         } else {
  94.             return (avg - (avg - X) / n);
  95.         }
  96.     } else {
  97.         return 0;
  98.     }
  99. }

  100. unsigned char data_check (recType *pRec, float *modePow)
  101. {
  102.     unsigned char ret = 1;
  103.     float fAvg;
  104.     u32 u32Temp1, u32Temp2;
  105.     u16 i = 0, j = 0;
  106.    
  107.     if (pRec->size == 0 || pRec->size == 1) {   // 不够1Hz
  108.         *modePow = 0;
  109.         ret = 0;
  110.         goto end;
  111.     }
  112.    
  113.     // 矫正 数据中 溢出中断 与 捕获中断 并发 造成的 溢出数据(overCnt) 顺序混乱的情况
  114.     for (i = 0; i < pRec->size; i++) {
  115.         if (pRec->overCnt[i] == pRec->overCnt[i + 1]) {
  116.             if (pRec->cnt[i] > pRec->cnt[i + 1]) {                      // 后面的数据小于前面的数据--这种情况不应该发生
  117.                 pRec->overCnt[i + 1]++;
  118.             }
  119.         }
  120.     }
  121.    
  122.     // 将 数据 由 绝对值 换算为 相对值
  123.     for (i = 0; i < pRec->size - 1; i++) {
  124.         u32Temp1 = U16_TO_U32(pRec->overCnt[i + 0], pRec->cnt[i + 0]);
  125.         u32Temp2 = U16_TO_U32(pRec->overCnt[i + 1], pRec->cnt[i + 1]);
  126.         
  127.         pRec->overCnt[i]    = (u16)((u32Temp2 - u32Temp1) >> 16);
  128.         pRec->cnt[i]        = (u16)((u32Temp2 - u32Temp1) >> 0);
  129.     }
  130.     pRec->size -= 1;                                                    // 数量减一
  131.    
  132.     // 删除 波形中 的高频毛刺
  133.     for (i = 0; i < pRec->size; i++) {
  134.         u32Temp1 = U16_TO_U32(pRec->overCnt[i], pRec->cnt[i]);
  135.         if (CNT_TO_FREQ(u32Temp1) > 100000) {                   // TIM1_FREQ / 100KHz = 720 过滤掉>100KHz的波形
  136.             for (j = i; j < pRec->size - 1; j++) {
  137.                 pRec->overCnt[j]    = pRec->overCnt[j + 1];
  138.                 pRec->cnt[j]        = pRec->cnt[j + 1];
  139.             }
  140.             pRec->size--;
  141.         }
  142.     }
  143.    
  144.     // 将 高频数据 整合在一起 求平均
  145.     fAvg = 0;
  146.     for (i = 0; i < pRec->size; i++) {
  147.         u32Temp1 = U16_TO_U32(pRec->overCnt[i], pRec->cnt[i]);
  148.         fAvg = mYverage(fAvg, (float)u32Temp1, i + 1);
  149.     }
  150.     *modePow = hlw8012_Pp * CNT_TO_FREQ((u32)fAvg);                     //  计算功率
  151.    
  152.     /********************************打印数据************************************************/
  153.     tempStrLen = sprintf(tempStr,"%f", *modePow);
  154.     txNByte(USART1, tempStr, tempStrLen);
  155.     txStr(USART1, "w\r\n");
  156.     /********************************打印数据************************************************/
  157. end:
  158.     return ret;
  159. }
复制代码

所有资料51hei提供下载:
单片机源码及固件下载.zip (3.99 MB, 下载次数: 271)



作者: 创业者联盟    时间: 2017-9-7 10:25
顶一下
作者: yunzhuxiao    时间: 2017-10-25 09:56
绑定
作者: cdl511    时间: 2017-11-29 22:23
顶一下
作者: SHAOLM    时间: 2017-12-1 09:00
扣了5个黑币,但是下载文件不存在 ,晕
作者: 右走    时间: 2018-2-11 22:25

顶一下  正需要
作者: wuguangyue    时间: 2018-3-23 14:59
我也想玩玩电功率表,有的资料分享一下,谢谢  
作者: kcgf    时间: 2018-5-10 14:35
不错,支持~~
作者: kcgf    时间: 2018-5-10 14:37
很好~想学习学习,
作者: ABCLSL    时间: 2018-7-18 09:45
鼎 顶起 !
作者: jzzgb    时间: 2018-9-21 16:53
谢谢共享!资料很有学习价值!
作者: cyllife    时间: 2019-1-19 17:17
谢谢分享!!
作者: lionmon    时间: 2019-3-11 11:31
下载学习了,多谢分享
作者: swap1    时间: 2019-4-15 15:45

不错,支持~~
作者: ydgzuishuai    时间: 2019-7-19 11:39
这个东西很有用哈哈哈哈
作者: 2893068776    时间: 2019-8-3 10:30
特别好用!!!
作者: jims9809303    时间: 2020-10-15 18:29
这样计算电功率和电压,电流,不知道准不准?
作者: mhse    时间: 2021-1-8 19:38
很好~想学习学习




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1