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

怎样实现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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版