怎样实现ADC连续转换
我现在想要用战舰板子(核心是STM32F103ZET6)实现ADC连续转换以及串口输出。比如,输入模拟正弦信号,通过ADC转换后由串口输出,通过串口调试助手在电脑上显示数据,应该怎样做?要有比较详细的步骤,最好有代码。谢各位指点!有例程的,在网上找找,可以满足你的要求的。 网上都可以找到! 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Çø¡£
}
externu16 ADCConvertedValue;
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£¬ÐòÁÐ2½á¹û·ÅÔÚADCConvertedValue
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);
} 再发一个,带中文说明的
#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区。
}
externu16 ADCConvertedValue;
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,序列2结果放在ADCConvertedValue
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);
} 再发一个,带中文说明的
#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区。
}
externu16 ADCConvertedValue;
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,序列2结果放在ADCConvertedValue
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);
} 使用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 至此ADC的DMA连续多通道转换配置完成,可以调用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。 我擦没有图片:L 这个是我自己做多通道连续采集总结的经验,分享给你吧
页:
[1]