stm32程序怎么设置apb2总线时钟_浅谈STM32之ADC+DMA

本次内容是关于ADC+DMA组合的代码配置,具体内容是官方提供的使用案例。你可以到ST下载。或者以下链接(本链接为永久有效,如若害怕丢失请收藏):

链接:https://pan.baidu.com/s/1fOX5fSHUe4aAPW0fitjrFQ 提取码:LVST​pan.baidu.com

如果关于ADC基础知识不够熟悉,请参看以下链接:

露水:浅谈STM32-ADC之基本组成及原理​zhuanlan.zhihu.com

关于DMA的概述性的知识,不够了解,请参看以下链接:

露水:浅谈STM32之DMA​zhuanlan.zhihu.com

本次将具体问题具体分析,将整个配置使用过程分为四个过程来讲解,如下图

v2-8a0440ed9958366d1cde2806a61e9cc8_b.jpg

1.首先第一部分如下图

v2-b804b43c3bc7f92fc1fb43060340ea28_b.jpg

先不去管这个条件变量哪一个成立,那个不是当前的所要讲的重点,我们姑且认为运行的是红色方框中的三行代码。那么问题来了,1.为什么要如此配置呢?2.如果不是ADC,而是其他外设,那么关于时钟应该如何配置呢?

首先需要明确一件事情,stm32芯片手册,或者stm32中文参考手册,并不是拿过来死记硬背的,只是用来翻阅查看的(在你使用的时候),关于任何外设的使用配置也都是有章可循的,如果刻意的死记硬背,那么从本质上就错误了。那么我们就借此机会来做了示范喽。

首先这里是时钟配置,我们在这里之所以配置这些内容原因在于下图(RCC章节的图):

v2-0f312cfe4bd563378b7f24fc5ffe8cdd_b.jpg

上图是关于stm32中文参考手册中RCC部分中提到的时钟树。首先我们现在需要使用ADC1(上图中最下面的篮方框),所以ADC需要ADCCLK,从而就需要配置ADC预分频器,从而出现了第一行代码:RCC_ADCCLKConfig(RCC_PCLK2_Div4);,沿着红线往上看,可以看到ADC是挂接在APB2总线上面的,如果ADC有时钟,那么前提是APB2总线一定要有要给ADC提供时钟。从而出现了第三行代码:RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);

这两句如果理解了,学而不思则罔,思而不学则殆,那么思考一下,为啥配置DMA时钟时,使用第二句话: RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

。。。。。。。。。。。。。

是不是因为DMA挂接在AHB总线下啊。上图没有标注出DMA的位置,不妨寻找一下,看是不是呢。

说到这里也许你会问了,顺着红线往前走,会走到SYSTEM(系统时钟),既然配置了APB2,AHB,那么为啥没有在这里面配置系统时钟呢?没事是应该要配置系统时钟的,但是不是在这里面配置。而是在SystemInit ()中配置的。程序开始时先进入到这个函数中,进如,通过配置RCC进行了系统复位,与此同时也进行了系统时钟的配置,如下图(由于代码行数太多,不方便截图显示,删除了很多系统复位的函数,所以不用质疑和你的不一样)

v2-6341837625d5a182aad2b13eaeabbed2_b.jpg

之所以提前配置了系统时钟,是因为,只要你使用stm32,就必须配置系统时钟,这是一个必备条件。然而对于ADC则是,只有在你使用的时候在配置,不使用的时候就不调用。这样可以节省计算机资源,不是吗。

2.第二部分

如下图

v2-4ec00a124d1876b6572986b9fd74f732_b.png

问题有2个,首先1.为啥需要配置GPIO。其次2.为啥要这样配置。

首先关于第一个问题,本质上ADC是复用了GPIO的接口的,当我们作为通用I/O的时候,会有相应的配置,但是现在需要那他当作ADC的接口使用,不可避免的要重新配置GPIO.或者看下图也很清楚的可以了解这个原因:

v2-83041a8c5ed0d045ac52e49d3a818646_b.jpg

这是GPIO的端口的基本结构,从上图可以看出来,他有很多种配置输入和输出模式,这些模式是在我们使用的时候,具体问题具体配置使用的。我们现在使用的是ADC(模数转换)。当然要将这个GPIO选择为模拟量输入喽。

关于第2个问题,如下图

v2-77fb7bfed3c18cb6078f54a92ff214df_b.jpg

这个结构体总共有3个元素需要配置,所以需要向上图那样一一配置了,仔细看会发现为啥没有配置GPIO_Speed呢?原因在于传输速度,当前不是GPIO能决定的,传输速度主要在于ADC转换的速度。所以没有这个里没有做相应的配置。

3.第三部分

如下图

v2-8b9097fd067e5927e4994eea772ef42b_b.jpg

首先第一句:DMA_DeInit(DMA1_Channel1);

将 DMA 的通道 x 寄存器重设为缺省值
。原因在于下图

v2-d32d853521ac79b513256f46e49f21f4_b.png

上图种说明了DMA在同一时间只能被一个外设使用,所以在使用DMA之前,需要将先将其设置为缺省值,避免DMA打架。

第二句:DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;//内存及地址

第三句:DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设数据传输当然莫弟弟还是来源

原因看下图:

v2-57539ebbb7c58688e080fd890d1550cb_b.jpg

第四句:DMA_InitStructure.DMA_BufferSize = 1;//DMA通道缓存的大小

开下图

v2-1e4a057840adbc20eb8fbee3347002b1_b.png

剩下几句看下图

v2-68a20d67d6cd969bc711ebe8852d2d1d_b.jpg

4.第四部分

如下图

v2-445609c84efbfd634d756f812fe0d49a_b.jpg

第一句:ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

原因看下图:

v2-16c2482616e6b9260c227d04b076d415_b.png

第二句:ADC_InitStructure.ADC_ScanConvMode = ENABLE;

原因如下图:

v2-20997bc66942626d78d5b25b2cae6f21_b.jpg

第三句:ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

原因如下图

v2-82693eeaf4b84ae6a48aa57f6e8ee64c_b.jpg

这里就不再累赘剩下的了,其实是就是这么个过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值