OpenEdv-开源电子网

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

定时器触发扫描模式ADC+DMA传输(寄存器版本)

[复制链接]

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
发表于 2013-1-11 13:55:59 | 显示全部楼层 |阅读模式
   来论坛这么久了,伸手拿了好多东西,最近要使用ADC,就研究了下ADC。ADC+DMA传输就不介绍了,论坛有帖子。下面看下定时器触发AD。


ADC1可由上述事件触发,我这里使用的是TIM2的CC2事件,则 设置  ADC1->CR2|=3<<17;     //定时器2 CC2事件控制规则通道转换
很多新手疑问,TIM2的CC2事件指的是什么,如何触发CC2事件?
我当时也有这样的疑问,只知道溢出事件,更新事件是什么。疑惑了好久,之后看到之后看到了这么一张图。


在这张图上终于可以看见所谓的CC1,CC2,CC3,CC4了。所谓的CCX事件,就是指捕获/比较X寄存器的所发生的事件。意思就是说必须得使用 捕获/比较X寄存器才可以产生CCX事件。
这里我使用的是捕获/比较寄存器的PWM输出功能。则可以写出TIMER的程序
RCC->APB1ENR|=1<<0;   //TIM2时钟使能
TIM2->CCMR1|=7<<12;   //CH2 PWM2模式 
TIM2->CCMR1|=1<<11;   //CH2预装载使能
TIM2->ARR=1900;           //设定计数器自动重装值
TIM2->SC=0;                //预分频器不分频
TIM2->CCR2=0x23;         //设置占空比
TIM2->CR1=0x8000;      //ARPE使能
通道2事件进入总线则写出
TIM2->CCER|=1<<4;     //OC2 输出使能
最后使能定时器
TIM2->CR1|=0x01;      //使能定时器2
定时器部分设置完毕,界面贴出 ADC 和DMA代码
void  adc_init(void)
 {
//外部设置
  GPIOA->CRL&=0XFFFFFFF0;   //PA0 1  输入            
  RCC->APB2ENR|=1<<2|1<<9;  //开启PA时钟 ,以及ADC时钟
  RCC->APB2RSTR|=1<<9;      //复位adc1
  RCC->APB2RSTR&=~(1<<9);   //复位完成,需要将复位关闭   
  RCC->CFGR|=2<<14;         //设置为4分频给ADC转换时钟   ADCCLK=12Mhz    
 
//AD设置  
  ADC1->CR1|=1<<8;      //开启扫描模式
//ADC1->CR1|=1<<5;      //允许中断

  ADC1->CR2|=1<<0;      //开启AD转换器
  ADC1->CR2|=0<<1;      //设置为单次转换模式
  ADC1->CR2|=1<<2;      //开启AD校准
  while(ADC1->CR2&1<<2);//等待校准结束
  ADC1->CR2|=1<<3;      //开启复位校准
  while(ADC1->CR2&1<<3);//等待校准结束
  ADC1->CR2|=1<<8;      //允许dma访问
  ADC1->CR2|=3<<17;     //定时器2 CC2事件控制规则通道转换
  ADC1->CR2|=1<<20;     //允许外部事件触发
//  ADC1->CR2|=1<<23;     //开启内部温度传感器
//  ADC1->CR2|=1<<22;     //开始规则转换
 
  ADC1->SMPR2|=0<<0;    //通道0  采样周期1.5周期
//  ADC1->SMPR2|=0<<3;    //通道1  采样周期1.5周期
//  ADC1->SMPR2|=0<<6;    //通道2  采样周期1.5周期
//  ADC1->SMPR2|=0<<9;    //通道3  采样周期1.5周期
//  ADC1->SMPR2|=0<<12;   //通道4  采样周期1.5周期
//ADC1->SMPR2|=0<<16;   //通道5  采样周期1.5周期
//ADC1->SMPR2|=0<<18;   //通道6  采样周期1.5周期
//  ADC1->SMPR1|=7<<18;   //通道16  239.5周期,提高采样时间可以提高精确度
 
  ADC1->SQR1|=0<<20;    //开启一个转换

// MY_NVIC_Init(2,1,ADC1_2_IRQChannel,2);        //设置中断优先级
  ADC1->SQR3=0;  //规则通道安排
//  ADC1->CR2|=1<<22;     //开始规则转换
}
为了便于设置我只开启了通道0,当然大家可以随便设置,提醒几点:
1.由于是外部触发,要开启外部事件触发
2.CR2 22位就是开始规则转换不能开启
3.扫描和循环概念不能混淆,扫描实际上是一次性转换几个通道,而循环是不停的转换。
我们这里是由外部触发,则使用单次转换模式。
需要多通道的,直接加上通道即可使用,无须更改其他设置。
注意手册上明确指出多通道时必须使用DMA
最后设置DMA,贴上程序
void dma_init(DMA_Channel_TypeDef*DMA_CHx,u32 slaveaddr,u32 masteraddr,u16 number)
{

RCC->AHBENR|=1<<0;//打开dma时钟
__nop();
__nop();
DMA_CHx->CCR|=0<<4;                  //从外设读取数据
DMA_CHx->CMAR=(u32)slaveaddr;    //存储器地址
DMA_CHx->CPAR=(u32)masteraddr;  //外设地址
DMA_CHx->CNDTR=number;            //代表dma通道传数输据的个数
DMA_CHx->CCR|=1<<5;                 //执行循环模式
//dma_number->CCR|=1<<6;         //从存储器读取数据的时,地址指针可自动加1
DMA_CHx->CCR|=1<<7;                //存储器地址增量模式
DMA_CHx->CCR|=1<<8;                //外设数据宽度为16位
DMA_CHx->CCR|=1<<10;              //存储器数据宽度为16位
DMA_CHx->CCR|=2<<12;              //dma优先级高
DMA_CHx->CCR|=1<<0;               //开启dma传输
}
DMA有些概念需要注意。DMA传输是由ADC事件控制,所以我们时刻保持DMA开启即DMA开启循环模式。
DMA循环模式写数据是写满缓冲区才从头执行的。而单次模式时每次都从头开始写。
有必要时我们可以重启DMA,强制使循环模式从头开始写数据
void dma_restart(DMA_Channel_TypeDef*DMA_CHx)
{DMA_CHx->CCR&=~(1<<0); //关闭 
DMA_CHx->CCR|=(1<<0); //开启
}
需要知道定时器期间采集了多少数据,我们可以使用ADC中断计数。

定时器触发ADC就此结束,不好的地方希望指出。

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-1-11 15:15:12 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2013-3-3
在线时间
5 小时
发表于 2013-3-3 20:10:28 | 显示全部楼层
您好~请问一下您这个代码自己测试过了吗?我测试了一下不能进中断啊!
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-3-4 07:59:50 | 显示全部楼层
回复【3楼】guwu454:
---------------------------------
嗯,测试好了。还有这里没中断
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2013-1-25
在线时间
0 小时
发表于 2013-3-12 16:49:15 | 显示全部楼层
回复【4楼】tian123chi:
---------------------------------
刚刚开始学习,也遇到这个问题。想问一下,这个功能的实现是不是不用中断处理函数?在主函数中声明存储器地址,然后使能DMA就可以得到采集的数据了?
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-3-12 17:02:31 | 显示全部楼层
回复【5楼】scutauliguanlin:
---------------------------------
不是 不需要中断
回复 支持 反对

使用道具 举报

10

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2012-12-27
在线时间
0 小时
发表于 2013-3-16 21:19:18 | 显示全部楼层
回复【6楼】tian123chi:
回复【5楼】scutauliguanlin: --------------------------------- 不是 不需要中断
---------------------------------
为什么不需要开启规则转换?CR2的22位?
回复 支持 反对

使用道具 举报

10

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2012-12-27
在线时间
0 小时
发表于 2013-3-17 11:37:32 | 显示全部楼层
 求助,我根据论坛上的帖子修给了一下,用Timer2的CH2来触发ADC1,也就是图中的ICG,同时用DMA和串口通信,但不知道哪里出错了,串口助手就是没动静、
 

#include "stm32f10x_lib.h"
#include "sys.h"
#include "delay.h"
#include "led.h"
#define USART1_DR_Base  0x40013804 
#define ADC1_DR_Address 0x4001244C //0x40012400+0x4C
#define KEY0 PAin(13)   //PA13按键0
//#define DMA1_MEM_ADD    (u32)ADC_Buf
//#define DMA1_MEM_SIZE    (u32)sizeof(ADC_Buf)
u16 ADC_Buf[714];
u16 times=0;
void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx);//配置DMA1_CHx
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx);//使能DMA1_CHx
void MYDMA_GOnes(DMA_Channel_TypeDef*DMA_CHx); //执行一次DMA   
void  adc_init(void) ;
void  USART_Initaize(u32 pclk2,u32 bound);
void  Uart1_PutChar(u8 ch);
void Uart1_PutString(u8 *Buf, u8 Len);
void PWM_Init(u16 arr,u16 psc);
void PWM4_PULSE_Init(u16 arr1,u16 psc1,u16 arr2,u16 psc2);
void KEY_Init(void);
u8 KEY_Scan(void);
//主函数的内容:
int main(void)
{    
 
 u16 t;
 u16 m;
 u32 temp =0;
 u16 adcx;
 u8 table[4];
 u8 *p;
 p= table;
 Stm32_Clock_Init(9);//72M
 delay_init(72);     //延时初始化
 WM_Init(18,1);  //Timer3 CH3 PB0  主时钟
    PWM4_PULSE_Init(1000,1440,12,125);    // Timer4 CH1 时钟为100K  SH  PB6, Timer2 CH2 PA1  ICG
 USART_Initaize(72,9600); //串口初始化
 
  while (1)
    {
  t=KEY_Scan();//得到键值
     if(m)
  {        
   switch(m)
   {    
    case 1:
           adc_init();
        break;
    }
   }
     if(DMA1->ISR&(1<<1)) //传输完成了
  { 
      
   for(t=0;t<715;t++)
   {   
   temp = ADC_Buf[t];
   temp = temp /5;
   adcx=temp*330/4096;;    
   table[0]=adcx / 100 + 0x30;
   table[1]='.';
   table[2]=adcx % 100/10 + 0x30;
   table[3]= adcx %10 + 0x30;
   Uart1_PutString(p,4);                
   Uart1_PutString("\r\n",2);
   temp =0;
   DMA1->IFCR|=1<<1;
   MYDMA_GOnes(DMA1_Channel1);
   
            } 
  }                
    } 
           
 } 
   
void  adc_init(void)
{    
 RCC->APB2ENR|=1<<2;    //使能PORTA口时钟 
 GPIOA->CRL&=0XFFFFFFF0;//PA.0 anolog输入 
 //通道10/11设置  
 RCC->APB2ENR|=1<<9;    //ADC1时钟使能
 __nop();
 __nop();     
 RCC->APB2RSTR|=1<<9;   //ADC1复位
 RCC->APB2RSTR&=~(1<<9);//复位结束  
 RCC->CFGR|=2<<14;      //SYSCLK/DIV2=72M/6=12Mhz ADCCLK12MHz   
 
 ADC1->CR1&=0XF0FFFF;   //独立工作模式
 ADC1->CR1|=1<<8;       //扫描模式   
 ADC1->CR2|=0<<1;       //单次转换模式 
 ADC1->CR2|=3<<17;     //定时器2 CC2事件控制规则通道转换
 ADC1->CR2|=1<<20;      //用一个事件来触发
 ADC1->CR2&=~(1<<11);   //右对齐
 ADC1->SQR1&=0xFFF0FFFF;//1个转换在规则序列中  
 ADC1->SQR3&=0XFFFFFFE0;//规则序列1=通道0
 ADC1->SQR3|=0;    
 ADC1->SMPR2|=0X07;     //通道0的转换时间为:239.5+12.5个ADC时钟周期    
 ADC1->CR2|=1<<0;       //开启AD转换器,第一次唤醒AD转换器  
 ADC1->CR2|=1<<3;       //使能复位校准  
 while(ADC1->CR2&1<<3); //等待校准结束   
    //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。    
 ADC1->CR2|=1<<2;       //开启AD校准    
 while(ADC1->CR2&1<<2); //等待校准结束
 //该位由软件设置以开始校准,并在校准结束时由硬件清除    
 ADC1->CR2|=1<<8;    //开启ADC DMA转换
 MYDMA_Config(DMA1_Channel1);//配置DMA通道1
 MYDMA_Enable(DMA1_Channel1);//开启DMA通道1 
 ADC1->CR2|=1<<0;    //开启AD转换
}
//获得ADC值
u16 get_adc(void)   
{     
 ADC1->CR2|=1<<22;       //启动规则转换通道 
 while(!(ADC1->SR&1<<1));//等待转换结束      
 return ADC1->DR; //返回adc值         
}
//DMA1的各通道配置
//DMA_CHxMA1的通道 参考手册
void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx)
{
 RCC->AHBENR|=1<<0;//开启DMA1时钟
 __nop();                    //等待 DMA1 时钟稳定
    __nop();                    //经测试最少 2 个 nop
    __nop();
 DMA_CHx->CPAR=ADC1_DR_Address;//DMA1 外设地址 ADC1_DR_Address
 DMA_CHx->CMAR=(u32)ADC_Buf ;   //DMA1,ADC 存储器地址
 DMA_CHx->CNDTR=(u32)sizeof(ADC_Buf) ;  //DMA1,传输数据量
 DMA_CHx->CCR=0X00000000;//复位
 DMA_CHx->CCR|=0<<4;  //从外设器件读数据
 DMA_CHx->CCR|=0<<5;  //非循环模式
 DMA_CHx->CCR|=0<<6;  //外设地址非增量模式
 DMA_CHx->CCR|=1<<7;  //存储器增量模式
 DMA_CHx->CCR|=1<<8;  //外设数据宽度为16位
 DMA_CHx->CCR|=1<<10; //存储器数据宽度16位
 DMA_CHx->CCR|=1<<13; //高优先级
 DMA_CHx->CCR|=0<<14; //非存储器到存储器模式   
}
//开启 DMA传输
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
 DMA_CHx->CCR|=1<<0;  //开启DMA传输
}   
//开启一次DMA传输
//单次DMA转换之后,必须把DMA关闭,再次启动,才能实现第二次DMA传输!!!
void MYDMA_GOnes(DMA_Channel_TypeDef*DMA_CHx)
{   
 DMA_CHx->CCR&=~(1<<0);  //关闭DMA传输
 DMA_CHx->CNDTR=(u32)sizeof(ADC_Buf) ;  //DMA1,传输数据量
 DMA_CHx->CCR|=1<<0;  //开启DMA传输
}
void  USART_Initaize(u32 pclk2,u32 bound)
{
 float temp;
 u16 mantissa;
 u16 fraction;   
 temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
 mantissa=temp;     //得到整数部分
 fraction=(temp-mantissa)*16; //得到小数部分 
    mantissa<<=4;
 mantissa+=fraction;
 RCC->APB2ENR|=1<<2;   //使能PORTA口时钟 
 RCC->APB2ENR|=1<<14;  //使能串口时钟
 GPIOA->CRH&=0XFFFFF00F;
 GPIOA->CRH|=0X000008B0;//IO状态设置
   
 RCC->APB2RSTR|=1<<14;   //复位串口1
 RCC->APB2RSTR&=~(1<<14);//停止复位       
 //波特率设置
  USART1->BRR=mantissa; // 波特率设置 
 USART1->CR1|=0X200C;  //1位停止,无校验位.
#ifdef EN_USART1_RX    //如果使能了接收
 //使能接收中断
 USART1->CR1|=1<<8;    //PE中断使能
 USART1->CR1|=1<<5;    //接收缓冲区非空中断使能      
 MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级
#endif
}
void  Uart1_PutChar(u8 ch)

 USART1->DR = (u8) ch; 
 while((USART1->SR&0X40)==0);//循环发送,直到发送完毕    
}
void Uart1_PutString(u8 *Buf, u8 Len)
{
 u8 i;
 for(i= 0; i<Len; i++)
 {
  Uart1_PutChar(*Buf++);
 }
}
//TIM3 PWM部分
//正点原子@ALIENTEK
//2010/6/2 
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void PWM_Init(u16 arr,u16 psc)
{        
 //此部分需手动修改IO口设置
 RCC->APB1ENR|=1<<1;       //TIM3时钟使能   
 RCC->APB2ENR|=1<<3;    //使能PORTB时钟
// GPIOA->CRH&=0XFFFFFFF0;//PA8输出
// GPIOA->CRH|=0X00000004;//浮空输入
    
 GPIOB->CRL&=0XFFFFFFF0;//PB0输出
 GPIOB->CRL|=0X0000000B;//复用功能输出   
 GPIOB->ODR|=1;//PB0上拉 
 TIM3->ARR=arr;//设定计数器自动重装值
 TIM3->SC=psc;//预分频器
 
 TIM3->CCMR2|=7<<4;  //CH3 PWM2模式  
 TIM3->CCMR2|=1<<4; //CH3预装载使能   
 
 TIM3->CCER|=1<<8;   //OC3 输出使能   
 
 TIM3->CCR3=0X0009;  // 比较寄存器为值18,arr为18
 
 TIM3->CR1=0x0080;   //ARPE使能
 TIM3->CR1|=0x01;    //使能定时器3            
}
  
void PWM4_PULSE_Init(u16 arr1,u16 psc1,u16 arr2,u16 psc2)
{        
 //此部分需手动修改IO口设置
 RCC->APB1ENR|=1;       //TIM2时钟使能
 RCC->APB2ENR|=1<<2;    //使能PORTA时钟   
   RCC->APB1ENR|=1<<2;       //TIM4时钟使能   
    RCC->APB2ENR|=1<<3;    //使能PORTB时钟
 GPIOA->CRL&=0XFFFFFF0F;//PA1输出
 GPIOA->CRL|=0X000000B0;//复用功能输出   
 GPIOA->ODR|=1<<1;//PA1上拉 
 GPIOB->CRL&=0XF0FFFFFF;//PB6输出
    GPIOB->CRL|=0X0B000000;//复用功能输出   
    GPIOB->ODR|=1<<6;//PB6上拉
 
 TIM2->ARR=arr1;//设定计数器自动重装值
 TIM2->SC=psc1;//预分频器
 TIM4->ARR=arr2;//设定计数器自动重装值
    TIM4->SC=psc2;//预分频器不分频
 TIM2->CCMR1|=7<<12;  //CH2 PWM2模式  
 TIM2->CCMR1|=1<<11; //CH2预装载使能   
 TIM4->CCMR1|=7<<4;  //CH1 PWM2模式  
    TIM4->CCMR1|=1<<3; //CH1预装载使能
 TIM2->CCER|=1<<4;   //OC2 输出使能   
 TIM4->CCER|=1;   //OC1 输出使能
 TIM2->CCR2=0X0002;  //
 TIM4->CCR1=0X0009;
 TIM2->CR1=0x0080;   //ARPE使能
 TIM2->CR1|=0x01;    //使能定时器2
 TIM4->CR1=0x0080;   //ARPE使能
    TIM4->CR1|=0x01;    //使能定时器4           
}

void KEY_Init(void)
{
 RCC->APB2ENR|=1<<2;     //使能PORTA时钟
 GPIOA->CRH&=0XFF0FFFFF;//PA13设置成输入  
 GPIOA->CRH|=0X00800000;       
 GPIOA->ODR|=1<<13;    //PA13上拉 
}

 u8 KEY_Scan(void)

 if(KEY0==1)
 {
     delay_ms(10);//去抖动
      return 1;// 无按键按下
      }else if(KEY0==0)
   return 0;
    }


还望大神们指点一下
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-3-18 08:16:00 | 显示全部楼层
回复【8楼】BULELJ:
---------------------------------
主程序里没看到ADC DMA初始化,帖子你没好好看,DMA必须设置成循环模式
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-3-18 08:17:18 | 显示全部楼层
回复【7楼】BULELJ:
---------------------------------
规则转换不是开启了么,这是说不能开始规则转换而已,规则转换由定时器触发
回复 支持 反对

使用道具 举报

10

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2012-12-27
在线时间
0 小时
发表于 2013-3-18 11:18:12 | 显示全部楼层
回复【10楼】tian123chi:
---------------------------------
谢谢,我修改了之后忘了写上去了
回复 支持 反对

使用道具 举报

10

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2012-12-27
在线时间
0 小时
发表于 2013-3-23 20:58:07 | 显示全部楼层
回复【10楼】tian123chi:
回复【7楼】BULELJ: --------------------------------- 规则转换不是开启了么,这是说不能开始规则转换而已,规则转换由定时器触发
---------------------------------
请问楼主,这里的OC事件,是指OC输出电平翻转一次就触发一次吗,还是一个周期触发一次?
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-3-24 20:40:53 | 显示全部楼层
回复【12楼】BULELJ:
---------------------------------
你可以试试的,呵呵~
回复 支持 反对

使用道具 举报

10

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2012-12-27
在线时间
0 小时
发表于 2013-3-25 09:50:33 | 显示全部楼层
回复【13楼】tian123chi:
---------------------------------
......
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-3-25 10:54:32 | 显示全部楼层
回复【14楼】BULELJ:
---------------------------------
....
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-3-25 11:31:25 | 显示全部楼层
回复【楼主位】tian123chi:
---------------------------------
在这张图上终于可以看见所谓的CC1,CC2,CC3,CC4了。所谓的CCX事件,就是指捕获/比较X寄存器的所发生的事件。意思就是说必须得使用 捕获/比较X寄存器才可以产生CCX事件。
这里我使用的是捕获/比较寄存器的PWM输出功能。

这句可否再详细一点。是在捕获/比较X寄存器与CNT寄存器一样,TIM触发事件,同时也就自动触发了ADC?
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-3-26 15:31:21 | 显示全部楼层
回复【16楼】wwjdwy:
---------------------------------
产生CC1,CC2,CC3,CC4事件是不够的,还要让AD知道,那就需要将这些事件输出,就是对应的OC1、OC2等等输出。
回复 支持 反对

使用道具 举报

13

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2012-6-30
在线时间
4 小时
发表于 2013-3-27 20:16:07 | 显示全部楼层
学习了,试了一下成功了,但是采样率不是很高,不知道是不是我哪里设置错了,呵呵
回复 支持 反对

使用道具 举报

2

主题

394

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2115
金钱
2115
注册时间
2012-5-8
在线时间
314 小时
发表于 2013-3-28 13:27:42 | 显示全部楼层
谢谢分享!学习了!
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-3-28 14:56:30 | 显示全部楼层
回复【18楼】koss:
---------------------------------
采样率 由定时器控制,调节pwm占空比即可
回复 支持 反对

使用道具 举报

13

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2012-6-30
在线时间
4 小时
发表于 2013-3-28 21:24:32 | 显示全部楼层
回复【20楼】tian123chi:
---------------------------------
额,采样率应该是由周期决定的吧,一个周期内电平翻转,触发一次采样?
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-3-29 10:35:43 | 显示全部楼层
回复【21楼】koss:
---------------------------------
对,说错了,由周期决定,丢人啊,呜呜~
回复 支持 反对

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2013-3-16
在线时间
7 小时
发表于 2013-4-6 00:47:53 | 显示全部楼层
mark
回复 支持 反对

使用道具 举报

2

主题

394

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2115
金钱
2115
注册时间
2012-5-8
在线时间
314 小时
发表于 2013-4-24 10:37:32 | 显示全部楼层
发个工程吧
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-4-24 12:08:20 | 显示全部楼层
回复【24楼】zuoyi:
---------------------------------
由于直接在项目中实验,不是单独做的,提取需要时间,不好意思~勉强看看吧
回复 支持 反对

使用道具 举报

105

主题

522

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1386
金钱
1386
注册时间
2012-10-23
在线时间
97 小时
发表于 2013-6-21 22:43:30 | 显示全部楼层
l楼主快出来指点一下啊
回复 支持 反对

使用道具 举报

4

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
110
金钱
110
注册时间
2013-3-21
在线时间
0 小时
发表于 2013-8-11 23:27:18 | 显示全部楼层
好贴
回复 支持 反对

使用道具 举报

28

主题

190

帖子

0

精华

高级会员

Rank: 4

积分
758
金钱
758
注册时间
2012-8-23
在线时间
71 小时
发表于 2013-8-30 20:58:11 | 显示全部楼层
顶一个~
回复 支持 反对

使用道具 举报

1

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2013-9-3
在线时间
0 小时
发表于 2013-9-9 10:31:40 | 显示全部楼层
回复【16楼】wwjdwy:
---------------------------------
如果是CNT==CRR相等的时候触发ADC转换,那么在PWM波中每个周期的占空比都变化,岂不是ADC的转换频率也在变化??只有在PWM波占空比一定的时候,ADC的转换周期才一直与之相等!这样理解对不对?
回复 支持 反对

使用道具 举报

1

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2013-9-3
在线时间
0 小时
发表于 2013-9-9 10:32:32 | 显示全部楼层
回复【22楼】tian123chi:
---------------------------------
由占空比决定的吧
回复 支持 反对

使用道具 举报

19

主题

199

帖子

0

精华

高级会员

Rank: 4

积分
512
金钱
512
注册时间
2012-11-18
在线时间
72 小时
发表于 2013-9-11 15:35:12 | 显示全部楼层
楼主用的CCx(x=1,2,3)比较输出来触发ADC,问题来了,我触发ADC的时候,有个GPIO在那里产生方波,而那个引脚我刚好要用作其他的功能.岂不是浪费了.



用TIM3的TRGO来触发ADC是不是更好呢?他们之间内部就能解决.
回复 支持 反对

使用道具 举报

33

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
280
金钱
280
注册时间
2013-6-18
在线时间
15 小时
发表于 2013-9-11 17:12:19 | 显示全部楼层
回复【楼主位】tian123chi:
----------回复【楼主位】tian123chi:
我当时也有这样的疑问,只知道溢出事件,更新事件是什么。疑惑了好久,之后看到之后看到了这么一张图。
在这张图上终于可以看见所谓的CC1,CC2,CC3,CC4了。所谓的CCX事件,就是指捕获/比较X寄存器的所发生的事件。意思就是说必须得使用 捕获/比较X寄存器才可以产生CCX事件。......
---------------------------------
楼主说只要产生CCX事件即可触发ADC进行转换,从图上来看,产生CCX事件后同过输出控制器输出到外部的引脚上,
TIM2 CC2的引脚在PA1上这岂不是在说用CC2触发是不是就不能进行ADC-CH1的转换了吗?
后来我吧TIM2->CCER|=1<<4;     //OC2 输出使能去掉了,就是产生CCX事件不输出(我是这样理解的),这时ADC-CH0,就不转换了,
不知道上面情况!问有没有上面方法用Tim2——CC2触发同时有能对ADC—CH1进行转换(CC2/ADC_CH1在同一引脚上)
一知半解!
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-9-12 14:52:10 | 显示全部楼层
回复【32楼】liawei123:
---------------------------------
TIM2 CC2的引脚在PA1上,这句话怎么理解?
回复 支持 反对

使用道具 举报

33

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
280
金钱
280
注册时间
2013-6-18
在线时间
15 小时
发表于 2013-9-16 11:37:56 | 显示全部楼层
你是用 TIM2——CH2输出PWM触发ADC进行转换吧,转换通道位ADC0(PA0),
我想说的是你吧ADC0通道如果改成ADC1(PA1),还是用TIM2-CH2,产生PWM进行触发!
这是就又个问题了TIM2-CH2/ADC1/PA1这几个脚是复用的吧,那么怎么样进行设置?。有没有试过!



看图来说,产生CC2I是不用控制输出的(不产生PWM),也就是不输出,但是我试过好像不行,不输出就不转换了!
不知道你试过没!
一知半解!
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-9-21 14:42:32 | 显示全部楼层
回复【34楼】liawei123:
---------------------------------
TIM-CH2只是在内部工作 不牵涉IO管脚,我总共用了 0-7 8个通道,没有任何冲突。
回复 支持 反对

使用道具 举报

1

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2013-9-3
在线时间
0 小时
发表于 2013-10-17 22:48:08 | 显示全部楼层
回复【楼主位】tian123chi:
-----------------------------
有个疑问想请教一下:这里ADC设置为单次转换、扫描模式。假设有5路AD通道转换。当TIM2上升沿的时候触发开始ADC转换,每个EOC均触发DMA来搬运数据。DMA设置为循环操作,比如设置COUNT=5,那即使搬运了5个数据,那只要有EOC,DMA又会重新搬运(COUNT自动重新赋值为5)。我的问题是:ADC什么时候停止转换?难道是TIM2的高电平期间,设置为D?转换的次数为N,取决于设置的采样时间T,次数:N = D / (T*5) 。这个对不对?
回复 支持 反对

使用道具 举报

1

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2013-9-3
在线时间
0 小时
发表于 2013-10-17 22:48:34 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
有个疑问想请教一下:这里ADC设置为单次转换、扫描模式。假设有5路AD通道转换。当TIM2上升沿的时候触发开始ADC转换,每个EOC均触发DMA来搬运数据。DMA设置为循环操作,比如设置COUNT=5,那即使搬运了5个数据,那只要有EOC,DMA又会重新搬运(COUNT自动重新赋值为5)。我的问题是:ADC什么时候停止转换?难道是TIM2的高电平期间,设置为D?转换的次数为N,取决于设置的采样时间T,次数:N = D / (T*5) 。这个对不对?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-10-17 23:46:38 | 显示全部楼层
回复【37楼】逆流而上901458:
---------------------------------
我也没做过这种应用,不知道哦,不好意思。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2013-9-3
在线时间
0 小时
发表于 2013-10-18 08:35:16 | 显示全部楼层
回复【38楼】正点原子:
---------------------------------
没关系,还是很感谢你的回复!
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-10-18 12:55:57 | 显示全部楼层
回复【37楼】逆流而上901458:
---------------------------------
ADC停止转换?ADC只是由定时器触发而已,停止时间是由ADC转换时间控制的。后面一句话就看不懂什么意思了
回复 支持 反对

使用道具 举报

1

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2013-9-3
在线时间
0 小时
发表于 2013-10-21 16:58:39 | 显示全部楼层
回复【40楼】tian123chi:
---------------------------------
如果说TIM2定时100us,设置占空比为20%。设:低电平80us,高电平20us。ADC在第81us处开始转换,假设AD采样时间一共是100us,那下一个周期的触发AD的时候,上一次还没结束呢!
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2013-10-28 09:36:05 | 显示全部楼层
回复【41楼】逆流而上901458:
---------------------------------
那只有降低采样时间咯,或定时加长了。
回复 支持 反对

使用道具 举报

8

主题

76

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
264
金钱
264
注册时间
2013-9-5
在线时间
31 小时
发表于 2014-3-29 20:58:25 | 显示全部楼层
学习记号备用!
回复 支持 反对

使用道具 举报

27

主题

259

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
387
金钱
387
注册时间
2014-8-19
在线时间
0 小时
发表于 2014-10-22 15:35:07 | 显示全部楼层
回复【11楼】BULELJ:
---------------------------------
解决了吗?
回复 支持 反对

使用道具 举报

8

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2013-11-29
在线时间
7 小时
发表于 2014-10-31 10:51:01 | 显示全部楼层
楼主你好,我现在做的实验需要stm32进行高速的AD转换,转换速度为250KHz,这样每次转换完成后,如何读取数值?
回复 支持 反对

使用道具 举报

8

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2013-11-29
在线时间
7 小时
发表于 2014-10-31 15:24:16 | 显示全部楼层
大神能留下你的联系方式么?
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
 楼主| 发表于 2014-11-11 20:36:21 | 显示全部楼层
回复【46楼】程序猿:
---------------------------------
去年搞的了~今年主要搞了DSP~现在又要用STM32了,所以又回来了,当时项目完成了,现在又记不得了~
你的问题是如何读取数值?
这个很好解决,建立数组,DMA传过去即可,需要时再调用,如果数据比较,就挂个RAM就是了
回复 支持 反对

使用道具 举报

11

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2015-7-6
在线时间
5 小时
发表于 2015-8-10 15:15:41 | 显示全部楼层
感谢分享!!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-18 18:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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