找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12660|回复: 17
打印 上一主题 下一主题
收起左侧

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)


评分

参与人数 1黑币 +2 收起 理由
wuguangyue + 2 赞一个!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:231577 发表于 2017-9-7 10:25 | 只看该作者
顶一下
回复

使用道具 举报

板凳
ID:242686 发表于 2017-10-25 09:56 | 只看该作者
绑定
回复

使用道具 举报

地板
ID:71262 发表于 2017-11-29 22:23 | 只看该作者
顶一下
回复

使用道具 举报

5#
ID:255250 发表于 2017-12-1 09:00 | 只看该作者
扣了5个黑币,但是下载文件不存在 ,晕
回复

使用道具 举报

6#
ID:55591 发表于 2018-2-11 22:25 | 只看该作者

顶一下  正需要
回复

使用道具 举报

7#
ID:295960 发表于 2018-3-23 14:59 | 只看该作者
我也想玩玩电功率表,有的资料分享一下,谢谢  
回复

使用道具 举报

8#
ID:326812 发表于 2018-5-10 14:35 | 只看该作者
不错,支持~~
回复

使用道具 举报

9#
ID:326812 发表于 2018-5-10 14:37 | 只看该作者
很好~想学习学习,
回复

使用道具 举报

10#
ID:347194 发表于 2018-7-18 09:45 | 只看该作者
鼎 顶起 !
回复

使用道具 举报

11#
ID:100247 发表于 2018-9-21 16:53 | 只看该作者
谢谢共享!资料很有学习价值!
回复

使用道具 举报

12#
ID:58730 发表于 2019-1-19 17:17 | 只看该作者
谢谢分享!!
回复

使用道具 举报

13#
ID:72324 发表于 2019-3-11 11:31 | 只看该作者
下载学习了,多谢分享
回复

使用道具 举报

14#
ID:242969 发表于 2019-4-15 15:45 | 只看该作者

不错,支持~~
回复

使用道具 举报

15#
ID:583329 发表于 2019-7-19 11:39 | 只看该作者
这个东西很有用哈哈哈哈
回复

使用道具 举报

16#
ID:593572 发表于 2019-8-3 10:30 | 只看该作者
特别好用!!!
回复

使用道具 举报

17#
ID:830387 发表于 2020-10-15 18:29 | 只看该作者
这样计算电功率和电压,电流,不知道准不准?
回复

使用道具 举报

18#
ID:75487 发表于 2021-1-8 19:38 | 只看该作者
很好~想学习学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表