具體原理參考說明書,代碼依據(jù)正點原子
ADC.c 文件
/**
****************************************************************************************************
* @file adc.c
* @author 正點原子團隊(ALIENTEK)
* @version V1.0
* @date 2020-04-23
* @brief ADC 驅(qū)動代碼
* @license Copyright (c) 2020-2032, 廣州市星翼電子科技有限公司
****************************************************************************************************
* @attention
*
* 實驗平臺:正點原子 STM32F103開發(fā)板
* 在線視頻:www.yuanzige.com
* 技術(shù)論壇:www.openedv.com
* 公司網(wǎng)址:www.alientek.com
* 購買地址:openedv.taobao.com
*
* 修改說明
* V1.0 20200423
* 第一次發(fā)布
*
****************************************************************************************************
*/
#include "adc.h"
#include "./SYSTEM/delay/delay.h"
ADC_HandleTypeDef g_adc_handle; /* ADC句柄 */
/**
* @brief ADC初始化函數(shù)
* @note 本函數(shù)支持ADC1/ADC2任意通道, 但是不支持ADC3
* 我們使用12位精度, ADC采樣時鐘=12M, 轉(zhuǎn)換時間為: 采樣周期 + 12.5個ADC周期
* 設(shè)置最大采樣周期: 239.5, 則轉(zhuǎn)換時間 = 252 個ADC周期 = 21us
* @param 無
* @retval 無
*/
void adc_init(void)
{
g_adc_handle.Instance = ADC_ADCX; /* 選擇哪個ADC */
g_adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* 數(shù)據(jù)對齊方式:右對齊 */
g_adc_handle.Init.ScanConvMode = ADC_SCAN_DISABLE; /* 非掃描模式,僅用到一個通道 */
g_adc_handle.Init.ContinuousConvMode = DISABLE; /* 關(guān)閉連續(xù)轉(zhuǎn)換模式 */
g_adc_handle.Init.NbrOfConversion = 1; /* 賦值范圍是1~16,本實驗用到1個規(guī)則通道序列 */
g_adc_handle.Init.DiscontinuousConvMode = DISABLE; /* 禁止規(guī)則通道組間斷模式 */
g_adc_handle.Init.NbrOfDiscConversion = 0; /* 配置間斷模式的規(guī)則通道個數(shù),禁止規(guī)則通道組間斷模式后,此參數(shù)忽略 */
g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* 觸發(fā)轉(zhuǎn)換方式:軟件觸發(fā) */
HAL_ADC_Init(&g_adc_handle); /* 初始化 */
HAL_ADCEx_Calibration_Start(&g_adc_handle); /* 校準(zhǔn)ADC */
}
/**
* @brief ADC底層驅(qū)動,引腳配置,時鐘使能
此函數(shù)會被HAL_ADC_Init()調(diào)用
* @param hadc:ADC句柄
* @retval 無
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
if(hadc->Instance == ADC_ADCX)
{
GPIO_InitTypeDef gpio_init_struct;
RCC_PeriphCLKInitTypeDef adc_clk_init = {0};
ADC_ADCX_CHY_CLK_ENABLE(); /* 使能ADCx時鐘 */
ADC_ADCX_CHY_GPIO_CLK_ENABLE(); /* 開啟GPIO時鐘 */
/* 設(shè)置ADC時鐘 */
adc_clk_init.PeriphClockSelection = RCC_PERIPHCLK_ADC; /* ADC外設(shè)時鐘 */
adc_clk_init.AdcClockSelection = RCC_ADCPCLK2_DIV6; /* 分頻因子6時鐘為72M/6=12MHz */
HAL_RCCEx_PeriphCLKConfig(&adc_clk_init); /* 設(shè)置ADC時鐘 */
/* 設(shè)置AD采集通道對應(yīng)IO引腳工作模式 */
gpio_init_struct.Pin = ADC_ADCX_CHY_GPIO_PIN; /* ADC通道IO引腳 */
gpio_init_struct.Mode = GPIO_MODE_ANALOG; /* 模擬 */
HAL_GPIO_Init(ADC_ADCX_CHY_GPIO_PORT, &gpio_init_struct);
}
}
/**
* @brief 設(shè)置ADC通道采樣時間
* @param adcx : adc句柄指針,ADC_HandleTypeDef
* @param ch : 通道號, ADC_CHANNEL_0~ADC_CHANNEL_17
* @param stime: 采樣時間 0~7, 對應(yīng)關(guān)系為:
* @arg ADC_SAMPLETIME_1CYCLE_5, 1.5個ADC時鐘周期 ADC_SAMPLETIME_7CYCLES_5, 7.5個ADC時鐘周期
* @arg ADC_SAMPLETIME_13CYCLES_5, 13.5個ADC時鐘周期 ADC_SAMPLETIME_28CYCLES_5, 28.5個ADC時鐘周期
* @arg ADC_SAMPLETIME_41CYCLES_5, 41.5個ADC時鐘周期 ADC_SAMPLETIME_55CYCLES_5, 55.5個ADC時鐘周期
* @arg ADC_SAMPLETIME_71CYCLES_5, 71.5個ADC時鐘周期 ADC_SAMPLETIME_239CYCLES_5, 239.5個ADC時鐘周期
* @param rank: 多通道采集時需要設(shè)置的采集編號,
假設(shè)你定義channle1的rank=1,channle2 的rank=2,
那么對應(yīng)你在DMA緩存空間的變量數(shù)組AdcDMA[0] 就i是channle1的轉(zhuǎn)換結(jié)果,AdcDMA[1]就是通道2的轉(zhuǎn)換結(jié)果。
單通道DMA設(shè)置為 ADC_REGULAR_RANK_1
* @arg 編號1~16:ADC_REGULAR_RANK_1~ADC_REGULAR_RANK_16
* @retval 無
*/
void adc_channel_set(ADC_HandleTypeDef *adc_handle, uint32_t ch, uint32_t rank, uint32_t stime)
{
ADC_ChannelConfTypeDef adc_ch_conf;
adc_ch_conf.Channel = ch; /* 通道 */
adc_ch_conf.Rank = rank; /* 序列 */
adc_ch_conf.SamplingTime = stime; /* 采樣時間 */
HAL_ADC_ConfigChannel(adc_handle, &adc_ch_conf); /* 通道配置 */
}
/**
* @brief 獲得ADC轉(zhuǎn)換后的結(jié)果
* @param ch: 通道值 0~17,取值范圍為:ADC_CHANNEL_0~ADC_CHANNEL_17
* @retval 無
*/
uint32_t adc_get_result(uint32_t ch)
{
adc_channel_set(&g_adc_handle , ch, ADC_REGULAR_RANK_1, ADC_SAMPLETIME_239CYCLES_5); /* 設(shè)置通道,序列和采樣時間 */
HAL_ADC_Start(&g_adc_handle); /* 開啟ADC */
HAL_ADC_PollForConversion(&g_adc_handle, 10); /* 輪詢轉(zhuǎn)換 */
return (uint16_t)HAL_ADC_GetValue(&g_adc_handle); /* 返回最近一次ADC1規(guī)則組的轉(zhuǎn)換結(jié)果 */
}
/**
* @brief 獲取通道ch的轉(zhuǎn)換值,取times次,然后平均
* @param ch : 通道號, 0~17
* @param times : 獲取次數(shù)
* @retval 通道ch的times次轉(zhuǎn)換結(jié)果平均值
*/
uint32_t adc_get_result_average(uint32_t ch, uint8_t times)
{
uint32_t temp_val = 0;
uint32_t i = 0;
uint8_t t;
for (t = 0; t < times; t++) /* 獲取times次數(shù)據(jù) */
{
temp_val += adc_get_result(ch);
HAL_Delay(5);
}
i = temp_val / times; /* 返回平均值 */
return i;
}
ADC.h文件文章來源:http://www.zghlxwxcb.cn/news/detail-858511.html
/**
****************************************************************************************************
* @file adc.h
* @author 正點原子團隊(ALIENTEK)
* @version V1.0
* @date 2020-04-23
* @brief ADC 驅(qū)動代碼
* @license Copyright (c) 2020-2032, 廣州市星翼電子科技有限公司
****************************************************************************************************
* @attention
*
* 實驗平臺:正點原子 STM32F103開發(fā)板
* 在線視頻:www.yuanzige.com
* 技術(shù)論壇:www.openedv.com
* 公司網(wǎng)址:www.alientek.com
* 購買地址:openedv.taobao.com
*
* 修改說明
* V1.0 20200423
* 第一次發(fā)布
*
****************************************************************************************************
*/
#ifndef __ADC_H
#define __ADC_H
#include "stm32f1xx.h" // Device header
/******************************************************************************************/
/* ADC及引腳 定義 */
#define ADC_ADCX_CHY_GPIO_PORT GPIOA
#define ADC_ADCX_CHY_GPIO_PIN GPIO_PIN_1
#define ADC_ADCX_CHY_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口時鐘使能 */
#define ADC_ADCX ADC1
#define ADC_ADCX_CHY ADC_CHANNEL_1 /* 通道Y, 0 <= Y <= 17 */
#define ADC_ADCX_CHY_CLK_ENABLE() do{ __HAL_RCC_ADC1_CLK_ENABLE(); }while(0) /* ADC1 時鐘使能 */
/******************************************************************************************/
void adc_init(void); /* ADC初始化 */
void adc_channel_set(ADC_HandleTypeDef *adc_handle, uint32_t ch,uint32_t rank, uint32_t stime); /* ADC通道設(shè)置 */
uint32_t adc_get_result(uint32_t ch); /* 獲得某個通道值 */
uint32_t adc_get_result_average(uint32_t ch, uint8_t times); /* 得到某個通道給定次數(shù)采樣的平均值 */
#endif
main函數(shù)中的調(diào)用文章來源地址http://www.zghlxwxcb.cn/news/detail-858511.html
adc_init(); /* 初始化ADC */
while(1)
{
adcx = adc_get_result_average(ADC_ADCX_CHY, 10); /* 獲取通道5的轉(zhuǎn)換值,10次取平均 */
temp = (float)adcx * (3.3 / 4096); /* 獲取計算后的帶小數(shù)的實際電壓值,比如3.1111 */
// 整數(shù)部分
adcx = temp; /* 賦值整數(shù)部分給adcx變量,因為adcx為u16整形 */
// 小數(shù)部分
temp -= adcx; /* 把已經(jīng)顯示的整數(shù)部分去掉,留下小數(shù)部分,比如3.1111-3=0.1111 */
temp *= 1000; /* 小數(shù)部分乘以1000,例如:0.1111就轉(zhuǎn)換為111.1,相當(dāng)于保留三位小數(shù)。 */
}
到了這里,關(guān)于MQ2煙霧傳感器 - STM32F103C8T6-HAL庫的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!