上篇文章寫了硬件部分的實(shí)現(xiàn)思路,通過采樣電阻的到小電壓后經(jīng)過二級(jí)放大電路得到單片機(jī)可處理的交流電壓,此文介紹了如何采用單片機(jī)采集交流電壓以及stm32ADC外設(shè)的使用。首先是硬件電路部分。
?電路沒有采用核心板,而是直接將芯片焊接到主板上,采用type-c接口供電,調(diào)參采用五軸按鍵,參數(shù)及測(cè)量結(jié)果顯示采用0.96寸OLED顯示,采用有源蜂鳴器作為報(bào)警電路。PCB如圖所示
?交流電壓經(jīng)放大后到達(dá)ADC口,此時(shí)即可進(jìn)行ADC采樣。
ADC采樣采用DMA的方式,初始化主要有兩個(gè)方面:
一:GPIO的初始化
static void ADCx_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//打開 ADC IO 端口時(shí)鐘
ADC_GPIO_APBxClock_FUN(ADC_GPIO_CLK,ENABLE);
//配置ADC IO 引腳模式
//必須為模擬輸入
GPIO_InitStructure.GPIO_Pin = ADC_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
//初始化ADC IO
GPIO_Init(ADC_PORT,&GPIO_InitStructure);
}
二:DMA的初始化
static void ADCx_Mode_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
//打開DMA時(shí)鐘
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
//復(fù)位DMA
DMA_DeInit(ADC_DMA_CHANNEL);
DMA_InitStructure.DMA_PeripheralBaseAddr = ( uint32_t ) ( & (ADC_x->DR ) );
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//Normal是一直傳輸
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(ADC_DMA_CHANNEL,&DMA_InitStructure);
DMA_Cmd(ADC_DMA_CHANNEL,ENABLE);
ADC_InitTypeDef ADC_InitStruct;
ADC_APBxClock_FUN ( ADC_CLK, ENABLE );
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
ADC_InitStruct.ADC_ScanConvMode = DISABLE;
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; //一直轉(zhuǎn)換
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //軟件觸發(fā)
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; //右對(duì)齊
ADC_InitStruct.ADC_NbrOfChannel = 1; //轉(zhuǎn)換通道為一個(gè)
ADC_Init(ADC_x, &ADC_InitStruct);
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL,1, ADC_SampleTime_55Cycles5);
//使能ADC DMA請(qǐng)求
ADC_DMACmd(ADC_x,ENABLE);
ADC_Cmd(ADC_x,ENABLE);
//校準(zhǔn)ADC
ADC_StartCalibration(ADC_x);
//等待校準(zhǔn)完成
while(ADC_GetCalibrationStatus(ADC_x));
//采用軟件觸發(fā)
ADC_SoftwareStartConvCmd(ADC_x,ENABLE);
}
此時(shí)采用DMA傳輸,ADC采樣使用軟件觸發(fā)。在這里我的理解是只要ADC一個(gè)周期轉(zhuǎn)換完成即開始下一次轉(zhuǎn)換。DMA時(shí)刻在更新變量的值。文章來源:http://www.zghlxwxcb.cn/news/detail-523962.html
u16 ch_rms_value(void)
{
u32 sum = 0;
u32 value[200] = {0};
u16 rms = 0;
u16 i = 0;
float squ = 0;
for(i = 0; i < 200; i++) //20ms 采樣200個(gè)點(diǎn)
{
value[i] = ADC_ConvertedValue;
delay_us(100);
}
for(i = 0; i < 200; i++)
{
squ= __fabs(value[i] - 2085.236);
sum += squ*squ;
}
rms = mySqrt(sum / 200); //求均方根值
return rms;
}
計(jì)算交流電壓主要是均方根算法,因交流電壓為市電50Hz,故我們選擇在20ms的周期內(nèi)采樣200個(gè)點(diǎn)。采用的算法是簡(jiǎn)單的delay 100us然后采樣二百個(gè)。在精度要求不高的情況下是可以接受的,若精度要求較高可以自行寫在中斷中自動(dòng)讀取。具體的工程可在主頁(yè)中獲取文章來源地址http://www.zghlxwxcb.cn/news/detail-523962.html
到了這里,關(guān)于基于STM32F103C8T6ADC檢測(cè)交流電壓的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!