找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11070|回复: 18
收起左侧

STM32F103多路ADC采集程序

  [复制链接]
ID:300190 发表于 2018-4-1 01:42 | 显示全部楼层 |阅读模式
三路ADC采集stm32源程序:
  1. /**
  2.     @author                        Mei Jilin
  3.         @brief                    ADC1的配置完成3通道的数据采集
  4.     @attention
  5.        1 ----------- adc_config();                     //配置adc
  6.        2 ----------- adc_start();                      //启动adc,开始转换
  7.        3 ----------- get_ChannelValue(ADC_Channel_x);  //读取相应通道的adc值
  8. **/
  9. #include "stm32f10x.h"
  10. #include "adc.h"
  11. #define CH_NUM  3           //要使用的ADC通道数

  12. static uint16_t ad_value[CH_NUM]={0};
  13. /** @para none
  14.   * @ret  none
  15.   * @brief adc对应的gpio初始化
  16.   */
  17. void adc_gpio_init(void)
  18. {
  19.     GPIO_InitTypeDef gpio;
  20.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  21.     gpio.GPIO_Mode = GPIO_Mode_AIN;                         //配置为模拟输入
  22.     gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;   //ADC1 --channel0,1,2
  23.     gpio.GPIO_Speed = GPIO_Speed_50MHz;
  24.     GPIO_Init(GPIOA,&gpio);
  25. }
  26. /** @para none
  27.   * @ret  none
  28.   * @brief adc配置
  29.   */
  30. void adc_init(void)
  31. {
  32.     ADC_InitTypeDef adc;
  33.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  34.     RCC_ADCCLKConfig(RCC_PCLK2_Div6);                       //设置ad时钟为72/6=12M,ad最大时钟频率为14M
  35.    
  36.     ADC_DeInit(ADC1);
  37.     adc.ADC_Mode                = ADC_Mode_Independent;     //工作在独立模式
  38.     adc.ADC_ContinuousConvMode  = ENABLE;                   //连续转换模式
  39.     adc.ADC_DataAlign           = ADC_DataAlign_Right;      //数据右对齐
  40.     adc.ADC_ExternalTrigConv    = ADC_ExternalTrigConv_None;//不使用外部触发
  41.     adc.ADC_NbrOfChannel        = CH_NUM ;                       //转换3个通道
  42.     adc.ADC_ScanConvMode        = ENABLE;                   //连续转换模式
  43.     ADC_Init(ADC1,&adc);
  44.     //设定指定的ADC通道组,设置转化顺序和采样时间
  45.     ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
  46.     ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
  47.     ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);
  48.     //开启adc的DMA
  49.     ADC_DMACmd(ADC1,ENABLE);
  50.     //使能ADC1
  51.     ADC_Cmd(ADC1, ENABLE);
  52.     /* Enable ADC1 reset calibaration register */   
  53.     ADC_ResetCalibration(ADC1);          //重新校准
  54.     /* Check the end of ADC1 reset calibration register */
  55.     while(ADC_GetResetCalibrationStatus(ADC1));  //等待重新校准完成
  56.     /* Start ADC1 calibaration */
  57.     ADC_StartCalibration(ADC1);                //开始校准
  58.     /* Check the end of ADC1 calibration */
  59.     while(ADC_GetCalibrationStatus(ADC1));           //等待校准完成

  60. }
  61. /** @para none
  62.   * @ret  none
  63.   * @brief 配置dma
  64.   */
  65. void adc_dma_init()
  66. {
  67.     DMA_InitTypeDef dma;
  68.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  69.    
  70.     DMA_DeInit(DMA1_Channel1);
  71.     dma.DMA_PeripheralBaseAddr  = (u32)&(ADC1->DR);     //DMA对应的外设基地址
  72.     dma.DMA_MemoryBaseAddr      = (u32)&ad_value;       //内存存储基地址
  73.     dma.DMA_DIR                 = DMA_DIR_PeripheralSRC;//DMA的转换模式为SRC模式,由外设搬移到内存
  74.     dma.DMA_M2M                 = DMA_M2M_Disable;      //M2M模式禁用
  75.     dma.DMA_PeripheralDataSize  = DMA_PeripheralDataSize_HalfWord;//定义外设数据宽度为16位
  76.     dma.DMA_MemoryDataSize      = DMA_MemoryDataSize_HalfWord;  //DMA搬移数据尺寸,HalfWord就是为16位   
  77.     dma.DMA_BufferSize          = CH_NUM;                       //DMA缓存大小CH_NUM个
  78.     dma.DMA_MemoryInc           = DMA_MemoryInc_Enable;         //接收一次数据后,目标内存地址后移
  79.     dma.DMA_PeripheralInc       = DMA_PeripheralInc_Disable;    //接收一次数据后,设备地址禁止后移
  80.     dma.DMA_Mode                = DMA_Mode_Circular;            //转换模式,循环缓存模式。
  81.     dma.DMA_Priority            = DMA_Priority_High;            //DMA优先级高
  82.     DMA_Init(DMA1_Channel1,&dma);
  83. }
  84. /** @para none
  85.   * @ret  none
  86.   * @brief 完成adc配置
  87.   */
  88. void adc_config(void)
  89. {
  90.     adc_gpio_init();
  91.     adc_dma_init();
  92.     adc_init();
  93. }
  94. /** @para none
  95.   * @ret  none
  96.   * @brief 启动adc,开始转换
  97.   */
  98. void adc_start(void)
  99. {
  100.     /* Start ADC1 Software Conversion */
  101.     ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //连续转换开始,ADC通过DMA方式不断的更新RAM区。
  102.     DMA_Cmd(DMA1_Channel1,ENABLE);   
  103. }

  104. /** @para ADC_Channel --- (ADC_Channel0 ~ ADC_Channel17)
  105.   * @ret  ADC_Channel_x 的ADC值
  106.   */
  107. uint16_t get_ChannelVale(uint8_t ADC_Channel)
  108. {
  109.     uint16_t ret = 0;
  110.     switch(ADC_Channel)
  111.     {
  112.         case ADC_Channel_0:
  113.             ret = ad_value[0];
  114.             break;
  115.         case ADC_Channel_1:
  116.             ret = ad_value[1];
  117.             break;
  118.         case ADC_Channel_2:
  119.             ret = ad_value[2];
  120.             break;
  121.     }
  122.     return ret;
  123. }
复制代码

所有资料51hei提供下载:
ADC_test.rar (274.67 KB, 下载次数: 405)
回复

使用道具 举报

ID:280272 发表于 2019-1-25 22:20 | 显示全部楼层
不错不错!
回复

使用道具 举报

ID:437392 发表于 2019-2-20 22:26 | 显示全部楼层
十分不错.值得学习
回复

使用道具 举报

ID:523999 发表于 2019-4-28 21:25 | 显示全部楼层
您好,我想请问一下怎么能看到最后ret的值?
回复

使用道具 举报

ID:538806 发表于 2019-5-15 14:00 | 显示全部楼层
很好的教程
回复

使用道具 举报

ID:538806 发表于 2019-5-15 14:00 | 显示全部楼层
不错的教程,值得学习
回复

使用道具 举报

ID:316613 发表于 2019-6-4 14:22 | 显示全部楼层
怎么显示呢?
回复

使用道具 举报

ID:470746 发表于 2019-6-7 15:47 | 显示全部楼层
非常不错,值得借鉴
回复

使用道具 举报

ID:182969 发表于 2019-7-31 17:40 | 显示全部楼层
参考一下看看
回复

使用道具 举报

ID:401854 发表于 2019-8-13 19:25 | 显示全部楼层
程序不错不错
回复

使用道具 举报

ID:203051 发表于 2019-8-23 13:01 | 显示全部楼层

非常不错,值得借鉴
回复

使用道具 举报

ID:594340 发表于 2020-2-23 16:38 | 显示全部楼层
刚好用这个,楼主分享的完美,谢谢!
回复

使用道具 举报

ID:618469 发表于 2020-3-8 16:01 | 显示全部楼层
好东西,谢谢分享,下载下来看看
回复

使用道具 举报

ID:759611 发表于 2020-6-13 12:04 | 显示全部楼层
请问怎么看测到的值?
回复

使用道具 举报

ID:592257 发表于 2020-6-14 17:54 | 显示全部楼层
谢谢分享!谢谢,很有用的资料。
回复

使用道具 举报

ID:592257 发表于 2020-6-14 17:56 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:779688 发表于 2020-6-15 11:02 | 显示全部楼层
学习学习 谢谢分享
回复

使用道具 举报

ID:300190 发表于 2021-3-4 17:47 | 显示全部楼层
glimmerhyy 发表于 2019-4-28 21:25
您好,我想请问一下怎么能看到最后ret的值?

在需要取值的地方,定义一个变量,调用uint16_t get_ChannelVale(uint8_t ADC_Channel)这个函数,
如uint16 a;
a = get_ChannelVale(ADC_Channel_0);//a取到的值为通道0的AD值
回复

使用道具 举报

ID:137171 发表于 2022-9-15 21:38 来自手机 | 显示全部楼层
能十路同时采集吗?
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表