打印
[其他ST产品]

STM32 测量交流电压的方法

[复制链接]
1532|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
关于STM32测量交流电的一种方法.

关于交流电压测量的难点有以下几点:1.电压过大,比如市电220V,2.交流电和直流电区别很大,例如值一直在变不稳定.3.交流电压存在负值,STM32 的AD模块没法测量.4.STM32读取的电压值是瞬时值和交流电的有效值还要转换.

针对以上几点:可以采取合适的硬件设计和算法设计解决.采用电流互感器将电压从高变低,采用直流电压叠加的方式将整体的交流波形抬升,抬升到最低都大于零.至于读取到的数值采用均方根的算法算出交流有效值.另外还要注意一点是采样周期的设置.

电路设计:


使用特权

评论回复
沙发
我爱台妹mmd|  楼主 | 2023-5-30 19:52 | 只看该作者
这个硬件电路设计很完善.还有一种:

使用特权

评论回复
板凳
我爱台妹mmd|  楼主 | 2023-5-30 19:52 | 只看该作者
第二种电路结构更简单,但是运放采用的是用于测量交流信号的MCP6292.

两种设计的思路大致相同,都是互感器降压,降压信号放大,直流叠加,然后测量.

下面是对交流电压有效值算法的数学推导,(这里我用的是和交流电压相似的一个物理量,可以理解成交流电压的有效值算法)

使用特权

评论回复
地板
我爱台妹mmd|  楼主 | 2023-5-30 19:52 | 只看该作者
针对第二种电路图程序如下:

取一百个点测算变压器二次端的电压有效值然后根据放大倍数和变压器的比率算出实际接入电压的有效值.

注意转换时间要短.Uac的值除以放大倍数(4),就是接在160Ω电阻的电压,再除以160就是流过电流互感器两边的电流,乘以300K就是接入的交流电压有效值.
        void  Adc_Init(void)
{        
        ADC_InitTypeDef ADC_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1        , ENABLE );         


        RCC_ADCCLKConfig(RCC_PCLK2_Div6);                     
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;               
        GPIO_Init(GPIOA, &GPIO_InitStructure);       

        ADC_DeInit(ADC1);  

        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;       
        ADC_InitStructure.ADC_ScanConvMode = DISABLE;
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;       
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;       
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;       
        ADC_InitStructure.ADC_NbrOfChannel = 1;       
        ADC_Init(ADC1, &ADC_InitStructure);       
        ADC_Cmd(ADC1, ENABLE);       
        ADC_ResetCalibration(ADC1);       
         
        while(ADC_GetResetCalibrationStatus(ADC1));       
       
        ADC_StartCalibration(ADC1);       

        while(ADC_GetCalibrationStatus(ADC1));       



}                                  

u16 Get_Adc(u8 ch)   
{
         
        ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_13Cycles5 );                                     
  
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);               
         
        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));

        return ADC_GetConversionValue(ADC1);       
}

u16 Get_Adc_Average(u8 ch,u8 times)
{
        u32 temp_val=0;
        u8 t;
        for(t=0;t<times;t++)
        {
                temp_val+=Get_Adc(ch);
                delay_ms(5);
        }
        return temp_val/times;
}          




                int main()
               {
                for(j=0;j<100;j++)
                {
                                adcx=Get_Adc_Average(ADC_Channel_1,1);
                                Num[j] = (float)adcx*(3.3/4096)-1.24;
                                u1+=Num[j]*Num[j];
                               
                }
                        u1 = sqrt(u1/100);
                temp = u1*468.75;
                LCD_ShowxNum(172,192,temp,3,24,0);
              }


使用特权

评论回复
5
kissdb| | 2023-6-10 15:26 | 只看该作者
最近需要做交流电的测量,学习一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

67

主题

538

帖子

0

粉丝