历史上的今天

今天是:2024年10月06日(星期日)

2018年10月06日 | STM32F407ADC多通道+定时器触发+DMA模式设置

发布者:数字驿站 来源: eefocus关键字:STM32F407A  DC多通道  定时器触发  DMA模式 手机看文章 扫描二维码
随时随地手机看文章

#include "adc.h"

u8 UpdataTIM = 0;        //更新TIM2定时器标志

u16 CurrentFreq = 500;//默认市电频率,单位为0.1hz

ADBASE_TYPE uAD_Buff_A[ADC_CHANNEL];        //ADC采集缓存A

ADBASE_TYPE uAD_Buff_B[ADC_CHANNEL];        //ADC采集缓存B

//考虑到可能出现的数据处理时间较长的问题,临时添加缓存

//u16 uAD_IN_BUFF[ADC_BUFFSIZE][ADC_CHANNEL];

ADBASE_TYPE *CurrentBuffPtr = NULL;        //当前缓存指针

static void ADCInit_GPIO(void)

{

    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟

    //ADC通道初始化

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|  \

                                    GPIO_Pin_9|GPIO_Pin_10; //PF3,PF4,PF5,PF6,PF7,PF8,PF9,PF10 ADC通道

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;  //模拟输入

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //不带上下拉

    GPIO_Init(GPIOF, &GPIO_InitStructure);  //初始化     

}

static void ADCInit_ADC(void)

{

    ADC_CommonInitTypeDef ADC_CommonInitStructure;

    ADC_InitTypeDef       ADC_InitStructure;

    

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); //使能ADC3时钟

    

    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE);      //ADC3复位

    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE); //复位结束     

    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式

    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟5个时钟(三重模式或双重模式下使用)

    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能(对于多个ADC模式)

    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz 

    ADC_CommonInit(&ADC_CommonInitStructure);//初始化

    

    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式

    ADC_InitStructure.ADC_ScanConvMode = ENABLE;//扫描模式(多通道ADC采集要用扫描模式)    

    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换

//    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //软件触发

    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; //上升沿触发

    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;  //定时器事件2触发ADC

    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐    

    ADC_InitStructure.ADC_NbrOfConversion = ADC_CHANNEL;    //8个转换在规则序列中

    ADC_Init(ADC3, &ADC_InitStructure);//ADC初始化

    

    //连续模式下,通道的配置

    ADC_RegularChannelConfig(ADC3, ADC_Channel_9, 1, ADC_SampleTime_15Cycles);  //PF3,VIN1,通道9,UA,rank=1,表示连续转换中第一个转换的通道,采样时间15个周期(如果数据不稳定可以延时采样时间)

    ADC_RegularChannelConfig(ADC3, ADC_Channel_14, 2, ADC_SampleTime_15Cycles); //PF4,VIN2,通道14,UB

    ADC_RegularChannelConfig(ADC3, ADC_Channel_15, 3, ADC_SampleTime_15Cycles); //PF5,VIN3,通道15,AC220

    ADC_RegularChannelConfig(ADC3, ADC_Channel_4, 4, ADC_SampleTime_15Cycles);     //PF6,VIN4,通道4,I0

    ADC_RegularChannelConfig(ADC3, ADC_Channel_5, 5, ADC_SampleTime_15Cycles);     //PF7,VIN5,通道5,IA

    ADC_RegularChannelConfig(ADC3, ADC_Channel_6, 6, ADC_SampleTime_15Cycles);     //PF8,VIN6,通道6,IB

    ADC_RegularChannelConfig(ADC3, ADC_Channel_7, 7, ADC_SampleTime_15Cycles);     //PF9,VIN7,通道7,IC

    ADC_RegularChannelConfig(ADC3, ADC_Channel_8, 8, ADC_SampleTime_15Cycles);     //PF10,VIN8,通道8,暂时未接入信号

    ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE); //连续使能DMA

    ADC_DMACmd(ADC3, ENABLE);  //使能ADC_DMA

    ADC_Cmd(ADC3, ENABLE);//开启AD转换器    

}

static void ADCInit_DMA(void)

{

    DMA_InitTypeDef  DMA_InitStructure;

    

    //时钟

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

    

    //DMA设置

    DMA_InitStructure.DMA_Channel = DMA_Channel_2; //选择通道号

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC3->DR); //外围设备地址,ADC_DR_DATA规则数据寄存器

    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(u16 *)uAD_Buff_A; //DMA存储器地址,自己设置的缓存地址

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //传输方向,外设->存储器

    DMA_InitStructure.DMA_BufferSize = ADC_BUFFSIZE * ADC_CHANNEL; //DMA缓存大小,数据传输量32*8

    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设是否为增量模式

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器是否为增量模式

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据长度半个字(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_FIFOMode = DMA_FIFOMode_Disable; //不使用FIFO

    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; //FIFO阈值

    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发,单次传输

    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发,单次传输

    DMA_Init(DMA2_Stream0, &DMA_InitStructure); //初始化DMA2_Stream0,对应为ADC3

    //双缓冲模式设置

    DMA_DoubleBufferModeConfig(DMA2_Stream0,(uint32_t)(u16 *)(uAD_Buff_B),DMA_Memory_0);    //DMA_Memory_0首先被传输

    DMA_DoubleBufferModeCmd(DMA2_Stream0,ENABLE);

    

    //设置DMA中断

    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TC); //清除中断标志   

    DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); //传输完成中断                                       

    DMA_Cmd(DMA2_Stream0, ENABLE); //使能DMA

    

}

void ADCInit_Timer(void)

{

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    //时钟

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);          

    //失能定时器

    TIM_Cmd(TIM2, DISABLE);

    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); //初始化定时器

    

    //定时器设置,T=(84 * 625) / 84M = 625us = 20ms/32,50Hz信号,每周期采样32个点,采样频率1600

    TIM_TimeBaseStructure.TIM_Prescaler = 84-1; //分频系数,TIM2时钟在分频系数不为1时,时钟是APB1时钟的两倍84M

    TIM_TimeBaseStructure.TIM_Period = 312500/CurrentFreq - 1; //周期值1M/32=31250,CurrentFreq单位为0.1hz,因此需扩大10倍

    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频因子

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up ; //向上计数模式

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定时器2

    

    //使能定时器中断    

    TIM_ARRPreloadConfig(TIM2, ENABLE); //允许TIM2定时重载

    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);  //选择TIM2的UPDATA事件更新为触发源

//    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //配置TIM2中断类型

    

    //使能TIM2

    TIM_Cmd(TIM2, ENABLE); 

    DebugLog("Enable TIM2, Set frequency is %d.", CurrentFreq);

}

static void ADCInit_Nvic(void)

{

    NVIC_InitTypeDef NVIC_InitStructure;

    

    //定时器中断设置

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //定时器TIM2中断通道

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;  //抢占优先级0

    NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;        //子优先级1

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能

    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化NVIC寄存器    

    

    //DMA中断设置

    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;  //DMA2_Stream0中断

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;  //抢占优先级1

    NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;        //子优先级1

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能

    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化NVIC寄存器    

}

                                                           

void ADCInit(void)

{

    ADCInit_GPIO();

    ADCInit_DMA();

    ADCInit_ADC();

    ADCInit_Nvic();

    DebugLog("ADC Init is finish.");

}    

void TIM2_IRQHandler(void)  

{

  OSIntEnter(); //进入中断    

    

    if(TIM_GetITStatus(TIM2, TIM_IT_Update))  //判断发生update事件中断  

    {         

        TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除update事件中断标志

//    ADC_SoftwareStartConv(ADC1);      

    }

    

    OSIntExit();  //退出中断  

}

void DMA2_Stream0_IRQHandler(void)  

{

    u16 period = 0;

    

  OSIntEnter(); //进入中断 

    if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))  //判断DMA传输完成中断  

    {

         DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);

//         DMA_Cmd(DMA2_Stream0, ENABLE); //使能DMA,连续模式下不需要该使能

         //数据转移程序

         if(DMA_GetCurrentMemoryTarget(DMA2_Stream0) == DMA_Memory_0)

         {

             CurrentBuffPtr = uAD_Buff_A;

         }

         else

         {

             CurrentBuffPtr = uAD_Buff_B;

         }

         //遥测任务等待该信号量

         OSSemPost(SemAD);

         

         //判断是否更新TIM2

         if(UpdataTIM)

         {

             period = 312500/CurrentFreq - 1;        //计算采样频率1M/32=31250;32为采样点数,31250/freq=采样周期

             TIM_ARRPreloadConfig(TIM2, DISABLE); //关闭TIM2定时重载

             TIM2->ARR = period ;        //更新定时器周期

             TIM_ARRPreloadConfig(TIM2, ENABLE);     //打开TIM2定时重载

         }

    }

    OSIntExit();  //退出中断  

}


关键字:STM32F407A  DC多通道  定时器触发  DMA模式 引用地址:STM32F407ADC多通道+定时器触发+DMA模式设置

上一篇:Stm32f103rct6ADC电压采集简介及注意点
下一篇:STM32如何实现可调频率、占空比的PWM波形

推荐阅读

据Globaldata的数据显示,2017年投资者对全球所有新兴科技公司最感兴趣的属于机器人,排在其后有智能支付、物联网、人工智能、安防/网络安全、区块链。虽然在全球中,人们对于人工智能技术创新热情要远远高于其他领域,但总体而言机器人技术带给投资者的吸引要高于人工智能,据中国电子学会发布了《中国机器人产业发展报告(2017年)》指出,2017年中国机...
一、总部 1.国网办公厅、国网董办 2.国网总师办 3.国网研究室 4.国网发展部 5.国网财务部 6.国网安监部 7.国网设备部 8.国网营销部、国网农电部 9.国网科技部、国网联办 10.国网基建部 11.国网特高压部 12.国网水新部 13.国网互联网部 14.国网物资部 15.国网产业部 16.国网宣传部、国网外联部 17.国网国际部 18.国网...
  工业机器人目前在工业中逐渐适用,工业机器人将代替人工重复性劳动。现实中,更多工厂均采用进口工业机器人,那国产工业机器人与其到底有何差距呢?此外,目前工业机器人又有何应用呢?本文将揭露这些问题的答案。如果你对本文具有兴趣,不妨继续往下阅读哦。   一、国内外工业机器人差距分析   在我国工业机器人市场的需求一直在持续增长,但...
来源:学习军团·解放军新闻传播中心融媒体作者:解放军报记者 韩 成 通讯员 于 晨“机器人技术正在深刻改变着人类的生产和生活方式,中国空间站机械臂也助力我们完成了两次出舱任务。”9月中旬,在北京亦庄开幕的2021世界机器人大会上,神舟十二号飞行乘组3位航天员聂海胜、刘伯明、汤洪波从中国空间站传来“太空点赞”。被表扬的主角,是我国自主研...

史海拾趣

问答坊 | AI 解惑

路由信息协议(RIP)

一、背景   路由信息协议(RIP)是以跳数作为metric的距离向量协议。RIP广泛用于全球因特网的路由,是一种内部网关协议(interior gateway protocol),即在自治系统内部执行路由功能。外部网关路由协议(exterior gateway protocol),如边缘网关协议 ...…

查看全部问答∨

新手问题

一个新手上来首先要熟悉网站的建构,否则好多东西使用不了。这不就像这个网站,我要熟悉熟悉了。呵呵呵…

查看全部问答∨

【Labview 概念】波形图-DAQ

我们使用DAQ进行数据采集时,采集卡得到的数组,每列表示一个通道所采集到的数据,所以用波形图显示时请先用数组转置。…

查看全部问答∨

Windows CE平台上开发采集板驱动程序.pdf

Windows CE平台上开发采集板驱动程序.pdf…

查看全部问答∨

smflash.dll 在哪

请问smflash.dll 这个是哪个驱动生成的文件?为什么我的PB在2440下编译后找不到这个文件?…

查看全部问答∨

什么是城管通

 城市管理现代化是建设现代化城市的重要组成部分。只有不断进行科技创新,才能为城市管理现代化插上腾飞的翅膀。“城管信息化系统”是振讯通信凭借在通信领域的多年经验,基于对通信系统、系统集成、通信终端和移动增值业务等方面的深刻理解,以及 ...…

查看全部问答∨

谈谈软硬件的思维方式

很早就想写这篇文章了,但都不知如何入手,今天在华禹工控的群内讨论了一下,再把他写下来,就比较容易了。 先谈硬件思维,以我为代表。 本人从小接触电子,主要家里一堆电子垃圾天天有得玩,再加上我爸买了一本电工学,没事干就看书,第一章就是 ...…

查看全部问答∨

大家帮帮忙,2812的调理模块怎样设计?

大家帮帮忙,2812的调理模块怎样设计? 我现在正在做2812的板子,现在遇到了问题,请各位大虾帮帮忙啊。。。。   放大和调理模块将信号放大并过滤掉噪声, 然后将模拟信号的电压幅值调整到F2812DSP芯片允许的范围之内(0-3V),然后 ...…

查看全部问答∨

STM8和STM32能破解吗?

不晓得现在STM8和STM32能被破解吗?解密公司都说能破解,是真的吗?那以后该用什么芯片设计呀?…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved