打印

关于AD转换的旧帖子,找不到链接

[复制链接]
7939|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
海天一色|  楼主 | 2011-10-31 10:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
https://bbs.21ic.com/club/bbs/showEssence.asp?id=10676
这个是圈圈的一个帖子,但是是旧网站的链接,点击后进不去,新网站的连接是什么呢?

17楼:
ADC的数据不是你去读的时候才采样的呀,控制时间的是启动
建议你参考我的程序吧,我直接用DMA加定时器采样的,44.1KBps的。
我的这个芯片是可以直接将定时器的比较信号启动ADC的。如果你的没有这个功能,那么在定时器中断中启动ADC即可。
启动后它就开始转换了,这时才是真正的采样,转换完成后,它会自动去触发DMA去读数据。当指定的数据个数达到时,
DMA会产生中断(或者你去查询也得),这时候就可以去处理这一些数据了。当然在数据处理之前,你可以先设置好
DMA,指向另外一个缓冲区,同时又采样了。

你要搞清楚这个关系:定时器是用来启动ADC的,而不是用来去读数据。ADC转换完毕会自动触发DMA读数据,DMA数据足够后,产生中断,处理数据。

https://bbs.21ic.com/club/bbs/showEssence.asp?id=10676
沙发
香水城| | 2011-10-31 10:35 | 只看该作者
你看看帖子的标题是什么,按照标题搜索一下。

使用特权

评论回复
板凳
海天一色|  楼主 | 2011-10-31 10:41 | 只看该作者
没有帖子标题,只有链接
在这个帖子里看到的
https://bbs.21ic.com/icview-110322-1-1.html
17楼

使用特权

评论回复
地板
香水城| | 2011-10-31 10:44 | 只看该作者
没有标题,没有内容,我没有办法找到。

使用特权

评论回复
5
海天一色|  楼主 | 2011-10-31 10:56 | 只看该作者
直接请教版主了。不舍近求远
问题: 定时器tim2的CC2触发ADC转换,采样512个点,利用DMA,DMA传输完后中断,进行相应的处理。存在的问题是,修改CC2的捕获值,采样率没有发生改变,不知问题出在哪里?
程序如下
//定时器设置
#include "stm32lib//stm32f10x.h"

//#define samplerate250
//#define samplerate500
#define samplerate1000
//  #define samplerate1
void Tim2_Config(void)
{
TIM_TimeBaseInitTypeDef Tim_TimeBaseStruct;
TIM_OCInitTypeDef Tim_OcIniStruct;
__IO uint16_t  CCR2_val = 40 ;

//开启tim2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_DeInit(TIM2);
//不同的采样率
#ifdef samplerate500
  Tim_TimeBaseStruct.TIM_Period = 20;
#endif
#ifdef  samplerate250
  Tim_TimeBaseStruct.TIM_Period = 40;
#endif
#ifdef samplerate1000
  Tim_TimeBaseStruct.TIM_Period = 10;
#endif
#ifdef samplerate1
  Tim_TimeBaseStruct.TIM_Period = 10000;
#endif

Tim_TimeBaseStruct.TIM_Prescaler = 7199;
Tim_TimeBaseStruct.TIM_ClockDivision = 0;
Tim_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2,&Tim_TimeBaseStruct);
//比较通道配置,因为ADC的时候定时器触发转换使用的是CC2,所以对OC2进行配置
Tim_OcIniStruct.TIM_OCMode = TIM_OCMode_Timing;
Tim_OcIniStruct.TIM_Pulse = CCR2_val;
Tim_OcIniStruct.TIM_OCPolarity = TIM_OCPolarity_High;
Tim_OcIniStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC2Init(TIM2,&Tim_OcIniStruct);
TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Disable);  //禁止重装
/*使能预装载*/
TIM_ARRPreloadConfig(TIM2, ENABLE);
/*预先清除所有中断位*/
TIM_ClearITPendingBit(TIM2,TIM_IT_Update|TIM_IT_CC2);
//中断开启
TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC2,ENABLE);
TIM_Cmd(TIM2,ENABLE);
}

//////ADC和DMA的设置
#include "stm32lib//stm32f10x.h"

#define smpnum    256
#define channelCnt 2  //ad转换的通道数目
#define buffsize smpnum*channelCnt    //dma缓冲区大小
                      //为了进行FFT转换,每个通道的采样点数应为(2^n),采样点数取64、256或512
                      //缓冲区大小应该为通道数*采样点数

u16 ADCCov[buffsize];           

static DMA_InitTypeDef DMA_InitStructure;
static ADC_InitTypeDef adc_initStruct;

void adcIni(void);
uint readAdc(void);

void adcIni(void)
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  ADC_DeInit(ADC1);
  adc_initStruct.ADC_Mode = ADC_Mode_Independent;
  adc_initStruct.ADC_ContinuousConvMode = ENABLE;
  adc_initStruct.ADC_ScanConvMode = ENABLE;
  adc_initStruct.ADC_DataAlign = ADC_DataAlign_Right;
  adc_initStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; //设置定时器触发AD转换
  adc_initStruct.ADC_NbrOfChannel = channelCnt;  //
  ADC_Init(ADC1,&adc_initStruct);
  
  ADC_RegularChannelConfig(ADC1,ADC_Channel_14,1,ADC_SampleTime_28Cycles5); //PC4 adc1 in14
  ADC_RegularChannelConfig(ADC1,ADC_Channel_15,2,ADC_SampleTime_28Cycles5); //PC5 adc1 in15
  //ADC_RegularChannelConfig(ADC1,ADC_Channel_4,3,ADC_SampleTime_71Cycles5); //PA4 adc1 in4
  //ADC_RegularChannelConfig(ADC1,ADC_Channel_5,4,ADC_SampleTime_239Cycles5); //PA5 adc1 in5
  //ADC_RegularChannelConfig(ADC1,ADC_Channel_6,5,ADC_SampleTime_71Cycles5); //PA6 adc1 in6
  //ADC_RegularChannelConfig(ADC1,ADC_Channel_7,6,ADC_SampleTime_239Cycles5); //PA7 adc1 in7
  ADC_DMACmd(ADC1,ENABLE);
  ADC_Cmd(ADC1,ENABLE);
  //ADC_SoftwareStartConvCmd(ADC1,ENABLE); //软件触发转换
  ADC_ExternalTrigConvCmd(ADC1,ENABLE);  //外部触发ADC转换,使用TIM2的CC2进行触发
  /*重置校准寄存器 */   
  ADC_ResetCalibration(ADC1);
  while(ADC_GetResetCalibrationStatus(ADC1));
   
  /*开始校准状态*/
  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1));
      
  /* 人工打开ADC转换.*/
  ADC_ExternalTrigConvCmd( ADC1, ENABLE); //使能或者失能ADCx的经外部触发启动转换功能  
        
}


//DMA的配置
void DMA_Configuration(void)
{
       
        /* 允许 DMA1 */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
        /* DMA通道1*/
        DMA_DeInit(DMA1_Channel1);
        DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)( &(ADC1->DR));                //ADC1数据寄存器
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADCCov;                                        //获取ADC的数组
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                                        //片内外设作源头
        DMA_InitStructure.DMA_BufferSize = buffsize;                                             //每次DMAbuffsize个数据
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;        //外设地址不增加
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                //内存地址增加
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;        //半字
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;                        //半字
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                                                //普通模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;                                                        //高优先级
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                                                //非内存到内存
        DMA_Init(DMA1_Channel1, &DMA_InitStructure);
       
        DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);                                                                //DMA通道1传输完成中断
       
        /* Enable DMA1 channel1 */
        DMA_Cmd(DMA1_Channel1, ENABLE);
}

///DMA中断
volatile bool ADC_Ok;
void DMA1_Channel1_IRQHandler(void)                  //NVIC、stm32f10x_it.h、startup_stm32f10x_md.s中的名称要一致
{
        if(DMA_GetITStatus(DMA1_IT_TC1))
        {
                DMA_ClearITPendingBit(DMA1_IT_GL1);        //清除全部中断标志
                ADC_Ok=TRUE;
                TIM_ClearITPendingBit(TIM2,TIM_IT_Update|TIM_IT_CC2);           
        }
}

使用特权

评论回复
6
海天一色|  楼主 | 2011-10-31 10:59 | 只看该作者
板子上调试,AD和定时器都能正常工作。
nvic程序
void NVIC_Configuration(void)
{
  
  NVIC_InitTypeDef nvic_initStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);  
  nvic_initStructure.NVIC_IRQChannel=DMA1_Channel1_IRQn;
  nvic_initStructure.NVIC_IRQChannelPreemptionPriority=0;
  nvic_initStructure.NVIC_IRQChannelSubPriority=0;
  nvic_initStructure.NVIC_IRQChannelCmd=ENABLE;
  NVIC_Init(&nvic_initStructure);   
  
  nvic_initStructure.NVIC_IRQChannel = TIM2_IRQn;
  nvic_initStructure.NVIC_IRQChannelPreemptionPriority = 0;
  nvic_initStructure.NVIC_IRQChannelSubPriority = 1;
  nvic_initStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&nvic_initStructure);
}

使用特权

评论回复
7
香水城| | 2011-10-31 11:46 | 只看该作者
直接请教版主了。不舍近求远
问题: 定时器tim2的CC2触发ADC转换,采样512个点,利用DMA,DMA传输完后中断,进行相应的处理。存在的问题是,修改CC2的捕获值,采样率没有发生改变,不知问题出在哪里?
程序如下
//定 ...
海天一色 发表于 2011-10-31 10:56


为什么要修改捕获值?

使用特权

评论回复
8
海天一色|  楼主 | 2011-10-31 13:15 | 只看该作者
Tim_OcIniStruct.TIM_Pulse = CCR2_val;
改变CC2_val,可以改变每秒内的采样次数,用定时的进行AD转换

使用特权

评论回复
9
海天一色|  楼主 | 2011-10-31 13:22 | 只看该作者
Tim_OcIniStruct.TIM_Pulse = CCR2_val;
使用的是CC2来定时触发AD转换
不同的值,每秒的采样点数不一样

使用特权

评论回复
10
香水城| | 2011-10-31 13:43 | 只看该作者
Tim_OcIniStruct.TIM_Pulse = CCR2_val;
使用的是CC2来定时触发AD转换
不同的值,每秒的采样点数不一样
海天一色 发表于 2011-10-31 13:22


这个不是捕获值,这是比较值,如果你有波形输出,改变它只改变波形的占空比,不改变频率。对于你的应用,改变比较值不会影响采样的频率。

使用特权

评论回复
11
海天一色|  楼主 | 2011-10-31 14:09 | 只看该作者
那就是我理解有误。谢谢。
程序的结果也如你说的,
采样速率只和预分频数和定时器的计数器预装值有关。改这个捕获值不起作用。
adc_initStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;
那么这种触发方式,通过改Tim2的什么参数来修改触发AD转换的采样速率呢?

使用特权

评论回复
12
yinyangdianzi| | 2011-10-31 14:19 | 只看该作者
高级搜索:ADC    肯定能找到

使用特权

评论回复
13
香水城| | 2011-10-31 17:53 | 只看该作者
那就是我理解有误。谢谢。
程序的结果也如你说的,
采样速率只和预分频数和定时器的计数器预装值有关。改这个捕获值不起作用。
adc_initStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;
那么这种触发方 ...
海天一色 发表于 2011-10-31 14:09


你不是说了:采样速率只和预分频数和定时器的计数器预装值有关。你就改变这两个值就好了。

使用特权

评论回复
14
hackthree| | 2011-11-1 08:40 | 只看该作者
应该是圈圈的那个FFT频谱显示的帖子。。
不过他用的不是STM32,是AT91SAM7S64
这个:
https://bbs.21ic.com/viewthread.php?tid=119652&highlight=

使用特权

评论回复
15
wenzj12345| | 2012-3-22 15:00 | 只看该作者
走过··

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

80

帖子

0

粉丝