你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

怎样实现ADC连续转换

[复制链接]
狂奔的蜗牛233 提问时间:2017-2-16 11:21 /
悬赏12ST金币未解决
我现在想要用战舰板子(核心是STM32F103ZET6)实现ADC连续转换以及串口输出。比如,输入模拟正弦信号,通过ADC转换后由串口输出,通过串口调试助手在电脑上显示数据,应该怎样做?要有比较详细的步骤,最好有代码。谢各位指点!

收藏 1 评论8 发布时间:2017-2-16 11:21

举报

8个回答
asmhai 回答时间:2017-2-16 22:03:55
有例程的,在网上找找,可以满足你的要求的。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

epochal 回答时间:2017-2-17 06:46:58
网上都可以找到!
zhao.zhao 回答时间:2017-2-17 10:05:48
void ADC_Configuration(void)
{
    ADC_InitTypeDef ADC_InitStructure;        //ADC³õʼ»¯½á¹¹ÌåÉùÃ÷
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div8);         //72M/8=9M,ADC×î´óʱ¼ä²»Äܳ¬¹ý14M

    ADC_InitStructure.ADC_Mode               = ADC_Mode_Independent;  //ADC¹¤×÷ģʽ:ADC1ºÍADC2¹¤×÷ÔÚ¶ÀÁ¢µÄת»»Ä£Ê½
    ADC_InitStructure.ADC_ScanConvMode       = ENABLE;    //Ä£Êýת»»¹¤×÷ÔÚɨÃèģʽ
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//DISABLE;   //Ä£Êýת»»¹¤×÷ÔÚÁ¬Ðøת»»Ä£Ê½        // ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConv   = ADC_ExternalTrigConv_None;        //Èí¼þ´¥·¢ //Íⲿ´¥·¢×ª»»¹Ø±Õ
    ADC_InitStructure.ADC_DataAlign          = ADC_DataAlign_Right;   //¶ÔÆ뷽ʽ,ADCΪ12룬ÓÒ¶ÔÆ뷽ʽ
    ADC_InitStructure.ADC_NbrOfChannel       = ADC_MUX_MAX;   //˳Ðò½øÐйæÔòת»»µÄADCͨµÀµÄÊýÄ¿,¿ªÆôͨµÀÊý£¬¼´ADC_MUX_MAX
    ADC_Init(ADC1, &ADC_InitStructure);

    //ÉèÖÃÖ¸¶¨ADCµÄ¹æÔò×éͨµÀ£¬ÉèÖÃËüÃǵÄת»¯Ë³ÐòºÍ²ÉÑùʱ¼ä ADC1,ADCͨµÀx,¹æÔò²ÉÑù˳ÐòֵΪy,²ÉÑùʱ¼äΪ239ÖÜÆÚ   
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);  // STM32.PIN30#.PA1,ADC1_IN1,  RW1, tim3
    ADC_RegularChannelConfig(ADC1, ADC_Channel_13,2, ADC_SampleTime_239Cycles5);  // STM32.PIN29#.PC3,ADC1_IN13, RW2, tim4
    ADC_RegularChannelConfig(ADC1, ADC_Channel_12,3, ADC_SampleTime_239Cycles5);  // STM32.PIN28#.PC2,ADC1_IN12, RW3, tim5
    ADC_RegularChannelConfig(ADC1, ADC_Channel_11,4, ADC_SampleTime_239Cycles5);  // STM32.PIN27#.PC1,ADC1_IN11, RW4, tim6
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10,5, ADC_SampleTime_239Cycles5);  // STM32.PIN26#.PC0,ADC1_IN10, RW5, tim7

    ADC_DMACmd(ADC1, ENABLE); // ¿ªÆôADCµÄDMAÖ§³Ö£¨ÒªÊµÏÖDMA¹¦ÄÜ£¬»¹Ðè¶ÀÁ¢ÅäÖÃDMAͨµÀµÈ²ÎÊý
    ADC_Cmd(ADC1, ENABLE);    //¿ªÆôADC1, ʹÄÜÖ¸¶¨µÄADC1
  
    ADC_ResetCalibration(ADC1);                // ¸´Î»Ö¸¶¨µÄADC1µÄУ׼¼Ä´æÆ÷,ÖØÐÂУ׼
    while(ADC_GetResetCalibrationStatus(ADC1));// µÈ´ýÖØÐÂУ׼Íê³É
    ADC_StartCalibration(ADC1);                // ¿ªÊ¼Ö¸¶¨ADC1µÄУ׼״̬,¿ªÊ¼Ð£×¼
    while(ADC_GetCalibrationStatus(ADC1));     // µÈ´ýУ׼Íê³É
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);    //Á¬Ðøת»»¿ªÊ¼£¬ADCͨ¹ýDMA·½Ê½²»¶ÏµÄ¸üÐÂRAMÇø¡£
}

extern  u16   ADCConvertedValue[N_SAMPLE_PER10MS * ADC_MUX_MAX];
void DMA_Configuration()   
{
    DMA_InitTypeDef DMA_InitStructure;        
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    DMA_DeInit(DMA1_Channel1);                                                 // ¿ªÆôDMA1µÄµÚһͨµÀ
    DMA_InitStructure.DMA_PeripheralBaseAddr  = ADC1_DR_ADDRESS;                    // DMA¶ÔÓ¦µÄÍâÉè»ùµØÖ·
    DMA_InitStructure.DMA_MemoryBaseAddr      = (uint32_t)&ADCConvertedValue;  // ÄÚ´æ´æ´¢»ùµØÖ·
    DMA_InitStructure.DMA_DIR                 = DMA_DIR_PeripheralSRC;         // DMAµÄת»»Ä£Ê½ÎªSRCģʽ£¬ÓÉÍâÉè°áÒƵ½ÄÚ´æ
    DMA_InitStructure.DMA_BufferSize          = N_SAMPLE_PER10MS*ADC_MUX_MAX;  // DMA»º´æ´óС,ADC_MUX_MAX
    //Èç´ËÉèÖã¬Ê¹ÐòÁÐ1½á¹û·ÅÔÚADCConvertedValue[0]£¬ÐòÁÐ2½á¹û·ÅÔÚADCConvertedValue[1]

    DMA_InitStructure.DMA_PeripheralInc       = DMA_PeripheralInc_Disable;    // ½ÓÊÕÒ»´ÎÊý¾Ýºó£¬É豸µØÖ·½ûÖ¹ºóÒÆ
    DMA_InitStructure.DMA_MemoryInc           = DMA_MemoryInc_Enable;         // ½ÓÊÕÒ»´ÎÊý¾Ýºó£¬Ä¿±êÄÚ´æµØÖ·ºóÒÆ
    DMA_InitStructure.DMA_PeripheralDataSize  = DMA_PeripheralDataSize_HalfWord;  //¶¨ÒåÍâÉèÊý¾Ý¿í¶ÈΪ16λ
    DMA_InitStructure.DMA_MemoryDataSize      = DMA_MemoryDataSize_HalfWord;  // DMA°áÒÆÊý¾Ý³ß´ç£¬HalfWord¾ÍÊÇΪ16λ
    DMA_InitStructure.DMA_Mode                = DMA_Mode_Circular;    //ת»»Ä£Ê½£¬Ñ­»·Ä£Ê½¿ªÆô£¬BufferдÂúºó£¬×Ô¶¯»Øµ½³õʼµØÖ·¿ªÊ¼´«Êä
    DMA_InitStructure.DMA_Priority            = DMA_Priority_High;    //DMAÓÅÏȼ¶¸ß
    DMA_InitStructure.DMA_M2M                 = DMA_M2M_Disable;      //M2Mģʽ½ûÓÃ
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);         

    DMA_Cmd(DMA1_Channel1, ENABLE);
}

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

zhao.zhao 回答时间:2017-2-17 10:07:32
再发一个,带中文说明的
#include  "adc.h"


void ADC_GPIO_Configuration(void)   //ADC配置函数
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 ;     //管脚0,1,2,3
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AIN;//输入模式
    GPIO_Init(GPIOC, &GPIO_InitStructure);        //PC0(ADC1_IN10),PC1(ADC1_IN11),PC2(ADC1_IN12),PC3(ADC1_IN13)
   
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_1 ;  //管脚1
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AIN;//输入模式
    GPIO_Init(GPIOA, &GPIO_InitStructure);        // PA1(ADC1_IN1)
}

void ADC_Configuration(void)
{
    ADC_InitTypeDef ADC_InitStructure;        //ADC初始化结构体声明
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div8);         //72M/8=9M,ADC最大时间不能超过14M

    ADC_InitStructure.ADC_Mode               = ADC_Mode_Independent;  //ADC工作模式:ADC1和ADC2工作在独立的转换模式
    ADC_InitStructure.ADC_ScanConvMode       = ENABLE;    //模数转换工作在扫描模式
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//DISABLE;   //模数转换工作在连续转换模式        // ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConv   = ADC_ExternalTrigConv_None;        //软件触发 //外部触发转换关闭
    ADC_InitStructure.ADC_DataAlign          = ADC_DataAlign_Right;   //对齐方式,ADC为12位,右对齐方式
    ADC_InitStructure.ADC_NbrOfChannel       = ADC_MUX_MAX;   //顺序进行规则转换的ADC通道的数目,开启通道数,即ADC_MUX_MAX
    ADC_Init(ADC1, &ADC_InitStructure);

    //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间 ADC1,ADC通道x,规则采样顺序值为y,采样时间为239周期   
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);  // STM32.PIN30#.PA1,ADC1_IN1,  RW1, tim3
    ADC_RegularChannelConfig(ADC1, ADC_Channel_13,2, ADC_SampleTime_239Cycles5);  // STM32.PIN29#.PC3,ADC1_IN13, RW2, tim4
    ADC_RegularChannelConfig(ADC1, ADC_Channel_12,3, ADC_SampleTime_239Cycles5);  // STM32.PIN28#.PC2,ADC1_IN12, RW3, tim5
    ADC_RegularChannelConfig(ADC1, ADC_Channel_11,4, ADC_SampleTime_239Cycles5);  // STM32.PIN27#.PC1,ADC1_IN11, RW4, tim6
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10,5, ADC_SampleTime_239Cycles5);  // STM32.PIN26#.PC0,ADC1_IN10, RW5, tim7

    ADC_DMACmd(ADC1, ENABLE); // 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数
    ADC_Cmd(ADC1, ENABLE);    //开启ADC1, 使能指定的ADC1
  
    ADC_ResetCalibration(ADC1);                // 复位指定的ADC1的校准寄存器,重新校准
    while(ADC_GetResetCalibrationStatus(ADC1));// 等待重新校准完成
    ADC_StartCalibration(ADC1);                // 开始指定ADC1的校准状态,开始校准
    while(ADC_GetCalibrationStatus(ADC1));     // 等待校准完成
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);    //连续转换开始,ADC通过DMA方式不断的更新RAM区。
}

extern  u16   ADCConvertedValue[N_SAMPLE_PER10MS * ADC_MUX_MAX];
void DMA_Configuration()   
{
    DMA_InitTypeDef DMA_InitStructure;        
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    DMA_DeInit(DMA1_Channel1);                                                 // 开启DMA1的第一通道
    DMA_InitStructure.DMA_PeripheralBaseAddr  = ADC1_DR_ADDRESS;                    // DMA对应的外设基地址
    DMA_InitStructure.DMA_MemoryBaseAddr      = (uint32_t)&ADCConvertedValue;  // 内存存储基地址
    DMA_InitStructure.DMA_DIR                 = DMA_DIR_PeripheralSRC;         // DMA的转换模式为SRC模式,由外设搬移到内存
    DMA_InitStructure.DMA_BufferSize          = N_SAMPLE_PER10MS*ADC_MUX_MAX;  // DMA缓存大小,ADC_MUX_MAX
    //如此设置,使序列1结果放在ADCConvertedValue[0],序列2结果放在ADCConvertedValue[1]

    DMA_InitStructure.DMA_PeripheralInc       = DMA_PeripheralInc_Disable;    // 接收一次数据后,设备地址禁止后移
    DMA_InitStructure.DMA_MemoryInc           = DMA_MemoryInc_Enable;         // 接收一次数据后,目标内存地址后移
    DMA_InitStructure.DMA_PeripheralDataSize  = DMA_PeripheralDataSize_HalfWord;  //定义外设数据宽度为16位
    DMA_InitStructure.DMA_MemoryDataSize      = DMA_MemoryDataSize_HalfWord;  // DMA搬移数据尺寸,HalfWord就是为16位
    DMA_InitStructure.DMA_Mode                = DMA_Mode_Circular;    //转换模式,循环模式开启,Buffer写满后,自动回到初始地址开始传输
    DMA_InitStructure.DMA_Priority            = DMA_Priority_High;    //DMA优先级高
    DMA_InitStructure.DMA_M2M                 = DMA_M2M_Disable;      //M2M模式禁用
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);         

    DMA_Cmd(DMA1_Channel1, ENABLE);
}
zhao.zhao 回答时间:2017-2-17 10:07:48
再发一个,带中文说明的
#include  "adc.h"


void ADC_GPIO_Configuration(void)   //ADC配置函数
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 ;     //管脚0,1,2,3
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AIN;//输入模式
    GPIO_Init(GPIOC, &GPIO_InitStructure);        //PC0(ADC1_IN10),PC1(ADC1_IN11),PC2(ADC1_IN12),PC3(ADC1_IN13)
   
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_1 ;  //管脚1
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AIN;//输入模式
    GPIO_Init(GPIOA, &GPIO_InitStructure);        // PA1(ADC1_IN1)
}

void ADC_Configuration(void)
{
    ADC_InitTypeDef ADC_InitStructure;        //ADC初始化结构体声明
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div8);         //72M/8=9M,ADC最大时间不能超过14M

    ADC_InitStructure.ADC_Mode               = ADC_Mode_Independent;  //ADC工作模式:ADC1和ADC2工作在独立的转换模式
    ADC_InitStructure.ADC_ScanConvMode       = ENABLE;    //模数转换工作在扫描模式
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//DISABLE;   //模数转换工作在连续转换模式        // ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConv   = ADC_ExternalTrigConv_None;        //软件触发 //外部触发转换关闭
    ADC_InitStructure.ADC_DataAlign          = ADC_DataAlign_Right;   //对齐方式,ADC为12位,右对齐方式
    ADC_InitStructure.ADC_NbrOfChannel       = ADC_MUX_MAX;   //顺序进行规则转换的ADC通道的数目,开启通道数,即ADC_MUX_MAX
    ADC_Init(ADC1, &ADC_InitStructure);

    //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间 ADC1,ADC通道x,规则采样顺序值为y,采样时间为239周期   
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);  // STM32.PIN30#.PA1,ADC1_IN1,  RW1, tim3
    ADC_RegularChannelConfig(ADC1, ADC_Channel_13,2, ADC_SampleTime_239Cycles5);  // STM32.PIN29#.PC3,ADC1_IN13, RW2, tim4
    ADC_RegularChannelConfig(ADC1, ADC_Channel_12,3, ADC_SampleTime_239Cycles5);  // STM32.PIN28#.PC2,ADC1_IN12, RW3, tim5
    ADC_RegularChannelConfig(ADC1, ADC_Channel_11,4, ADC_SampleTime_239Cycles5);  // STM32.PIN27#.PC1,ADC1_IN11, RW4, tim6
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10,5, ADC_SampleTime_239Cycles5);  // STM32.PIN26#.PC0,ADC1_IN10, RW5, tim7

    ADC_DMACmd(ADC1, ENABLE); // 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数
    ADC_Cmd(ADC1, ENABLE);    //开启ADC1, 使能指定的ADC1
  
    ADC_ResetCalibration(ADC1);                // 复位指定的ADC1的校准寄存器,重新校准
    while(ADC_GetResetCalibrationStatus(ADC1));// 等待重新校准完成
    ADC_StartCalibration(ADC1);                // 开始指定ADC1的校准状态,开始校准
    while(ADC_GetCalibrationStatus(ADC1));     // 等待校准完成
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);    //连续转换开始,ADC通过DMA方式不断的更新RAM区。
}

extern  u16   ADCConvertedValue[N_SAMPLE_PER10MS * ADC_MUX_MAX];
void DMA_Configuration()   
{
    DMA_InitTypeDef DMA_InitStructure;        
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    DMA_DeInit(DMA1_Channel1);                                                 // 开启DMA1的第一通道
    DMA_InitStructure.DMA_PeripheralBaseAddr  = ADC1_DR_ADDRESS;                    // DMA对应的外设基地址
    DMA_InitStructure.DMA_MemoryBaseAddr      = (uint32_t)&ADCConvertedValue;  // 内存存储基地址
    DMA_InitStructure.DMA_DIR                 = DMA_DIR_PeripheralSRC;         // DMA的转换模式为SRC模式,由外设搬移到内存
    DMA_InitStructure.DMA_BufferSize          = N_SAMPLE_PER10MS*ADC_MUX_MAX;  // DMA缓存大小,ADC_MUX_MAX
    //如此设置,使序列1结果放在ADCConvertedValue[0],序列2结果放在ADCConvertedValue[1]

    DMA_InitStructure.DMA_PeripheralInc       = DMA_PeripheralInc_Disable;    // 接收一次数据后,设备地址禁止后移
    DMA_InitStructure.DMA_MemoryInc           = DMA_MemoryInc_Enable;         // 接收一次数据后,目标内存地址后移
    DMA_InitStructure.DMA_PeripheralDataSize  = DMA_PeripheralDataSize_HalfWord;  //定义外设数据宽度为16位
    DMA_InitStructure.DMA_MemoryDataSize      = DMA_MemoryDataSize_HalfWord;  // DMA搬移数据尺寸,HalfWord就是为16位
    DMA_InitStructure.DMA_Mode                = DMA_Mode_Circular;    //转换模式,循环模式开启,Buffer写满后,自动回到初始地址开始传输
    DMA_InitStructure.DMA_Priority            = DMA_Priority_High;    //DMA优先级高
    DMA_InitStructure.DMA_M2M                 = DMA_M2M_Disable;      //M2M模式禁用
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);         

    DMA_Cmd(DMA1_Channel1, ENABLE);
}
海迹天涯 回答时间:2017-2-17 16:43:52
使用STM32F2xx系列连续采样多通道ADC时最好使用DMA模式,当每个通道转换完成后自动将转换值保存到目标地址中,其配置代码如下:
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsD253.tmp.jpg
由于使用到DMA,因此还要配置DMA的相应功能,配置代码如下:
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsD254.tmp.jpg
当然还不能忘记DMA的中断服务函数
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsD255.tmp.jpg
至此ADCDMA连续多通道转换配置完成,可以调用HAL_ADC_Start_DMA(&hadc1,ADC_ConvertedValue,ADC_NUMOFCHANNEL);启动转换;
其中ADC_CR 寄存器中的EOCS有如下描述:
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsD256.tmp.jpg
意思是:当设置为0时,整个常规序列转换完成后置位EOC,当设置为1时,常规序列组中每个通道转换完成后置位EOC

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

海迹天涯 回答时间:2017-2-17 16:44:34
我擦没有图片
海迹天涯 回答时间:2017-2-17 16:47:15
这个是我自己做多通道连续采集总结的经验,分享给你吧

图1

图1
图2.png
图3.png

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版