完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在上一章,我们把IO系统的时钟源进行了一个梳理和详细分析,在正确的配置了相关的系统时钟源和IO模块的时钟源后,接下来还要做一件重要的事情,就是配置IO的输出模式。
既然是IO,就有输出也有输入,所以需要配置来选择正确的方向。 上图是STM32F103的IO基本结构图。 我们把这张图分两部分来解读: 第一部分: 输入input,如图中红色部分所示 当I/O端口配置为输入时,如上图简化后的图,注意红色圆圈的几个地方: 1.输出缓冲器被禁止,如图A点,被断开,所以你的输出数据无法反应到IO端口上,此路不通。 2. 施密特触发输入被激活,如图B点 这两步动作是把端口模式配置为输入后自动进行的,无需额外配置 3. 根据输入配置(上拉,下拉或浮动)的不同,弱上拉和下拉电阻被连接 4. 出现在I/O脚上的数据在每个APB2时钟被采样到输入数据寄存器,这就是IO能捕捉到数据的最大的频率,如果你的输入数的频率高于这个频率,将不会正确的捕捉到。 5. 对输入数据寄存器的读访问可得到I/O状态。 输入的三条路径如下第一条路径是模拟信号输入路径,它是直达系统的模拟输入器件端口的,比如ADC,比较器等模拟电路,所以它要绕过输入部分的数字电路(施密特触发器)。如下图ADC的输入路径所示,它从IO口进来后会进入一个MUX(多路复用器,算是一个模拟开关),然后到达ADC转换单元完成模拟到数字的转换后,才送到后端进行进一步的处理。 特别留意一下模拟输入的时候示意图如下: 如上图所示,当I/O端口被配置为模拟输入时:
对于特殊功能的路径,简化后如下: 当I/O端口被配置为复用功能时:
第二部分 输出output,如第一张图的蓝色部分所示 当I/O端口被配置为输出时,IO的结构如上图所示: 1.输出缓冲器被激活 ─ 开漏模式:输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将端口置于高阻状态(PMOS从不被激活,相当于已经被从系统断开)。 ─ 推挽模式:输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将激活P-MOS。 2. 施密特触发输入被激活,如图C点 3. 弱上拉和下拉电阻被禁止 4.出现在I/O脚上的数据在每个APB2时钟被采样到输入数据寄存器,这样才可以读到输出的数据 5.在开漏模式时,对输入数据寄存器的读访问可得到I/O状态 6. 在推挽式模式时,对输出数据寄存器的读访问得到最后一次写的值。 对应的输出也会有三条路径从图上可以看出来,三路输出的路径最后都要经过一个输出控制单元的控制,所以输出路径的特殊之处在于没有模拟信号输出。 第一条路径是特殊功能输出,比如UART的TX,DAC的输出等。 第二条路径,就是直接写端口的寄存器来输出数据,如下图所示,STM32F103的输出数据一般都是16bit(32bit的MCU最高是可以到32bit的)。 GPIOA->ODR = 0x0012; //将0x0012送到A端口,输出完毕后,端口的bit1,bit5变1 第三条路径就是arm的一个特殊操作,bit操作。这个操作的目的就是加速单个IO的数据输出速度。 IO的数据输入输出寄存器是32bit,我们读的时候就是一次性读入的,写也是一次性输出的,比如向GPIOA输出数据: GPIOA->ODR = PortVal; //这样输出是一次性输出16bit,同时改变16位的数据。如果我们只需要输出bit0的数据,就需要这样来操作才可以:PortVal = GPIOx->ODR;//先读入整个端口的输出寄存器值。PortVal &= 0xFFFFFFFE;//mask掉bit0If(要输出bit0==1) PortVal |= 0x00000001;GPIOA->ODR = PortVal; //输出数据 以上操作相当的繁琐,效率低下,如果用ARM的位操作来做,非常简单: GPIOA->BSRR = GPIO_Pin1;// GPIO_Pin1 == 1 只需要向这个特殊的寄存器的对应位写1就一步完成了操作,效率提高若干倍。 要注意的是复位对应的位也是写1而不是0,只是所用的寄存器不一样, GPIOA->BRR = GPIO_Pin1;// GPIO_Pin1 ==0 最后通过两个特殊的寄存器,来选择我们需要的输出和输入路径: 根据你的输入输出功能,选择正确的输出路径后,基本通道就打通了。 别高兴太早了,还要一步需要我们去完成,看到图一中的ABCD几个地方的设置了吗? |
|
|
|
只有小组成员才能发言,加入小组>>
3208 浏览 9 评论
2894 浏览 16 评论
3401 浏览 1 评论
8840 浏览 16 评论
3994 浏览 18 评论
9625浏览 3评论
998浏览 3评论
518浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
521浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2244浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-9-28 23:00 , Processed in 4.044630 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号