OpenEdv-开源电子网

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

stm32之TIM+ADC+DMA采集50HZ交流信号

[复制链接]

8

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2012-12-19
在线时间
16 小时
发表于 2015-2-28 15:04:19 | 显示全部楼层 |阅读模式
将部分代码贴出,共同学习。

void ADC_DMA_Config(void)
{
 DMA_InitTypeDef DMA_InitStructure;              
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 DMA_DeInit(DMA1_Channel1);  //DMA复位
 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;  //外设的地址
 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;  //存储区的起始地址
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //DMA传输方向到内部存储区
 DMA_InitStructure.DMA_BufferSize = ADC_FILT*ADC_NUM;  //ADC转换的次数
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                 //外设地址不变
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                          //内存地址递增
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //ADC数据长度为16位
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;  //存储区数据长度为16位
 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //DMA工作方式为循环工作
 DMA_InitStructure.DMA_Priority = DMA_Priority_High;  //DMA 优先级高
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //存储器对存储器关闭
 DMA_Init(DMA1_Channel1, &DMA_InitStructure);  //DMA通道初始化
 DMA_Cmd(DMA1_Channel1,ENABLE);  //DMA使能
}
 void ADC_START(void)
 {
   ADC_DMACmd(ADC1, ENABLE);    //ADC的DMA功能开启
   ADC_Cmd(ADC1, ENABLE);  //ADC使能
   ADC_ResetCalibration(ADC1);  //ADC复位校准
   while(ADC_GetResetCalibrationStatus(ADC1));  //ADC等待完成
   ADC_StartCalibration(ADC1);                                                    //开始校准
   while(ADC_GetCalibrationStatus(ADC1));  //ADC等待校准完成
   ADC_SoftwareStartConvCmd(ADC1, ENABLE);                                        //使能ADC的软件转换启动功能
  }
void ADC1_Config(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 ADC_InitTypeDef  ADC_InitStructure;     
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                         ////PA4567时钟使能
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);                         ////PC45时钟使能
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);                         ////PB01时钟使能     
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; ////初始化PA4567为模拟输入
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //管脚设为模拟输入
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;     ////初始化PC45为模拟输入
 GPIO_Init(GPIOC, &GPIO_InitStructure);
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; ////初始化PB0 1为模拟输入
 GPIO_Init(GPIOB, &GPIO_InitStructure);
 ADC_DMA_Config();                                                         /////使能DMA_ADC设置
  
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);         /////使能外设ADC时钟
 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                                  //ADC1和ADC2工作在独立模式 
 ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                        //多通道
 ///ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                               //连续转换
 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                              //连续转换
 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;
 ///ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;             //软件启动转换
 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                             //转换结果右对齐
 ADC_InitStructure.ADC_NbrOfChannel = ADC_NUM;                                      //通道数目
 ADC_Init(ADC1, &ADC_InitStructure);  
/// ADC_TempSensorVrefintCmd(ENABLE);                                            //使能片内温度传感器  
/// RCC_ADCCLKConfig(RCC_PCLK2_Div6);                                            //PCLK 6分频
 RCC_ADCCLKConfig(RCC_PCLK2_Div8);                                               //ADC 时钟 为PCLK2 8分频
 ADC_RegularChannelConfig(ADC1, ADC_Channel_4,  1, ADC_SampleTime_239Cycles5);  //通道4,转换次序,转换时间
 ADC_RegularChannelConfig(ADC1, ADC_Channel_5,  2, ADC_SampleTime_239Cycles5);  //通道5,转换次序,转换时间
 ADC_RegularChannelConfig(ADC1, ADC_Channel_6,  3, ADC_SampleTime_239Cycles5);  //通道6,转换次序,转换时间
 ADC_RegularChannelConfig(ADC1, ADC_Channel_7,  4, ADC_SampleTime_239Cycles5);  //通道7,转换次序,转换时间
 ADC_RegularChannelConfig(ADC1, ADC_Channel_8,  5, ADC_SampleTime_239Cycles5);  //通道8,转换次序,转换时间
 ADC_RegularChannelConfig(ADC1, ADC_Channel_9,  6, ADC_SampleTime_239Cycles5);  //通道9,转换次序,转换时间
 ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 7, ADC_SampleTime_239Cycles5);  //通道14,转换次序,转换时间
 ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 8, ADC_SampleTime_239Cycles5);  //通道15,转换次序,转换时间
// ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 6, ADC_SampleTime_239Cycles5);
 ADC_START();
}
/*
 系统时钟为72MHZ,FPCLK2=72 000 000HZ
 对50HZ交流信号进行采集,一个周期为20MS, 采集8路信号,每个信号采用64次,
 20*1000us/64=312us,即每隔312us要启动一次采集信号(需要采集8路信号),采集64次后正好是一个周期;
 采集一次8路的时间:(239.5+12.5)*8/9M =224us

 */
 void TIM2_Configuration(void) 
 { 
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
  TIM_OCInitTypeDef TIM_OCInitStructure;  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 
  TIM_TimeBaseStructure.TIM_Period    = 312;                             //设置一个周期0.312ms 
  TIM_TimeBaseStructure.TIM_Prescaler = 71;                           //系统主频72M,这里分频72,相当于1000K的定时器2时钟 
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; 
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;          /////
  TIM_TimeBaseInit(TIM2, & TIM_TimeBaseStructure); 
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                     //下面详细说明  
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;         //TIM_OutputState_Disable; 
  TIM_OCInitStructure.TIM_Pulse = 20; /////
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;              //如果是PWM1要为Low,PWM2则为High
  TIM_OC2Init(TIM2, & TIM_OCInitStructure);    
  TIM_Cmd(TIM2, ENABLE);   
  TIM_InternalClockConfig(TIM2); 
  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); 
  TIM_UpdateDisableConfig(TIM2, DISABLE); 
  } 

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

21

主题

2205

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5140
金钱
5140
注册时间
2014-8-26
在线时间
1317 小时
发表于 2015-2-28 18:06:04 | 显示全部楼层
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2015-2-28 22:14:51 | 显示全部楼层
谢谢分享....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

8

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2012-12-19
在线时间
16 小时
 楼主| 发表于 2015-3-5 16:48:56 | 显示全部楼层
不客气,以前都是看别人的代码,这个代码是产品的一部分单独摘出来。
回复 支持 反对

使用道具 举报

2

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2013-10-31
在线时间
3 小时
发表于 2015-3-6 18:03:10 | 显示全部楼层
谢谢楼主,谢谢分享
回复 支持 反对

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2015-3-6 22:54:22 | 显示全部楼层
顶一个,正好之前完成一个kl25的定时器+adc+dma的程序,有空整理一下分享出来
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复 支持 反对

使用道具 举报

8

主题

29

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
236
金钱
236
注册时间
2015-1-22
在线时间
72 小时
发表于 2015-6-6 16:05:07 | 显示全部楼层
有个问题,看楼主应该是定时器触发AD采样,那为什么 要用软件转换启动功能,
ADC_SoftwareStartConvCmd(ADC1, ENABLE);                                        //使能ADC的软件转换启动功能


应该是外部
ADC_ExternalTrigConvCmd(ADC1, ENABLE);   //设置外部触发模式使能
回复 支持 反对

使用道具 举报

25

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
399
金钱
399
注册时间
2015-5-2
在线时间
59 小时
发表于 2016-7-2 18:12:03 | 显示全部楼层
ljfljfljf 发表于 2015-6-6 16:05
有个问题,看楼主应该是定时器触发AD采样,那为什么 要用软件转换启动功能,
ADC_SoftwareStartConvCm ...

同问?
回复 支持 反对

使用道具 举报

1

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2016-3-8
在线时间
41 小时
发表于 2016-8-22 09:04:34 | 显示全部楼层
初学者求问,采集一次8路的时间:(239.5+12.5)*8/9M =224us这句是什么意思?239.5    12.5  和9分别是啥
回复 支持 反对

使用道具 举报

1

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2016-3-8
在线时间
41 小时
发表于 2016-8-22 09:34:59 | 显示全部楼层
神出没 发表于 2016-8-22 09:04
初学者求问,采集一次8路的时间:(239.5+12.5)*8/9M =224us这句是什么意思?239.5    12.5  和9分别是啥

哦,我知道,239.5+12.5是采样周期,72M的8分频是9M。谢谢楼主
回复 支持 反对

使用道具 举报

1

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2016-8-15
在线时间
17 小时
发表于 2016-9-9 17:18:05 | 显示全部楼层
全部搞出来啊
回复 支持 反对

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2016-9-9
在线时间
4 小时
发表于 2016-9-9 17:32:20 | 显示全部楼层
多谢分享,新手不太懂,求硬件连接
回复 支持 反对

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2016-9-9
在线时间
4 小时
发表于 2016-9-9 17:33:10 | 显示全部楼层
如果采集1KHZ信号可以么?
回复 支持 反对

使用道具 举报

8

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2012-12-19
在线时间
16 小时
 楼主| 发表于 2016-10-9 21:09:34 | 显示全部楼层
采集1KHZ的话肯定是可以的,可以自己计算下。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-15 10:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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