5032|10

69

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请问一个问题关于定时采样的,谢谢 [复制链接]

如果我想把采样率设在20K
我想有一下办法:
1:用定时器作为DMA触发源,频率20K,触发一次,把数据从ADC中放入内存。

2:用ADC作为DMA触发源 但是ADC触发源使用定时器。

再一个 我看到ADC1有一个TIM1_DCR TIM1_DMAR 这个貌似和DMA相关 请问是个啥东东啊 谢谢!
此帖出自stm32/stm8论坛

最新回复

                                 以下是我的配置,你参考一下///////////////////////////////////////////////////////////////////*************************************************************    函数名        Timer4_Configurate    功能        定时器4的配置函数    输入参数    unSampRate    每个周波的采样点数    输出参数    无    变量        无*************************************************************/void Timer4_Configurate(UINT16 unSampRate){    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;     TIM_OCInitTypeDef TIM_OCInitStructure;         switch(unSampRate)    {        case 16:    unSampRate = 5000;    break;        case 20:    unSampRate = 4000;    break;        case 32:    unSampRate = 2500;    break;        case 64:    unSampRate = 1250;    break;        case 128:    unSampRate = 625;    break;        default:    unSampRate = 0xFFFF;    }            RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE);            // 使能各个功能模块的的时钟    TIM_DeInit(TIM4);        // 配置时间基    if(unSampRate == 0xFFFF)    {    // 测试下的设置    // 72,000,000 / 7200 / 4 = 2500Hz    // 因此最后的时钟就完全由TIM_Period决定,    TIM_TimeBaseStructure.TIM_Period = 250-1;    TIM_TimeBaseStructure.TIM_Prescaler = 7199;    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV4;    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);    }else    {    TIM_TimeBaseStructure.TIM_Period = unSampRate-1;                // 周期        TIM_TimeBaseStructure.TIM_Prescaler = 18-1;                        // 预分频    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;            // 输入时钟1分频,72MHz/1, 时基输出频率=72/18=4MHz    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;        // 向上递增模式    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);    }    // 通道4:输出比较模式    TIM_OCInitStructure.TIM_OCMode = TIM1_OCMode_PWM1;     TIM_OCInitStructure.TIM_Channel = TIM_Channel_4;     TIM_OCInitStructure.TIM_Pulse = 10;     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;     TIM_OCInit(TIM4, &TIM_OCInitStructure);    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);        // 使能定时器4    TIM_Cmd(TIM4, ENABLE);    }/*************************************************************    函数名        ADC_Configrate    功能        ADC模块配置    输入参数    无    输出参数    无    变量        无*************************************************************/void ADC_Configrate(void){    GPIO_InitTypeDef GPIO_InitStructure;    ADC_InitTypeDef ADC_InitStructure;    DMA_InitTypeDef DMA_InitStructure;    NVIC_InitTypeDef NVIC_InitStructure;    ////////////////////////////////////////////////////////    // 配置定时器4,使之能够根据采样率的要求产生定时中断    // 并触发ADC模块的运行    Timer4_Configurate(ADSAMPIONT);    //Timer4_Configurate(0);    // 配置ADC的中断向量    NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQChannel;    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    NVIC_Init(&NVIC_InitStructure);    ////////////////////////////////////////////////////////    // DMA 通道1配置    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);                        // 使能DMA的时钟    DMA_DeInit(DMA_Channel1);                                                // 复位    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;                // 外围设备的基址    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&tAD_Cur;                    // 存储空间的基址    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                        // 方向:外围->内存    DMA_InitStructure.DMA_BufferSize = ADC_CONVNUM;                            // 传输的数目    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;        // 外围设备地址不增加    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                    // 内存空间地址加1    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;    // 外围设备的字长    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;            // 内存空间的字长    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                            // 模式:循环缓冲    DMA_InitStructure.DMA_Priority = DMA_Priority_High;                        // 优先级:高    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                            // 没有使用内存到内存方式    DMA_Init(DMA_Channel1, &DMA_InitStructure);    DMA_Cmd(DMA_Channel1, ENABLE);                                            // 使能DMA通道1    ////////////////////////////////////////////////////////    // 模拟量输入管脚的配置    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                    // 时钟    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3;            // 选中的管脚    //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;    GPIO_Init(GPIOA, &GPIO_InitStructure);    ////////////////////////////////////////////////////////    // ADC配置    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2, ENABLE);// 时钟    ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;    ADC_InitStructure.ADC_ScanConvMode = ENABLE;    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4;    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;    ADC_InitStructure.ADC_NbrOfChannel = ADC_CONVNUM;// 进行规则转换的ADC通道的数目。这个数目的取值范围是1到16    ADC_Init(ADC1, &ADC_InitStructure);            // ADC1初始化    ADC_Init(ADC2, &ADC_InitStructure);            // ADC2初始化        ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_1Cycles5);    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_1Cycles5);        ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_1Cycles5);    ADC_RegularChannelConfig(ADC2, ADC_Channel_0, 2, ADC_SampleTime_1Cycles5);        ADC_Cmd(ADC1, ENABLE);                        // 使能ADC1    ADC_ResetCalibration(ADC1);                    // 复位ADC1的校准寄存器    while(ADC_GetResetCalibrationStatus(ADC1));    // 等待检测校准过程完成    ADC_StartCalibration(ADC1);                    // 开始校准各个通道    while(ADC_GetCalibrationStatus(ADC1));        // 等待校准过程完成    ADC_Cmd(ADC2, ENABLE);                        // 使能ADC2    ADC_ResetCalibration(ADC2);                    // 复位ADC2的校准寄存器    while(ADC_GetResetCalibrationStatus(ADC2));    // 等待检测校准过程完成    ADC_StartCalibration(ADC2);                    // 开始校准各个通道    while(ADC_GetCalibrationStatus(ADC2));        // 等待校准过程完成    ADC_ExternalTrigConvCmd(ADC1, ENABLE);        // 采用外部触发方式启动(目前采用定时器4的CC4)    ADC_ExternalTrigConvCmd(ADC2, ENABLE);        // 采用外部触发方式启动(目前采用定时器4的CC4)    ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);        // 使能EOC中断    ADC_DMACmd(ADC1, ENABLE);                    // 使能ADC1的DMA功能}   详情 回复 发表于 2009-3-23 11:03
点赞 关注
 

回复
举报

68

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

这应该没有问题!

你可以用定时器的PWM输出作为ADC的触发输入,实现20K采样,

另外设置ADC模块的DMA使能,使之AD转换结束之后,直接由DMA把数据搬移到内存;
此帖出自stm32/stm8论坛
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

您说 使用PWM作为触发 那么需要在外部连线吧?

好想ADC可以直接使用内部的TIM的信号触发吧。。。
DMA貌似都要用到
此帖出自stm32/stm8论坛
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

4
 

不需要外部连线,内部处理的

                                 不需要外部连线,内部处理的
此帖出自stm32/stm8论坛
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

5
 

很奇怪 AD采数据后 通过DMA后 丢失一半的数据 这是为啥呢?

很奇怪 AD采数据后 通过DMA后 丢失一半的数据 这是为啥呢?

此帖出自stm32/stm8论坛
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

6
 

丢失一半的数据?当然是你的设置有问题

                                 不为啥~~~~
此帖出自stm32/stm8论坛
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

7
 

香版主,麻烦您看看我的配置 我用的库

 
   /* ADC1 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode =ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel10 configuration */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5);

  /* Enable ADC1 DMA */
   ADC_DMACmd(ADC1, ENABLE);

  
  /* Enable ADC1 */
   ADC_Cmd(ADC1, ENABLE);

  /* Enable ADC1 reset calibaration register */   
  ADC_ResetCalibration(ADC1);
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibaration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));
     
  /* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
 
 
 
  /* DMA1 channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADCConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 512;
  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_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  
  /* Enable DMA1 channel1 */
   DMA_Cmd(DMA1_Channel1, ENABLE);
此帖出自stm32/stm8论坛
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

8
 

解决了!!

是KEIL的问题
换IAR后正常
莫非是KEIL的BUG 还是STLINK2和KEIL不兼容呢?
打算入手JLINK
此帖出自stm32/stm8论坛
 
 
 

回复

91

帖子

0

TA的资源

一粒金砂(初级)

9
 

keil应该没有问题

                                 keil应该没有问题,我就是在Keil下进行的做的
此帖出自stm32/stm8论坛
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

10
 

同样的程序 我在IAR下OK

同样的程序 我在IAR下OK
在KEIL下 不行。见鬼了。。。

楼上的朋友 您也做过和我类似的东西?您在KEIL下 正常么? 可以看看您的配置么
此帖出自stm32/stm8论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

11
 

我做过

以下是我的配置,你参考一下

//////////////////////////////////////////////////////////////////
/*
************************************************************
    函数名        Timer4_Configurate
    功能        定时器4的配置函数
    输入参数    unSampRate    每个周波的采样点数
    输出参数    无
    变量        无
************************************************************
*/
void Timer4_Configurate(UINT16 unSampRate)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
    TIM_OCInitTypeDef TIM_OCInitStructure; 
    
    switch(unSampRate)
    {
        case 16:    unSampRate = 5000;    break;
        case 20:    unSampRate = 4000;    break;
        case 32:    unSampRate = 2500;    break;
        case 64:    unSampRate = 1250;    break;
        case 128:    unSampRate = 625;    break;
        default:    unSampRate = 0xFFFF;
    }
        
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE);            // 使能各个功能模块的的时钟
    TIM_DeInit(TIM4);
    
    // 配置时间基
    if(unSampRate == 0xFFFF)
    {
    // 测试下的设置
    // 72,000,000 / 7200 / 4 = 2500Hz
    // 因此最后的时钟就完全由TIM_Period决定,
    TIM_TimeBaseStructure.TIM_Period = 250-1;
    TIM_TimeBaseStructure.TIM_Prescaler = 7199;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV4;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
    }else
    {
    TIM_TimeBaseStructure.TIM_Period = unSampRate-1;                // 周期    
    TIM_TimeBaseStructure.TIM_Prescaler = 18-1;                        // 预分频
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;            // 输入时钟1分频,72MHz/1, 时基输出频率=72/18=4MHz
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;        // 向上递增模式
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
    }

    // 通道4:输出比较模式
    TIM_OCInitStructure.TIM_OCMode = TIM1_OCMode_PWM1; 
    TIM_OCInitStructure.TIM_Channel = TIM_Channel_4; 
    TIM_OCInitStructure.TIM_Pulse = 10; 
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; 
    TIM_OCInit(TIM4, &TIM_OCInitStructure);
    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
    
    // 使能定时器4
    TIM_Cmd(TIM4, ENABLE);    
}

/*
************************************************************
    函数名        ADC_Configrate
    功能        ADC模块配置
    输入参数    无
    输出参数    无
    变量        无
************************************************************
*/
void ADC_Configrate(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    ////////////////////////////////////////////////////////
    // 配置定时器4,使之能够根据采样率的要求产生定时中断
    // 并触发ADC模块的运行
    Timer4_Configurate(ADSAMPIONT);
    //Timer4_Configurate(0);

    // 配置ADC的中断向量
    NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    ////////////////////////////////////////////////////////
    // DMA 通道1配置
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);                        // 使能DMA的时钟
    DMA_DeInit(DMA_Channel1);                                                // 复位
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;                // 外围设备的基址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&tAD_Cur;                    // 存储空间的基址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                        // 方向:外围->内存
    DMA_InitStructure.DMA_BufferSize = ADC_CONVNUM;                            // 传输的数目
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;        // 外围设备地址不增加
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                    // 内存空间地址加1
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;    // 外围设备的字长
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;            // 内存空间的字长
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                            // 模式:循环缓冲
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;                        // 优先级:高
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                            // 没有使用内存到内存方式
    DMA_Init(DMA_Channel1, &DMA_InitStructure);
    DMA_Cmd(DMA_Channel1, ENABLE);                                            // 使能DMA通道1

    ////////////////////////////////////////////////////////
    // 模拟量输入管脚的配置
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                    // 时钟
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3;            // 选中的管脚
    //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ////////////////////////////////////////////////////////
    // ADC配置
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2, ENABLE);// 时钟

    ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = ADC_CONVNUM;// 进行规则转换的ADC通道的数目。这个数目的取值范围是1到16
    ADC_Init(ADC1, &ADC_InitStructure);            // ADC1初始化
    ADC_Init(ADC2, &ADC_InitStructure);            // ADC2初始化
    
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_1Cycles5);    

    ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_0, 2, ADC_SampleTime_1Cycles5);

    
    ADC_Cmd(ADC1, ENABLE);                        // 使能ADC1
    ADC_ResetCalibration(ADC1);                    // 复位ADC1的校准寄存器
    while(ADC_GetResetCalibrationStatus(ADC1));    // 等待检测校准过程完成
    ADC_StartCalibration(ADC1);                    // 开始校准各个通道
    while(ADC_GetCalibrationStatus(ADC1));        // 等待校准过程完成

    ADC_Cmd(ADC2, ENABLE);                        // 使能ADC2
    ADC_ResetCalibration(ADC2);                    // 复位ADC2的校准寄存器
    while(ADC_GetResetCalibrationStatus(ADC2));    // 等待检测校准过程完成
    ADC_StartCalibration(ADC2);                    // 开始校准各个通道
    while(ADC_GetCalibrationStatus(ADC2));        // 等待校准过程完成

    ADC_ExternalTrigConvCmd(ADC1, ENABLE);        // 采用外部触发方式启动(目前采用定时器4的CC4)
    ADC_ExternalTrigConvCmd(ADC2, ENABLE);        // 采用外部触发方式启动(目前采用定时器4的CC4)
    ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);        // 使能EOC中断
    ADC_DMACmd(ADC1, ENABLE);                    // 使能ADC1的DMA功能
}
此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表