OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 20295|回复: 19

STM32 定时器触发ADC且用DMA来搬运数据。

[复制链接]

76

主题

355

帖子

0

精华

高级会员

Rank: 4

积分
671
金钱
671
注册时间
2012-9-19
在线时间
5 小时
发表于 2014-11-27 15:23:37 | 显示全部楼层 |阅读模式
5金钱
我想设置一个1Khz的采样率来采集数据。要采集1000个点。请问程序怎么写啊。。ADC的采样率貌似的用定时器来完成。然后1000个点我用DMA来拟定。只要1000个点我就近DMA中断取数且分析。程序谁有代码给我看看。。另复上我百度的。不知道能用否。
void stm32ADCDMA(void)
{
        ADC_InitTypeDef ADC_InitStructure;
        NVIC_InitTypeDef    NVIC_InitStructure;
        DMA_InitTypeDef DMA_InitStructure;  //定义DMA初始化结构体

        adc_GPIO_Init();     //
模拟口初始化

        ADC_DeInit(ADC1);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);

        /* ADC1 configuration ------------------------------------------------------*/
        ADC_InitStructure.ADC_Mode  = ADC_Mode_Independent;        //
独立模式
        ADC_InitStructure.ADC_ScanConvMode = ENABLE;                //
扫描模式
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;        //
单次转换
        ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_T2_CC2;   //
TIM2CC2触发
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  //
数据右对齐
        ADC_InitStructure.ADC_NbrOfChannel =7;                                //
采样一个通道
        ADC_Init(ADC1, &ADC_InitStructure);


        ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1,ADC_SampleTime_13Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2,ADC_SampleTime_13Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3,ADC_SampleTime_13Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4,ADC_SampleTime_13Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5,ADC_SampleTime_13Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6,ADC_SampleTime_13Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7,ADC_SampleTime_13Cycles5);



        ADC_DMACmd(ADC1, ENABLE);
        ADC_Cmd(ADC1, ENABLE);            //
启动ADC1
        ADC_ResetCalibration(ADC1);         //
重置ADC1的校准寄存器
        while (ADC_GetResetCalibrationStatus(ADC1));         //
获取ADC重置校准寄存器的状态
        ADC_StartCalibration(ADC1);                                                //
开始ADC1的校准程序
        while (ADC_GetCalibrationStatus(ADC1));                         //
等待ADC1校准结束
       
 
        ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE); //使能ADC中断
        ADC_ExternalTrigConvCmd(ADC1, ENABLE);//
使能ADC经外部触发启动转换功能


        NVIC_InitStructure.NVIC_IRQChannel  = ADC1_2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//
先占优先级0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority   = 0;   //
从优先级
        NVIC_InitStructure.NVIC_IRQChannelCmd   = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

           /*DMA
相关设置*/
           RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//
初始化DMA时钟


        DMA_DeInit(DMA1_Channel1);
        DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address;//
外设地址
        DMA_InitStructure.DMA_MemoryBaseAddr=(u32)AdcResult;//
内存地址
        DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//DMA
传输方向单向
        DMA_InitStructure.DMA_BufferSize=7;//
设置DMA在传输时缓冲区的长度  word
        DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//
设置DMA的外设递增模式,一个外设
        DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//
设置DMA的内存递增模式
        DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//
外设数据字长 16bit
        DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//
内存数据字长 16bit
        DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//
设置DMA的传输模式:连续不断的循环模式
        DMA_InitStructure.DMA_Priority=DMA_Priority_VeryHigh;//DMA
优先级别最高  4 High/Medium/Low
        DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//
设置DMA2memory中的变量互相访问禁止
        DMA_Init(DMA1_Channel1,&DMA_InitStructure);//
按照DMA_InitStructure变量初始化DMA1的通道1
        DMA_Cmd(DMA1_Channel1,ENABLE);//
允许DMA通道1传输
       
 
        DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);//使能DMA通道1中断
        DMA_ClearFlag(DMA1_FLAG_TC1);//
清除Channel1中断
       
 
        /*配置DMA的中断通道*/
        NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}


然后定时器的配方没找到。。

具有资深STM32点灯技术,
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2014-11-27 16:08:09 | 显示全部楼层
TIM3_Int_Init(10, 7199);

void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

//定时器TIM3初始化
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
TIM_ITConfig(TIM3, TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清中断,以免一启用中断后立即产生中断
    TIM_SelectOutputTrigger(TIM3, xxx);           //选择TIM2的update事件更新为触发源 
    
  //中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;  //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

TIM_Cmd(TIM3, ENABLE);  //使能TIMx   
}

void TIM3_IRQHandler(void)   //TIM3中断
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清除TIMx更新中断标志 
    }
}
小小蜗牛
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2014-11-27 16:11:02 | 显示全部楼层
去掉adc中断,有dma,adc中断不执行。进去一判断就跳出去了。
小小蜗牛
回复

使用道具 举报

76

主题

355

帖子

0

精华

高级会员

Rank: 4

积分
671
金钱
671
注册时间
2012-9-19
在线时间
5 小时
 楼主| 发表于 2014-11-27 17:35:03 | 显示全部楼层
回复【3楼】jiutianshenjian:
---------------------------------
你给我的是TIM定时器配置吧。。。大哥。能帮我梳理一下吗? 我一直弄不明白。采样频率。你看。有个ADC的时钟如果我6分频会得到72/6=12M这样是符合条件的。手册说最大不能14M。所以我在ADC时钟为12M下。我想获得一个1K采样率。那么我的TIM要配置成1Khz  对吧。。可具体ADC又怎么配呢?看到ADC有什么293.5个周期什么的。我就晕了
具有资深STM32点灯技术,
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2014-11-27 17:48:52 | 显示全部楼层
回复【4楼】敌害:
---------------------------------
12M,每1/12微秒做一次什么呢,应该是比较一次吧。
1KHz就是1ms1个周期吧。
239.5那个越大越准确。比较次数越多,越接近实际值吧。
但是例如239.5计算出来不合适,就得改小。
239.5+12.5=252.
252*1/12=21μs. 就是21微秒准备好一次,1个周期1ms内有47个21微秒,所以,此时,你最多一个周期采集47次了。
如果你想采集50次,就不能选这个239.5.
小小蜗牛
回复

使用道具 举报

76

主题

355

帖子

0

精华

高级会员

Rank: 4

积分
671
金钱
671
注册时间
2012-9-19
在线时间
5 小时
 楼主| 发表于 2014-11-28 08:49:11 | 显示全部楼层
回复【5楼】jiutianshenjian:
---------------------------------
貌似听明白了。可是。我要想用定时器溢出来做一次采样。 我配置ADC的触发是TIM2。。可我ADC的这个时钟。还有这个什么239.5,什么的。还用配吗?配好会和我的TIM2定时到采一次 冲突吗?
具有资深STM32点灯技术,
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2014-11-28 08:56:01 | 显示全部楼层
回复【6楼】敌害:
---------------------------------
你的1KHz应该是指每个采样点之间是1ms吧?
那就不是前面我说的一个周期1ms

你配置的定时器是1ms溢出采样一次的话,远大于21微秒。
写最大的239.5吧。
你只要两个采样点间隔时间大于准备好的时间,239.5+12.5再乘以1/12就行了。

我也是自己总结的,不一定说的准确。
小小蜗牛
回复

使用道具 举报

76

主题

355

帖子

0

精华

高级会员

Rank: 4

积分
671
金钱
671
注册时间
2012-9-19
在线时间
5 小时
 楼主| 发表于 2014-11-28 10:32:05 | 显示全部楼层
回复【7楼】jiutianshenjian:
---------------------------------
定时器怎么写呢?我看到有人用的是TIM1_CC1 他直接写定时器配置成想要的定时时间。可也有人用PWM,不仅时间调整成想要的定时时间。PWM也调整成50%不懂了
具有资深STM32点灯技术,
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2014-11-28 11:09:18 | 显示全部楼层
回复【8楼】敌害:
---------------------------------
我就用的update

其他还没用过。。。
小小蜗牛
回复

使用道具 举报

3

主题

6

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2015-1-14
在线时间
0 小时
发表于 2015-1-19 20:53:45 | 显示全部楼层
楼主我现在也在做类似的东西,你的问题解决了么?能不能发一份程序参考一下?不胜感激
回复

使用道具 举报

25

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
399
金钱
399
注册时间
2015-5-2
在线时间
59 小时
发表于 2015-11-16 20:29:52 | 显示全部楼层
楼主,解决这个问题了没?ADC 定时器采集,DMA传输,可以给个DEMO么?
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2015-9-1
在线时间
1 小时
发表于 2015-12-21 15:57:16 | 显示全部楼层
回复【9楼】jiutianshenjian:
---------------------------------
可以给一个demo么
回复

使用道具 举报

3

主题

7

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2015-12-13
在线时间
1 小时
发表于 2015-12-24 10:17:16 | 显示全部楼层
回复【5楼】jiutianshenjian:
---------------------------------
请问我想采集50次,按你的推导应该是227.5个周期,可是将239.5修改为227.5的时候总会出错
回复

使用道具 举报

4

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2016-1-30
在线时间
22 小时
发表于 2016-7-6 15:01:40 | 显示全部楼层
jiutianshenjian 发表于 2014-11-28 11:09
回复【8楼】敌害:
---------------------------------
我就用的update

其他还没用过。。。

怎么把这么多路的AD数据放进定时器中断函数里呢?
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2016-7-6 16:12:37 | 显示全部楼层
江月疏影 发表于 2015-12-24 10:17
回复【5楼】jiutianshenjian:
---------------------------------
请问我想采集50次,按你的推导应该是227. ...

哪有227.5,只有几个可选的值。
小小蜗牛
回复

使用道具 举报

0

主题

0

帖子

0

精华

新手入门

积分
1
金钱
1
注册时间
2020-6-4
在线时间
0 小时
发表于 2016-7-24 14:13:52 | 显示全部楼层
PWM的上升沿触发一次ADC扫描
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
10
金钱
10
注册时间
2018-7-11
在线时间
7 小时
发表于 2016-8-16 09:06:39 | 显示全部楼层
楼主,ADC触发用定时器,DMA那部分要怎么处理呢,还有ADC的转换时间多长适合
回复

使用道具 举报

1

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2016-7-24
在线时间
19 小时
发表于 2016-8-18 12:49:08 | 显示全部楼层
江月疏影 发表于 2015-12-24 10:17
回复【5楼】jiutianshenjian:
---------------------------------
请问我想采集50次,按你的推导应该是227. ...

ADC采集的周期间隔是确定的几个 看手册
回复

使用道具 举报

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2016-4-21
在线时间
18 小时
发表于 2016-10-7 16:11:59 | 显示全部楼层
敌害 发表于 2014-11-28 10:32
回复【7楼】jiutianshenjian:
---------------------------------
定时器怎么写呢?我看到有人用的是TIM1_C ...

你好,如果用PWM的话,占空比是不是随便都行?上升沿触发,是不是就是一周期采样一次。
回复

使用道具 举报

4

主题

48

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
205
金钱
205
注册时间
2019-6-15
在线时间
36 小时
发表于 2019-6-20 17:37:43 | 显示全部楼层
楼主请教一下,我现在要用STM32 ADC采集正弦波,采样频率为1K,采样方式是DMA+TIM。现在我可以实现数据采集,但是用采集到的数据计算出来的均方根值不对,不知道哪里的问题。这种方式 采集正弦信号方案是可行的吧?然后采的值不对可能是什么原因呢?
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-16 00:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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