STM32定时触发ADC、DMA采样 源程序

[复制链接]
查看4 | 回复0 | 2020-6-5 10:14:14 | 显示全部楼层 |阅读模式
采用stm32f1开发板,使用ADC的定时器触发ADC转换的功能,然后使用DMA进行数据的搬运。采用TIM2定时器的触发间隔,实现ADC定时采样转换的功能,然后可以在程序的死循环中一直检测DMA转换完成标志,然后进行数据的读取,或者使能DMA转换完成中断,这样每次转换完成就会产生中断。

完整源码: 定时器触发ADC实验.7z (221.91 KB, 售价: 1 工控币)
## 定时器2初始化函数
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
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(TIM2, &TIM_TimeBaseStructure);   //根据指定的参数初始化TIMx的时间基数单位

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //选择定时器模式:TIM脉冲宽度调制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 1000;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;  //输出极性:TIM输出比较极性低
TIM_OC2Init(TIM2, & TIM_OCInitStructure);  //初始化外设TIM2_CH2
TIM_Cmd(TIM2, ENABLE);    //使能TIMx
TIM_CtrlPWMOutputs(TIM2, ENABLE);

## DMA配置
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);      //使能ADC1通道时钟

DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;    //ADC1地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;   //内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;     //方向(从外设到内存)
DMA_InitStructure.DMA_BufferSize = 1;       //传输内容的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;   //外设地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;    //内存地址固定
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord ; //外设数据单位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord ;    //内存数据单位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular  ;   //DMA模式:循环传输
DMA_InitStructure.DMA_Priority = DMA_Priority_High ;   //优先级:高
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;     //禁止内存到内存的传输
DMA_Init(DMA1_Channel1, &DMA_InitStructure);  //配置DMA1

DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);  //使能传输完成中断

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

DMA_Cmd(DMA1_Channel1,ENABLE);

## GPIO配置
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   //使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);  
## ADC初始化
ADC_InitTypeDef ADC_InitStructure;

TIM2_Init(30000,7199);  //72000000/7200=10000Hz,每3s采集一次
DMA1_Init();
ADC_GPIO_Configuration();  
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);   //使能ADC1通道时钟

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;    //独立ADC模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;     //关闭扫描方式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;   //关闭连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;    //使用外部触发模式
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;    //采集数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1;    //要转换的通道数目
ADC_Init(ADC1, &ADC_InitStructure);
  ## 注意事项
一定要在程序最前面定义ADC的采样数据和地址
    volatile uint16_t ADC_ConvertedValue;   //ADC采样的数据
    #define ADC1_DR_Address    ((u32)0x4001244C)  //ADC1的地址

回复

使用道具 举报

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

本版积分规则