我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 1196|回复: 8

[技术文章] 基于STM32F103ZET6芯片的采样+滤波程序源码

[复制链接]

该用户从未签到

19

主题

86

回帖

0

积分

二级逆天

积分
0

终身成就奖

发表于 2020-3-2 00:37:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×
例程介绍        

    这个例子演示如何使用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 参数。   


单片机源程序如下:

  1. /*
  2. *********************************************************************************************************
  3. *                                          
  4. *        模块名称 : 主程序模块。
  5. *        文件名称 : main.c
  6. *        版    本 : V2.0
  7. *        说    明 : ADC采样和滤波例程。
  8. *        修改记录 :
  9. *                版本号  日期       作者    说明
  10. *                v1.0    2011-08-27 armfly  ST固件库V3.5.0版本。
  11. *                v2.0    2011-10-16 armfly  优化工程结构。
  12. *
  13. *********************************************************************************************************
  14. */
  15. #include "stm32f10x.h"                /* 如果要用ST的固件库,必须包含这个文件 */
  16. #include <stdio.h>                        /* 因为用到了printf函数,所以必须包含这个文件 */
  17. #include "bsp_usart.h"                /* printf函数定向输出到串口,所以必须包含这个文件 */
  18. #include "bsp_led.h"                /* LED指示灯驱动模块 */
  19. #include "bsp_button.h"                /* 按键驱动模块 */
  20. #include "bsp_timer.h"                /* systick定时器模块 */
  21. /* 定义例程名和例程发布日期 */                                       
  22. #define EXAMPLE_NAME        "ADC采样和滤波例程"
  23. #define EXAMPLE_DATE        "2011-10-16"
  24. #define DEMO_VER                "2.0"
  25. #define SAMP_COUNT        20                /* 样本个数,表示200ms内的采样数据求平均值 */
  26. /*
  27.         实际测试数据:
  28.         (1)程序在CPU内部Flash或者内部RAM执行时,样本个数取20个,则采样值非常稳定
  29.         (2)程序在外部SRAM运行时,由于3.3V电源波动,因此采样值跳动较大。
  30. */
  31. /* 仅允许本文件内调用的函数声明 */
  32. static void InitBoard(void);
  33. static void PrintfLogo(void);
  34. static uint16_t GetADC(void);
  35. static void ADC_Configuration(void);
  36. uint16_t g_usAdcValue;        /* ADC 采样值的平均值 */
  37. /*
  38. *********************************************************************************************************
  39. *        函 数 名: main
  40. *        功能说明: c程序入口
  41. *        形    参:无
  42. *        返 回 值: 错误代码(无需处理)
  43. *********************************************************************************************************
  44. */
  45. int main(void)
  46. {
  47.         uint16_t usValue;
  48.         /*
  49.                 由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
  50.                 启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
  51.                
  52.                 系统时钟缺省配置为72MHz,如果需要更改,可以修改:
  53.                 \Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\system_stm32f10x.c
  54.                 中配置系统时钟的宏。
  55.         */
  56.       
  57.         InitBoard();        /* 为了是main函数看起来更简洁些,我们将硬件初始化的代码封装到这个函数 */
  58.         PrintfLogo();        /* 打印例程Logo到串口1 */      
  59.         printf("请调节开发板上的精密可调电阻,观察ADC采样值的变化\r\n");
  60.         ADC_Configuration();        /* 配置PC4 为ADC1_IN14 */
  61.         bsp_StartTimer(1, 300);        /* 定时器0周期 200毫秒 */
  62.         /* 进入主程序循环体 */
  63.         while (1)
  64.         {
  65.                 CPU_IDLE();          /* 这个宏在bsp_timer.h 中定义,目前定义为空。用户可以修改这个宏实现CPU休眠和喂狗 */
  66.                 if (bsp_CheckTimer(1))        /* 定时到 */
  67.                 {
  68.                         bsp_StartTimer(1, 300);        /* 启动下个定时周期 */
  69.                         usValue = GetADC();
  70.                         /* 注意: 末尾只有 \r回车, 没有\n换行,可以使PC超级终端界面稳定在1行显示 */
  71.                         {
  72.                                 /* 超级终端界面上会显示一个不断旋转的字符
  73.                                 增加这个功能,是为了避免程序死机的假象,因为ADC采样值很稳定
  74.                                 */
  75.                                 static uint8_t pos = 0;
  76.                                 if (pos == 0)
  77.                                         printf("|");
  78.                                 else if (pos == 1)
  79.                                         printf("/");
  80.                                 else if (pos == 2)
  81.                                         printf("-");
  82.                                 else if (pos == 3)
  83.                                         printf("\\");                /* 注意:这个特殊字符需要转义 */
  84.                                 if (++pos >= 4)
  85.                                 {
  86.                                         pos = 0;
  87.                                 }
  88.                                 printf(" PC4口线ADC采样值 = %5d , 电压 = %4dmV\r",
  89.                                         usValue, ((uint32_t)usValue * 3300) / 4095);
  90.                         }
  91.                 }
  92.                 /* 这个地方可以插入 GetKey(), 扩充对按键的响应代码 */
  93.         }
  94. }
  95. /*
  96. *********************************************************************************************************
  97. *        函 数 名: ADC_Configuration
  98. *        功能说明: 配置ADC, PC4模式
  99. *        形    参:无
  100. *        返 回 值: 无
  101. *********************************************************************************************************
  102. */
  103. static void ADC_Configuration(void)
  104. {
  105.         GPIO_InitTypeDef GPIO_InitStructure;
  106.         ADC_InitTypeDef ADC_InitStructure;
  107.         __IO uint16_t ADCConvertedValue;
  108.     /* 使能 ADC1 and GPIOC clock */
  109.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
  110.         /* 配置PC4为模拟输入(ADC Channel14) */
  111.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  112.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  113.         GPIO_Init(GPIOC, &GPIO_InitStructure);
  114.         /* 配置ADC1, 不用DMA, 用软件触发 */
  115.         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  116.         ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  117.         ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  118.         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  119.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  120.         ADC_InitStructure.ADC_NbrOfChannel = 1;
  121.         ADC_Init(ADC1, &ADC_InitStructure);
  122.         /* 配置ADC1 规则通道14 channel14 configuration */
  123.         ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5);
  124.         /* 使能ADC1 DMA功能 */
  125.         ADC_DMACmd(ADC1, ENABLE);
  126.         /* 使能 ADC1 */
  127.         ADC_Cmd(ADC1, ENABLE);
  128.         /* 使能ADC1 复位校准寄存器 */
  129.         ADC_ResetCalibration(ADC1);
  130.         /* 检查ADC1的复位寄存器 */
  131.         while(ADC_GetResetCalibrationStatus(ADC1));
  132.         /* 启动ADC1校准 */
  133.         ADC_StartCalibration(ADC1);
  134.         /* 检查校准是否结束 */
  135.         while(ADC_GetCalibrationStatus(ADC1));
  136.         /* 软件启动ADC转换 */
  137.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  138. }
  139. /*
  140. *********************************************************************************************************
  141. *        函 数 名: AdcPro
  142. *        功能说明: ADC采样处理,插入1ms systick中断进行调用
  143. *        形    参:无
  144. *        返 回 值: 无
  145. *********************************************************************************************************
  146. */
  147. void AdcPro(void)
  148. {
  149.         static uint16_t buf[SAMP_COUNT];
  150.         static uint8_t write;
  151.         uint32_t sum;
  152.         uint8_t i;
  153.         buf[write] = ADC_GetConversionValue(ADC1);
  154.         if (++write >= SAMP_COUNT)
  155.         {
  156.                 write = 0;
  157.         }
  158.         /* 下面这段代码采用求平均值的方法进行滤波
  159.                 也可以改善下,选择去掉最大和最下2个值,使数据更加精确
  160.         */
  161.         sum = 0;
  162.         for (i = 0; i < SAMP_COUNT; i++)
  163.         {
  164.                 sum += buf[i];
  165.         }
  166.         g_usAdcValue = sum / SAMP_COUNT;        /* ADC采样值由若干次采样值平均 */
  167.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);        /* 软件启动下次ADC转换 */
  168. }
  169. /*
  170. *********************************************************************************************************
  171. *        函 数 名: GetADC
  172. *        功能说明: 读取ADC采样的平均值
  173. *        形    参:无
  174. *        返 回 值: 无
  175. *********************************************************************************************************
  176. */
  177. static uint16_t GetADC(void)
  178. {
  179.         uint16_t ret;
  180.         /* 因为        g_AdcValue 变量在systick中断中改写,为了避免主程序读变量时被中断程序打乱导致数据错误,因此需要
  181.         关闭中断进行保护 */
  182.         /* 进行临界区保护,关闭中断 */
  183.         __set_PRIMASK(1);  /* 关中断 */
  184.         ret = g_usAdcValue;
  185.         __set_PRIMASK(0);  /* 开中断 */
  186.         return ret;
  187. }
  188. /*
  189. *********************************************************************************************************
  190. *        函 数 名: InitBoard
  191. *        功能说明: 初始化硬件设备
  192. *        形    参:无
  193. *        返 回 值: 无
  194. *********************************************************************************************************
  195. */
  196. static void InitBoard(void)
  197. {      
  198.         /* 配置串口,用于printf输出 */
  199.         bsp_InitUart();
  200.       
  201.         /* 配置LED指示灯GPIO */
  202.         bsp_InitLed();
  203.         /* 配置按键GPIO, 必须在bsp_InitTimer之前调用 */
  204.         bsp_InitButton();
  205.         /* 初始化systick定时器,并启动定时中断 */
  206.         bsp_InitTimer();
  207. }
  208. /*
  209. *********************************************************************************************************
  210. *        函 数 名: PrintfLogo
  211. *        功能说明: 打印例程名称和例程发布日期, 接上串口线后,打开PC机的超级终端软件可以观察结果
  212. *        形    参:无
  213. *        返 回 值: 无
  214. *********************************************************************************************************
  215. */
  216. static void PrintfLogo(void)
  217. {
  218.         printf("*************************************************************\n\r");
  219.         printf("* 例程名称   : %s\r\n", EXAMPLE_NAME);        /* 打印例程名称 */
  220.         printf("* 例程版本   : %s\r\n", DEMO_VER);                /* 打印例程版本 */
  221.         printf("* 发布日期   : %s\r\n", EXAMPLE_DATE);        /* 打印例程日期 */
  222.         /* 打印ST固件库版本,这3个定义宏在stm32f10x.h文件中 */
  223.         printf("* 固件库版本 : %d.%d.%d\r\n", __STM32F10X_STDPERIPH_VERSION_MAIN,
  224.                         __STM32F10X_STDPERIPH_VERSION_SUB1,__STM32F10X_STDPERIPH_VERSION_SUB2);               
  225.         printf("* \n\r");        /* 打印一行空格 */
  226.         printf("* QQ    : 1295744630 \r\n");
  227.         printf("* Email : armfly@qq.com \r\n");
  228.         printf("* Copyright www.armfly.com 安富莱电子\r\n");
  229.         printf("*************************************************************\n\r");
  230. }
复制代码
ADC采样和滤波例程.rar (473 KB, 下载次数: 6)
回复

使用道具 举报

  • TA的每日心情
    难过
    2024-10-13 14:26
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    38

    主题

    5068

    回帖

    2697

    积分

    二级逆天

    积分
    2697

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    发表于 2020-3-2 09:00:20 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-6-14 16:03
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    0

    主题

    1万

    回帖

    7618

    积分

    二级逆天

    积分
    7618

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    QQ
    发表于 2020-3-2 15:39:30 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-6-14 16:03
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    0

    主题

    1万

    回帖

    7618

    积分

    二级逆天

    积分
    7618

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    QQ
    发表于 2020-3-2 15:40:03 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    196

    主题

    3559

    回帖

    2004

    积分

    二级逆天

    积分
    2004

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2021-4-3 23:33:00 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    196

    主题

    3559

    回帖

    2004

    积分

    二级逆天

    积分
    2004

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2021-4-3 23:33:11 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    196

    主题

    3559

    回帖

    2004

    积分

    二级逆天

    积分
    2004

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2021-4-3 23:33:22 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    30

    主题

    1427

    回帖

    1854

    积分

    二级逆天

    积分
    1854

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2023-2-7 08:32:33 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    昨天 10:15
  • 签到天数: 112 天

    [LV.6]常住居民II

    0

    主题

    1467

    回帖

    3286

    积分

    二级逆天

    积分
    3286

    社区居民终身成就奖特殊贡献奖原创先锋奖

    QQ
    发表于 2023-2-7 08:33:53 | 显示全部楼层
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    每日签到,有金币领取。


    Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

    本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

    ( 闽ICP备2024076463号-1 ) 论坛技术支持QQ群171867948 ,论坛问题,充值问题请联系QQ1308068381

    平平安安
    TOP
    快速回复 返回顶部 返回列表