stm32 TIM2定时器触发ADC、DMA采样

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangyachao0803/article/details/82254365

        使用ADC的定时器触发ADC转换的功能,然后使用DMA进行数据的搬运!采用TIM2定时器的触发间隔,实现ADC定时采样转换的功能,然后可以在程序的死循环中一直检测DMA转换完成标志,然后进行数据的读取,或者使能DMA转换完成中断,这样每次转换完成就会产生中断。 

        做示波器时,由于要做调整横坐标显示倍数增大和缩小,故需要改变采样频率,也就是改变TIM2 的定时器时间间隔,在TIM2初始化函数定义时,添加u16 Value参数,第一次调试时,设置如下:

  • 定时器2初始化函数void TIM2_Configuration(u16 Value),配置TIM_Period = Value - 1;

            TIM_TimeBaseStructure.TIM_Period = Value - 1;//设置2ms一次TIM2比较的周期(注意此处!!!)
            TIM_TimeBaseStructure.TIM_Prescaler = 1;//系统主频56M,这里2分频 (注意此处!!!)

  • DMA配置:

            DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;//内存存储基地址
            DMA_InitStructure.DMA_BufferSize = 2000;//DMA缓存大小,2000个

  •  ADC配置:

            ADC_InitStructure.ADC_ScanConvMode =DISABLE;//关闭扫描模式 因为只有一个通道
            ADC_InitStructure.ADC_ContinuousConvMode =DISABLE;//关闭连续转换模式 否则只要触发一次,后续的转换就会永不停歇(除非CONT清0),这样第一次以后的ADC,就不是由TIM2_CC2来触发了
            ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;//软件转换模式  

       示波器中为防止波形频闪,需要用到触发电平。想让触发点定在屏幕中间,在第一次上电触发脉冲到来时,需要DMA中有至少半屏的数据,若半屏为240个点,则另外需要一个定时器来控制这个时间,采用TIM4,设置如下:

           TIM_TimeBaseStructure.TIM_Period = 240*Value -1;     //240个点的定时时间   (注意此处!!!)
           TIM_TimeBaseStructure.TIM_Prescaler = 1;         //系统主频56M,这里2分频 (注意此处!!!)

        当TIM2定时时间到,使能触发中断。当触发脉冲到来时,记下当前位置,即为触发位置。禁能触发中断并再次启动定时器,采集另外240个点。从上述位置左右各取240个点,显示在屏幕上即可;

  • 遇到的问题:

        1、在调整Value值来改变TIM2的时间间隔,240个点的定时时间出错,理论上在进入TIM4的中断时,应采样240多个点(比如为140时,采样242个点),但是Value为280时,才7个点。

        分析:

        通过查看TIM_Period的数据类型发现,其为u16,即unsigned short,范围为0-65536,当Value为280时,TIM4的TIM_Period为67200,超过了u16的范围,实际设置的TIM_Period值为1664-1。

扫描二维码关注公众号,回复: 3212075 查看本文章
  • TIM4的时间间隔:

      ((1+TIM_Prescaler )/56M)*(1+TIM_Period )=((1+1)/56M)*(1+1664-1)=59.4us 

  • 采样周期:

      ((1+TIM_Prescaler )/56M)*(1+TIM_Period )=((1+1)/56M)*(1+280-1)=10us 

通过以上计算,发现Value为280时,为6采样周期,与7个点的时间相差无几,终于找出问题所在;

        解决:

        由于定时器的分频TIM_Prescaler 设置的比较小,TIM4的TIM_Period 又做了240的乘数,想要增大定时器时间间隔,使得Value很容易超范围,可将TIM_Prescaler设置为19,采样周期为10us(即定时器TIM2时间间隔),Value只需设置为28即可。

       2、以上是Value过大时出现的问题,但当Value比较小时,还是在原来的TIM设置条件下,TIM_Prescaler  = 1,当Value小于28时,当TIM4定时时间到时,只采集了100多个点。

        分析:        

        ADC转换就是输入模拟的信号量,单片机转换成数字量。读取数字量必须等转换完成后,完成一个通道的读取叫做采样周期。采样周期一般来说=转换时间+读取时间。而转换时间=采样时间+12.5个时钟周期。

        CPU的频率为56MHz ,ADC取4分频,即为14MHz,则ADC总转换时间为:TCONV = 1.5 + 12.5 = 14周期= 14/14M = 1μs

        故采一个点的时间理论上略大于1us,而在Value设置为28时,TIM2的时间间隔正好为1us,导致240us实际采集的点数比较少,通过多次试验,修改Value的值,发现当取值为32是正好采样正确,为31时则不行,通过计算为1.1us,故需要设置TIM2的采样间隔大于此数值即可。

猜你喜欢

转载自blog.csdn.net/wangyachao0803/article/details/82254365