>[success] **技術支持說明**
> 1.**客服**提供簡單的技術支持,一般自主學習為主
> 2.可到官方問答社區中提問:[**去提問**](https://bbs.csdn.net/forums/nb-iot)
> 3.工程師**會盡快**解答社區問題,但他們是一線開發,【**難以保證**】解答時效,解答辛苦,感謝理解!
<br/>
## **ADC理論基礎**
* **模擬信號**:模擬信號是指用連續變化的物理量所表達的信息,特點是信號值的變化是連續的,如下圖所示。

###
* **數字信號**:數字信號是指用一系列斷續變化的脈沖數字量所表達的信息,特點是信號值會特然變化,如下圖所示。

###
* **ADC**:即模數轉換,指模擬信號轉換為數字信號的過程。舉個例子,例如下圖中的黑色線為一個模擬信號,可以通過特定的規則或者算法將其轉換為階梯狀的數字信號。

<br/>
  本節課將會以STM32F030F4P6的PA0這個IO口作為模擬信號的輸入口,然后把這個模擬信號轉換為數字信號。
<br/>
## **ADC 的 HCL API 設計**
ADC的HAL API比較簡單,只需要初始化和讀取數據的API即可,如圖所示。

<br/>
## **編寫代碼**
筆者在本節課配套的源代碼中新建了 hal\_adc.h 和 hal\_adc.c文件,如圖所示。

###
打開本節課配套的工程,筆者把hal\_adc.c以及必要的標準庫文件添加進工程了,如圖所示。

<br/>
hal_adc.h文件的代碼如下:
```
#ifndef __HAL_ADC_H__
#define __HAL_ADC_H__
/*
*初始化ADC
*/
void halAdcInit(void);
/*
*讀取ADC值
*/
unsigned int halAdcRead(void);
#endif /* __HAL_ADC_H__ */
```
<br/>
hal_adc.c文件代碼如下:
```
#include "hal_adc.h"
#include "stm32f0xx_adc.h"
/*
*初始化ADC
*/
void halAdcInit()
{
GPIO_InitTypeDef gpioCfg;//定義GPIO配置
ADC_InitTypeDef adcCfg;//定義ADC配置
/* 配置PA0 */
gpioCfg.GPIO_Pin = GPIO_Pin_0;//指定引腳為Pin 0
gpioCfg.GPIO_Mode = GPIO_Mode_AN;
gpioCfg.GPIO_PuPd = GPIO_PuPd_NOPULL;
/* 配置ADC */
adcCfg.ADC_Resolution = ADC_Resolution_12b;//ADC值的分辨率為12位
adcCfg.ADC_ContinuousConvMode = DISABLE;//不要進行持續的轉換。在halAdcRead函數每次讀取ADC值時,會重新啟動轉換過程
adcCfg.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
adcCfg.ADC_DataAlign = ADC_DataAlign_Right;
adcCfg.ADC_ScanDirection = ADC_ScanDirection_Backward;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
ADC_DeInit(ADC1);
GPIO_Init(GPIOA, &gpioCfg);//出初始化PA0
ADC_Init(ADC1, &adcCfg);//初始化ADC1
/* Convert the ADC1 Vref with 55.5 Cycles as sampling time */
ADC_ChannelConfig(ADC1, ADC_Channel_0, ADC_SampleTime_55_5Cycles);
ADC_GetCalibrationFactor(ADC1);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
ADC_StartOfConversion(ADC1);
}
/*
*讀取ADC值
*
*@return ADC值
*/
unsigned int halAdcRead()
{
ADC_StartOfConversion(ADC1);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
return ADC_GetConversionValue(ADC1);
}
```
<br/>
## **使用ADC HAL API**
編寫好ADC HAL API后,ADC的使用非常簡單。在配套工程的main.c文件中添加如下代碼:
###
```
/*
* 通過串口接收到信息時的回調函數
* @param byte - 接收到的數據
*/
static void onUartIRQ(unsigned char byte)
{}
int main(void)
{
halSystemInit();//系統初始化
halUartInit(115200);//串口通信初始化,并設置波特率為115200
halUartSetIRQCallback(onUartIRQ);//注冊串口通信回調函數,當通過串口接收到信息時自動調用此函數
halAdcInit();//ADC初始化
/* 每隔1秒讀取一次ADC值并通過串口發送出去 */
while (1)
{
halSystemDelayUs(1000 * 1000);//延時1000*1000微秒,即1秒
char debug[32];
sprintf(debug, "ADC=%d\n", halAdcRead());//讀取ADC值,并格式化保存到debug變量中
halUartWrite((uint8_t *)debug, strlen(debug));//把debug通過串口發送出去
}
}
```
###
上述代碼使用了格式化函數sprintf和字符串長度計算函數strlen,這兩個函數在以下頭文件中:
###
```
#include <stdio.h>
#include <string.h>
```
<br/>
**代碼測試**
1.編譯鏈接工程代碼,把生成的Hex文件燒錄到開發板中;
2.按如圖所示把開發板的撥碼開關的第1~4位打到右邊,第5、6位打到左邊,如圖所示。

###
3.然后打開串口助手,可以看到由PA0這個IO口輸入的模擬信號經過ADC后的值,如圖所示。

<br/>
**進一步解釋**
在按鍵相關章節曾經講解過,STM32F030F4P6的PA0是與一個按鍵鏈接的,如圖所示。

###
* 按鍵沒有被按下時,PA0輸入高電平(3.3v)
* 按鍵被按下后,PA0接地(GND),并且輸入低電平(0v)
也就是說,PA0輸入0到3.3v的模擬信號。main函數中的halAdcRead函數作用是讀取某個時刻的模擬信號值,并且這個值映射到[0,4095]這個取值范圍中后返回給mian函數。在ADC初始化函數halAdcInit中,把ADC分辨設置為12位,因此對應的ADC值取值范圍即為[0,4095]。讀者也可以把分辨率設置為8位,此時取值范圍就是[0,255]。
<br/>
**進一步擴展**
ADC初始化函數halAdcInit被配置為對由PA0輸入的模擬信號轉換為數字信號,讀者也可以更改其中的配置以更換到別的IO口。
<br/>
<br/>
## **商務合作**
如有以下需求,可掃碼添加管理員好友,注明“**商務合作**”
* 項目定制開發,技術范圍:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等;
* 入駐平臺,成為講師;
* 接項目賺外快;
* 善學坊官網:[www.sxf-iot.com](https://www.sxf-iot.com/)

(非商務合作**勿擾**,此處**非**技術支持)
- 課程介紹
- 配套資源下載
- 配套開發套件簡介
- 簡介
- 硬件組成 & 技術參數
- 電路原理圖 & PCB圖
- 撥碼開關使用說明
- 第一部分:無線通信 開發指南
- 1.1.1 NB-IoT:技術簡介
- 1.1.2 NB:CH34x USB轉串口驅動安裝
- 1.1.3 NB:AT 指令開發與測試
- 1.1.4 NB:基礎指令集簡介
- 1.1.5 NB:云端服務器
- 1.1.5.1 PuTTY 簡介與安裝
- 1.1.5.2 登錄云端服務器
- 1.1.6 NB:移遠官方工具簡介
- 1.1.7 NB:使用UDP協議與云端服務器通信
- 1.1.8 NB:使用TCP協議與云端服務器通信
- 1.1.9 NB:使用MQTT協議與云端服務器通信
- 進階課程
- 第二部分:STM32 開發指南
- 2.1 搭建開發環境
- 2.1.1 Keil MDK 簡介與安裝
- 2.1.2 STM32 Pack 簡介與安裝
- 2.1.3 CH34x 驅動簡介與安裝
- 2.1.4 其他開發工具
- 2.2 STM32 開發基礎
- 2.2.1 新建工程
- 2.2.2 實現第1個程序
- 2.2.3 Hex 文件燒錄詳解
- 2.3 移植官方標準工程模板
- 2.4 GPIO實驗——LED燈
- 2.5 系統延時應用
- 2.6 GPIO實驗——按鍵
- 2.7 GPIO中斷實驗——按鍵觸發
- 2.8 使用定時器TIM3
- 2.9 串口通信實驗
- 2.10 ADC 實驗
- 2.11 OLED顯示器實驗
- 2.12 SDK 設計思想
- 2.13 SDK 架構解析
- 2.14 多任務應用
- 2.15 輸入型任務:按鍵輸入
- 2.16 輸入型任務:串口接收
- 課外篇:項目實戰
- 基于STM32+NB-IoT的溫濕度采集
- 系統簡介
- 系統搭建
- 系統詳解
- 1.代碼編譯與架構說明
- 2.DHT11溫濕度傳感器
- 3. 數據通信任務說明
- 版權聲明與免責聲明