可用作開發學習使用
/*
*********************************************************************************************************
*
* 例程名稱 : Ex004-按鍵檢測例程(軟件濾波+FIFO)
* 例程版本 : V2.0
* ST固件庫版本 :V3.5.0
* 作 者 : armfly
* 發布日期 : 2011-10-16
*
* 開發環境 : KEIL的uVision V3.70、uVision V4.13、IAR的EWARM V5.30
*
* 修改記錄 :
* 2010-09-27 發布V1.0版本,固件庫為V3.1.2
* 2011-03-20 發布V1.1版本,固件庫為V3.4.0
* 2011-11-16 發布2.0版本,固件庫為V3.5.0,優化工程結構,打印信息改為中文
*
*********************************************************************************************************
*/
【1】例程介紹
這個例子演示如何使用ADC以及如何對ADC采樣值進行濾波處理。
Systick中斷服務程序每個1ms啟動并采集一次ADC值(PC4口線,可調電阻),并且對最近的20個樣本進行求平均值。
平均值保存在全局變量g_usAdcValue中。主程序定時讀取這個變量,并將值打印到串口1。
實際測試數據:
(1)程序在CPU內部Flash或者內部RAM執行時,樣本個數取20個,則采樣值非常穩定(1個字跳動)
(2)程序在外部SRAM運行時,由于3.3V電源波動,因此采樣值跳動較大。
請用串口線將開發板的COM1口連接到PC機的串口(或者USB串口),然后打開超級終端軟件(XP自帶的或者SecureCRT
軟件),可以在PC軟件界面看到例程的運行信息。
程序具有如下功能:
- 復位后打印例程基本信息
- 主程序定時將ADC值打印到串口1
- 調節開發板上的可調電阻,超級終端界面上會顯示一個不斷旋轉的字符 + 實時的ADC平均值
程序執行結果如下:
*************************************************************
* 例程名稱 : ADC采樣和濾波例程
* 例程版本 : 2.0
* 發布日期 : 2011-10-16
* 固件庫版本 : 3.5.0
*************************************************************
請調節開發板上的精密可調電阻,觀察ADC采樣值的變化
/ PC4口線ADC采樣值 = 2149 , 電壓 = 1731mV
對于Keil MDK,為了避免中文字符串告警,需要在C/C++編譯選項中增加 --diag_suppress=870 參數。
本程序支持在CPU內部Flash、CPU內部RAM和CPU外部RAM調試。在CPU內部RAM和CPU外部SRAM調試時,無需切換開發板上的
啟動模式撥碼開關。請將撥碼開關撥到Flash位置。
單片機源程序如下:
- /*
- *********************************************************************************************************
- *
- * 模塊名稱 : 主程序模塊。
- * 文件名稱 : main.c
- * 版 本 : V2.0
- * 說 明 : ADC采樣和濾波例程。
- * 修改記錄 :
- * 版本號 日期 作者 說明
- * v1.0 2011-08-27 armfly ST固件庫V3.5.0版本。
- * v2.0 2011-10-16 armfly 優化工程結構。
- *
- *********************************************************************************************************
- */
- #include "stm32f10x.h" /* 如果要用ST的固件庫,必須包含這個文件 */
- #include <stdio.h> /* 因為用到了printf函數,所以必須包含這個文件 */
- #include "bsp_usart.h" /* printf函數定向輸出到串口,所以必須包含這個文件 */
- #include "bsp_led.h" /* LED指示燈驅動模塊 */
- #include "bsp_button.h" /* 按鍵驅動模塊 */
- #include "bsp_timer.h" /* systick定時器模塊 */
- /* 定義例程名和例程發布日期 */
- #define EXAMPLE_NAME "ADC采樣和濾波例程"
- #define EXAMPLE_DATE "2011-10-16"
- #define DEMO_VER "2.0"
- #define SAMP_COUNT 20 /* 樣本個數,表示200ms內的采樣數據求平均值 */
- /*
- 實際測試數據:
- (1)程序在CPU內部Flash或者內部RAM執行時,樣本個數取20個,則采樣值非常穩定
- (2)程序在外部SRAM運行時,由于3.3V電源波動,因此采樣值跳動較大。
- */
- /* 僅允許本文件內調用的函數聲明 */
- static void InitBoard(void);
- static void PrintfLogo(void);
- static uint16_t GetADC(void);
- static void ADC_Configuration(void);
- uint16_t g_usAdcValue; /* ADC 采樣值的平均值 */
- /*
- *********************************************************************************************************
- * 函 數 名: main
- * 功能說明: c程序入口
- * 形 參:無
- * 返 回 值: 錯誤代碼(無需處理)
- *********************************************************************************************************
- */
- int main(void)
- {
- uint16_t usValue;
- /*
- 由于ST固件庫的啟動文件已經執行了CPU系統時鐘的初始化,所以不必再次重復配置系統時鐘。
- 啟動文件配置了CPU主時鐘頻率、內部Flash訪問速度和可選的外部SRAM FSMC初始化。
-
- 系統時鐘缺省配置為72MHz,如果需要更改,可以修改:
- \Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\system_stm32f10x.c
- 中配置系統時鐘的宏。
- */
-
- InitBoard(); /* 為了是main函數看起來更簡潔些,我們將硬件初始化的代碼封裝到這個函數 */
- PrintfLogo(); /* 打印例程Logo到串口1 */
- printf("請調節開發板上的精密可調電阻,觀察ADC采樣值的變化\r\n");
- ADC_Configuration(); /* 配置PC4 為ADC1_IN14 */
- bsp_StartTimer(1, 300); /* 定時器0周期 200毫秒 */
- /* 進入主程序循環體 */
- while (1)
- {
- CPU_IDLE(); /* 這個宏在bsp_timer.h 中定義,目前定義為空。用戶可以修改這個宏實現CPU休眠和喂狗 */
- if (bsp_CheckTimer(1)) /* 定時到 */
- {
- bsp_StartTimer(1, 300); /* 啟動下個定時周期 */
- usValue = GetADC();
- /* 注意: 末尾只有 \r回車, 沒有\n換行,可以使PC超級終端界面穩定在1行顯示 */
- {
- /* 超級終端界面上會顯示一個不斷旋轉的字符
- 增加這個功能,是為了避免程序死機的假象,因為ADC采樣值很穩定
- */
- static uint8_t pos = 0;
- if (pos == 0)
- printf("|");
- else if (pos == 1)
- printf("/");
- else if (pos == 2)
- printf("-");
- else if (pos == 3)
- printf("\\"); /* 注意:這個特殊字符需要轉義 */
- if (++pos >= 4)
- {
- pos = 0;
- }
- printf(" PC4口線ADC采樣值 = %5d , 電壓 = %4dmV\r",
- usValue, ((uint32_t)usValue * 3300) / 4095);
- }
- }
- /* 這個地方可以插入 GetKey(), 擴充對按鍵的響應代碼 */
- }
- }
- /*
- *********************************************************************************************************
- * 函 數 名: ADC_Configuration
- * 功能說明: 配置ADC, PC4模式
- * 形 參:無
- * 返 回 值: 無
- *********************************************************************************************************
- */
- static void ADC_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- ADC_InitTypeDef ADC_InitStructure;
- __IO uint16_t ADCConvertedValue;
- /* 使能 ADC1 and GPIOC clock */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
- /* 配置PC4為模擬輸入(ADC Channel14) */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- /* 配置ADC1, 不用DMA, 用軟件觸發 */
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
- ADC_InitStructure.ADC_ScanConvMode = ENABLE;
- ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_NbrOfChannel = 1;
- ADC_Init(ADC1, &ADC_InitStructure);
- /* 配置ADC1 規則通道14 channel14 configuration */
- ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5);
- /* 使能ADC1 DMA功能 */
- ADC_DMACmd(ADC1, ENABLE);
- /* 使能 ADC1 */
- ADC_Cmd(ADC1, ENABLE);
- /* 使能ADC1 復位校準寄存器 */
- ADC_ResetCalibration(ADC1);
- /* 檢查ADC1的復位寄存器 */
- while(ADC_GetResetCalibrationStatus(ADC1));
- /* 啟動ADC1校準 */
- ADC_StartCalibration(ADC1);
- /* 檢查校準是否結束 */
- while(ADC_GetCalibrationStatus(ADC1));
- /* 軟件啟動ADC轉換 */
- ADC_SoftwareStartConvCmd(ADC1, ENABLE);
- }
- /*
- *********************************************************************************************************
- * 函 數 名: AdcPro
- * 功能說明: ADC采樣處理,插入1ms systick中斷進行調用
- * 形 參:無
- * 返 回 值: 無
- *********************************************************************************************************
- */
- void AdcPro(void)
- {
- static uint16_t buf[SAMP_COUNT];
- static uint8_t write;
- uint32_t sum;
- uint8_t i;
- buf[write] = ADC_GetConversionValue(ADC1);
- if (++write >= SAMP_COUNT)
- {
- write = 0;
- }
- /* 下面這段代碼采用求平均值的方法進行濾波
- 也可以改善下,選擇去掉最大和最下2個值,使數據更加精確
- */
- sum = 0;
- for (i = 0; i < SAMP_COUNT; i++)
- {
- sum += buf[i];
- }
- g_usAdcValue = sum / SAMP_COUNT; /* ADC采樣值由若干次采樣值平均 */
- ADC_SoftwareStartConvCmd(ADC1, ENABLE); /* 軟件啟動下次ADC轉換 */
- }
- /*
- *********************************************************************************************************
- * 函 數 名: GetADC
- * 功能說明: 讀取ADC采樣的平均值
- * 形 參:無
- * 返 回 值: 無
- *********************************************************************************************************
- */
- static uint16_t GetADC(void)
- {
- uint16_t ret;
- /* 因為 g_AdcValue 變量在systick中斷中改寫,為了避免主程序讀變量時被中斷程序打亂導致數據錯誤,因此需要
- 關閉中斷進行保護 */
- /* 進行臨界區保護,關閉中斷 */
- __set_PRIMASK(1); /* 關中斷 */
- ret = g_usAdcValue;
- __set_PRIMASK(0); /* 開中斷 */
- return ret;
- }
- /*
- *********************************************************************************************************
- * 函 數 名: InitBoard
- * 功能說明: 初始化硬件設備
- * 形 參:無
- * 返 回 值: 無
- *********************************************************************************************************
- */
- static void InitBoard(void)
- {
- /* 配置串口,用于printf輸出 */
- bsp_InitUart();
-
- /* 配置LED指示燈GPIO */
- bsp_InitLed();
- /* 配置按鍵GPIO, 必須在bsp_InitTimer之前調用 */
- bsp_InitButton();
- /* 初始化systick定時器,并啟動定時中斷 */
- bsp_InitTimer();
- }
- /*
- *********************************************************************************************************
- * 函 數 名: PrintfLogo
- * 功能說明: 打印例程名稱和例程發布日期, 接上串口線后,打開PC機的超級終端軟件可以觀察結果
- * 形 參:無
- * 返 回 值: 無
- *********************************************************************************************************
- */
- static void PrintfLogo(void)
- {
- printf("*************************************************************\n\r");
- printf("* 例程名稱 : %s\r\n", EXAMPLE_NAME); /* 打印例程名稱 */
- printf("* 例程版本 : %s\r\n", DEMO_VER); /* 打印例程版本 */
- printf("* 發布日期 : %s\r\n", EXAMPLE_DATE); /* 打印例程日期 */
- /* 打印ST固件庫版本,這3個定義宏在stm32f10x.h文件中 */
- printf("* 固件庫版本 : %d.%d.%d\r\n", __STM32F10X_STDPERIPH_VERSION_MAIN,
- __STM32F10X_STDPERIPH_VERSION_SUB1,__STM32F10X_STDPERIPH_VERSION_SUB2);
- printf("* \n\r"); /* 打印一行空格 */
- printf("* QQ : 1295744630 \r\n");
- printf("* Email : armfly@qq.com \r\n");
- printf("* Copyright www.armfly.com 安富萊電子\r\n");
- printf("*************************************************************\n\r");
- }
復制代碼
所有資料51hei提供下載:
ADC采樣和濾波例程.rar
(472.09 KB, 下載次數: 117)
2018-9-17 11:03 上傳
點擊文件名下載附件
AD采樣濾波 下載積分: 黑幣 -5
|