初学STM32之简朴熟悉IO口设置(学习条记)

[复制链接]
发表于 前天 19:54 | 显示全部楼层 |阅读模式
     在使用51单片机的时间根本上不须要额外的设置IO,不外在使用特定的IO的时间须要额外的操持外围电路,比如PO口它是没有内置上拉电阻的。因此若想P0输出高电平,它就须要外接上拉电平。(固然这不是说它输入不须要上拉电阻,重要是它作为输入端的时间吸取高电平就是共外围电路的上拉电阻)。
操纵目的是控制STM32F103C8T6上某个IO口让其置1大概置0.

GPIO是APB2上的外设资源。
APB2是AMBA总线布局中的一种,重要用于低带宽的周边外设之间的毗连。
APB2(Advanced Peripheral Bus 2)是ARM公司提出的AMBA总线布局之一,属于一种片上总线布局。APB2重要用于毗连低速外设,如I2C、UART、SPI等,这些外设通常具有低带宽和低功耗的需求。
APB2的特点


  • 低带宽‌:APB2重要用于毗连低速外设,得当那些不须要高速数据传输的外设。
  • 非流水作业‌:APB2的传输至少须要两个时钟周期,且数据在时钟的上升沿厘革,不须要等候周期和回应信号。
  • 控制逻辑简朴‌:APB2只有四个控制信号,传输可以接纳状态机表现,控制逻辑相对简朴。
APB2与其他总线的区别



  • 与AHB的区别‌:AHB是高级高性能总线,重要用于毗连高性能模块如CPU、DMA和高速存储器。APB2则是用于毗连低速外设。
  • 与APB3和APB4的区别‌:APB3增长了PREADY和PSLVERR信号,用于反馈读和写的状态;APB4增长了PPROT和PSTRB信号,用于提供掩护机制和字节选通功能
   在51单片机中假如我们要是某个IO口,比如P1.0端口输出高电平 ,直接赋值即可。但作为输入端就稍微贫苦点须要先赋值P1.0为高电平,再读取P1.0端口的电压。须要两步走。
GPIO作为一种外设资源,在使用它的时间要颠末这么几步走,


  • 第一步:假设要是能PC13使其输出高电平,经查得知PC13是GPIOC的编号13的IO口(按照次序因该是第14位IO,是从0开始编的)以是第一步使能能APB2外设总线时钟寄存器
APB2这个外设使能时钟寄存器名字是RCC_APB2ENR,作为32位的单片机它的特殊功能寄存器一样平常也是32位,点一下APB2上的外设个数
,刚好是16个,GPIOC是此中的一位,然后我们看一动手册上的形貌(库函数里有21个)

确实是0-15位可控制,后16位是保存的。从他的复位值可知默认的都是0;具体检察可知

可知位4(是第5位)至1,即可使能GPIOC I/O口。即 RCC->APB2EBR = 0x00000010
 = 0B 0000 0000 0000 0000 0000 0000 0001 0000


  • 第二步:GPIO和51单片机的IO口的差别之处是它的输入输出是分开的须要额外的举行功能选择的,而且对应IO口处于什么布局模式也是须要选择的,

在STM32中控制这些功能,每个IO口须要4位,16个IO就是64位,因此这些IO口的功能选择控制寄存器就分成了两个,端口控制高寄存器(CRH)和端口控制低寄存器(CRL),PC13应是由CRH控制,打开手册得知:

先看一下它的复位值:0x4444 4444 = 0b0100 0100 0100 0100 0100 0100 0100 0100
可以看到0100代表的是浮空输入模式,即STM32上电后的复位状态都是浮空输入模式。

浮空输入(GPIO_Mode_IN_FLOATING)




  • 电路布局:无内部上下拉电阻,引脚悬空。
  • 特点

    • 电平由外部电路决定。
    • 未毗连外部电路时,电平大概不稳固(易受干扰)。

因此控制这个IO口我们选择0011 (通用推挽输出模式速率50HZ) 即我们赋值寄存器
GPIOC->CRH = 0x0030 0000;固然这个写法是不太对,别的位我们都赋值为0了,
一样平常来说须要先把该处的控制位清0;即GPIOC->CRH &= 0x1101 1111;
然后再通过或运算给控制位赋值:即GPIOC->CRH |= 0x0030 0000;(1个16进制数代表4个2进制数)
第三步:选择输出高电平还是低电平,在51机中我们直接就是使用赋值语句举行赋值,如:P1.0 = 0;但是在STM32中是在专用的寄存器里操纵的而且分输入和输出,端口输出数据寄存器(GPIOx_ODR) (x=A..E),端口输入数据寄存器(GPIOx_IDR) (x=A..E),现在是须要输出一个低电平,

我们是须要在位13处写0,正常环境下还是需要颠末与或运算才是正确的赋值方式,这边就直接赋值别的位都置0:
GPIOC->ODR = 0x0000 0000;//输出低电平
GPIOC->ODR = 0x0000 2000//输出高电平

颠末这三步我们就乐成使PC13端口输出低电平大概高电平(通用推挽输出方式,50MHZ)
这是使用寄存器的方式举行操纵。尚有使用库函数的,库函数就不叙述了。
笔者的资料来自B站江协科技。

模式电平特性驱动本事实用场景留意事项模仿输入模仿信号-ADC/DAC禁用数字功能浮空输入由外部决定-外部有上下拉的总线克制悬空下拉输入默认低电平-检测高电平有用信号外部信号需强驱动上拉输入默认高电平-检测低电平有用信号外部信号需强驱动推挽输出主动驱动高 / 低电平强LED、高速信号克制总线辩说开漏输出需外部上拉弱I2C、电平转换必须外接上拉电阻复用推挽外设驱动高 / 低电平强定时器 PWM、USART_TX需设置外设功能复用开漏外设驱动 + 外部上拉弱I2C、CAN 总线需设置外设功能
一、输入模式


1. 模仿输入(GPIO_Mode_AIN)




  • 电路布局:引脚直连 ADC/DAC 模块,断开内部上下拉电阻。
  • 特点

    • 无施密特触发器,直接转达模仿信号。
    • 克制数字信号输入(无法读取高低电平)。

  • 应用

    • ADC 电压收罗(如传感器信号)。
    • DAC 模仿输出(某些引脚支持)。


2. 浮空输入(GPIO_Mode_IN_FLOATING)




  • 电路布局:无内部上下拉电阻,引脚悬空。
  • 特点

    • 电平由外部电路决定。
    • 未毗连外部电路时,电平大概不稳固(易受干扰)。

  • 应用

    • 须要外部上拉或下拉的场景(如总线通讯:I2C 的 SDA/SCL 需外部上拉)。
    • 电平由外部装备驱动(如克制信号线)。

3. 下拉输入(GPIO_Mode_IPD)




  • 电路布局:内部毗连下拉电阻(约 20-50kΩ),默认低电平。
  • 特点

    • 引脚悬空时,默认读取低电平。
    • 外部高电平可覆盖下拉。

  • 应用

    • 克制引脚悬空引发误触发(如按键检测低电平有用)。

4. 上拉输入(GPIO_Mode_IPU)




  • 电路布局:内部毗连上拉电阻(约 20-50kΩ),默认高电平。
  • 特点

    • 引脚悬空时,默认读取高电平。
    • 外部低电平可覆盖上拉。

  • 应用

    • 克制引脚悬空引发误触发(如按键检测高电平有用)。

二、输出模式


5. 推挽输出(GPIO_Mode_Out_PP)




  • 电路布局:P-MOS 和 N-MOS 组合,可主动输出高 / 低电平。
  • 特点

    • 高电平:P-MOS 导通,输出 VDD。
    • 低电平:N-MOS 导通,输出 GND。
    • 驱动本事强,得当高速切换。

  • 应用

    • 驱动 LED、继电器等负载
    • 高频信号(如 PWM、SPI 时钟)。


6. 开漏输出(GPIO_Mode_Out_OD)




  • 电路布局:仅 N-MOS,需外部上拉电阻输出高电平。
  • 特点

    • 高电平:N-MOS 关闭,电平由外部上拉电阻决定。
    • 低电平:N-MOS 导通,输出 GND。
    • 支持 “线与” 逻辑,但上升沿较慢。

  • 应用

    • I2C、SMBUS 等总线通讯。
    • 电平转换(如 5V 与 3.3V 装备通讯)。


7. 复用推挽(GPIO_Mode_AF_PP)




  • 电路布局:与平凡推挽雷同,但输出由外设控制(如 USART、SPI)。
  • 特点

    • 外设主动管理电平输出(如定时器 PWM、串口 TX)。
    • 高驱动本事,得当高频外设。

  • 应用

    • 外设功能引脚(如 TIMx_CHx、USART_TX)。
    • 须要硬件主动控制的场景。


8. 复用开漏(GPIO_Mode_AF_OD)




  • 电路布局:与平凡开漏雷同,但输出由外设控制。
  • 特点

    • 需外部上拉电阻,支持 “线与” 逻辑。
    • 由外设主动管理电平(如 I2C 的 SDA/SCL)。

  • 应用

    • I2C、CAN 总线等复勤劳能。
    • 多装备共享总线通讯。


这是驱动电路,然后我们调用端口各个功能测试一下他们的区别:


  • GPIO_Mode_IPU 使PC13处于输入状态,而且内部设置上拉电阻,LED熄灭,端口电压3.2V
可以设置端口电压为低电平,这时LED会点亮不外亮度不敷端口电压为1V。


  • GPIO_Mode_IPD 使PC13处于输入状态,而且内部设置下拉电阻,LED依然会点亮不外亮度不敷
端口电压1V


  • GPIO_Mode_IN_FLOATING  LED熄灭端口电压1.3V,推测是是驱动电流不敷
  • 当设置IO输出端口的时间假如忘记设置频率将无法正确使IO工作,同理假如忘记操持别的参数IO口也无法正确使能?从测试结果看电压是1.3V即端口状态是之前的浮空输入状态。
使用库函数设置IO口使PC13端口输出低电平
  1. #include "stm32f10x.h"                  // Device header
  2. int main(void)
  3. {
  4.         //RCC->APB2ENR = 0x00000010; //APB2 外设时钟使能寄存器
  5.         //GPIOC->CRH = 0x00300000; //端口配置高寄存器
  6.         //GPIOC->ODR = 0X00000000; //端口输出数据寄存器
  7.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
  8.         GPIO_InitTypeDef GPIO_InitStructure;
  9.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出       
  10.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  11.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  12.        
  13.         GPIO_Init(GPIOC,&GPIO_InitStructure);
  14.         //GPIO_SetBits(GPIOC,GPIO_Pin_13);//端口设置为1
  15.         GPIO_ResetBits(GPIOC,GPIO_Pin_13); //端口设置为0
  16.        
  17.   while(1)
  18.         {
  19.        
  20.         }
  21. }
复制代码
GPIOpin的选择上可以用或运算:
  1. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_6 | GPIO_Pin_7 ;                                //GPIO引脚,赋值为0,2,3,4,6,7
复制代码
库函数与对应的寄存器罗列

下面的步调是PB14外部克制的初始化过程
  1. void CountSensor_Init(void)
  2. {
  3.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//GPIOB时钟使能
  4.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//AFIO时钟使能
  5.        
  6.         /*GPIO初始化 */
  7.         GPIO_InitTypeDef  GPIO_InitStructure;
  8.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//上拉
  9.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 ;  //14位
  10.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  11.         GPIO_Init(GPIOB,&GPIO_InitStructure);    //使能GPIOB_14设置
  12.        
  13.         /*AFIO选择引脚*/
  14.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//
  15.        
  16.         /*EXIT初始化*/
  17.     EXTI_InitTypeDef EXIT_InitStructure;
  18.         EXIT_InitStructure.EXTI_Line = EXTI_Line14 ;
  19.         EXIT_InitStructure.EXTI_LineCmd = ENABLE ;
  20.         EXIT_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //选择外部中断
  21.         EXIT_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling ;//下降沿
  22.     EXTI_Init(&EXIT_InitStructure);//使能外部中断设置
  23.        
  24.         /*设置NVIC,中断优先级设置  */
  25.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  26.         NVIC_InitTypeDef NVIC_InitStructure;
  27.         NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  28.         NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE ;
  29.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2 ;
  30.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2 ;
  31.         NVIC_Init(&NVIC_InitStructure); //使能NVIC中断设置
  32.        
复制代码
设置外部克制PB14、上拉电阻、降落沿触发。克制优先级 抢占2 相应2

  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//GPIOB时钟使能
复制代码
  寄存器   APB2ENR bit 3
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//AFIO时钟使能
复制代码
 寄存器   APB2ENR bit 0
  1. GPIO_InitTypeDef  GPIO_InitStructure;
  2.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//上拉
  3.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 ;  //14位
  4.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  5.         GPIO_Init(GPIOB,&GPIO_InitStructure);    //使能GPIOB_14设置
复制代码
见前文的阐明不赘述,此中的上下拉模式要特殊阐明一下




由手册发现上拉/下来输入模式由同一组控制位控制,怎么区分设置呢?
输入模式下的上拉电阻和下拉电阻寄存器设置  由GPIOx_ODR寄存器控制,为0则为下拉,为1则为上拉。ODR寄存器原先是数据输出寄存器。由上述的两图可以看到当设置为GPIO_Mode_IPU;时ODR14为1,下拉时为0.


  1. /*AFIO选择引脚*/
  2.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//
复制代码
AFIO(Alternate Function Input/Output)复用端口选择寄存器设置

该端口,本例接纳的是克制设置因此不设置默认。

端口复勤劳能设置,本案都是使用主功能因此也不设置。
  外部克制设置寄存器 1~4(AFIO_EXTICR1)      外部克制设置寄存器共4个,pb14使用的是第4个  AFIO_EXTICR4  
  由于是设置PB14因此控制的是8-11 EXTI14[3:0]位共4位控制位,由于是GPIOB 因此这4位是  0001 =0x01   



  1. EXTI_InitTypeDef EXIT_InitStructure;
  2.         EXIT_InitStructure.EXTI_Line = EXTI_Line14 ;
  3.         EXIT_InitStructure.EXTI_LineCmd = ENABLE ;
  4.         EXIT_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //选择外部中断
  5.         EXIT_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling ;//下降沿
  6.     EXTI_Init(&EXIT_InitStructure);//使能外部中断设置
复制代码
设置外部克制寄存器:
  ● 设置 20个克制线的屏蔽位(EXTI_IMR)   IMR( Interrupt Mask Register )  
  
  1. EXIT_InitStructure.EXTI_Line = EXTI_Line14 ;
  2.         EXIT_InitStructure.EXTI_LineCmd = ENABLE ;
  3. EXIT_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //选择外部中断
复制代码

  默认是全屏蔽的,步调是使能bit14
  

默认是全屏蔽的即复位值是0x0000 0000. EMR(Event Mask Interrupt)

  ● 设置所选克制线的触发选择位 (EXTI_RTSR 和 EXTI_FTSR) ;  
RTSR(Rising Trigger Selection Register),我们选择的是降落沿因此无需设置即默认。

FTSR(Falling edge Trigger Selection Register) 我们设置是bit14位因此须要设置为1
  1.     //EXIT_InitStructure.EXTI_Line = EXTI_Line14 ;
  2.         //EXIT_InitStructure.EXTI_LineCmd = ENABLE ;
  3. EXIT_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling ;//下降沿
复制代码


软件克制是通过代码大概寄存器操纵触发克制,之前代码中是接纳GPOI触发是硬件触发克制因此无需设置即默认即可。

PR(Pull Reques),挂起寄存器是操纵变乱触发的,当外部克制触发后,须要软件清0.即EXTI_ClearITPendingBit(EXTI_Linex);    

      
  1. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  2.         NVIC_InitTypeDef NVIC_InitStructure;
  3.         NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  4.         NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE ;
  5.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2 ;
  6.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2 ;
  7.         NVIC_Init(&NVIC_InitStructure); //使能NVIC中断设置
  8.        
复制代码

      至于NVIC是内核中的寄存器KEIL5中有相应的检察界面,但是内里的参数好像有点题目,以本案为  例:
  未使能NVIC之前的数据,可以看到优先级分组里的选项就不符合STM32F103C8t6里的分法,使能后的数据
  SCB->AIRCR根据手册因是
  他的掩码是0x05FA0000,分组是2组即0x500,以是结果是0x05FA0500和这个界面里表现的也不一样,因此这内里的  然后再看一张分组1的NVIC界面是1抢占3相应  
     记过频频设置分组的比力可以得出以下几个结果:
这里的数据代表分组是第几组(至于组内内里的相应设置变动,不会改变这个值)   
这个内里是数据 1是抢占优先级,48 = 16*3 相应优先级是3,即1抢占3相应。176不清晰,这是观察结果大概只得当STM32F103C8T6   硬件变乱选择   通过下面的过程,可以设置 20 个线路为变乱源   ● 设置 20 个变乱线的屏蔽位 (EXTI_EMR)   ● 设置变乱线的触发选择位 (EXTI_RTSR 和 EXTI_FTSR)   软件克制 / 变乱的选择   20 个线路可以被设置成软件克制 / 变乱线。下面是产生软件克制的过程:   ● 设置 20 个克制 / 变乱线屏蔽位 (EXTI_IMR, EXTI_EMR)   ● 设置软件克制寄存器的哀求位 (EXTI_SWIER)   以下来自DEEPSEEK   一、界说与焦点功能

  

  • 变乱寄存器

    • 功能‌:用于设置和控制硬件变乱的触发条件(如边沿检测)及是否允许变乱信号转达到硬件模块(如DMA、ADC等)‌。
    • 范例寄存器‌:

      • EMR(变乱屏蔽寄存器):控制变乱触发是否有用‌。
      • RTSR/FTSR(上升沿/降落沿触发选择寄存器):设置变乱的触发条件‌。


  • 克制寄存器

    • 功能‌:管理克制哀求的触发、优先级设置及克制屏蔽状态,直接关联CPU的克制相应流程‌12。
    • 范例寄存器‌:

      • IMR(克制屏蔽寄存器):控制克制哀求是否被CPU相应‌。
      • EXTICR(外部克制设置寄存器):设置克制线对应的GPIO引脚及触发方式‌。


  二、触发机制差别

  ‌特性‌‌变乱寄存器‌‌克制寄存器‌‌触发目的‌直接驱动硬件模块(如DMA、ADC)触发CPU克制服务步调(ISR)‌13‌相应方式‌硬件主动处理处罚,无需CPU加入需CPU生存现场并实行ISR‌12‌范例应用‌低耽误数据传输、周期性触发操纵异步任务处理处罚、告急变乱相应‌23  
  三、设置流程对比

  

  • 变乱寄存器设置示例

    • 通过RTSR设置上升沿触发变乱。
    • 通过EMR使能变乱触发,信号直接转达至外设模块‌。

  • 克制寄存器设置示例

    • 通过EXTICR绑定GPIO引脚到克制线。
    • 通过IMR使能克制哀求,并设置NVIC优先级‌。

  四、关键操持差别

  

  • 变乱寄存器‌:

    • 通过硬件链路实现快速相应,实用于实时性要求高且无需复杂逻辑的场景‌。
    • 范例应用:DMA触发、定时器同步‌23。

  • 克制寄存器‌:

    • 依赖CPU加入,得当须要实行复杂逻辑或修改步调流程的场景‌。
    • 范例应用:按键检测、通讯协议处理处罚‌。

  
  五、总结

  

  • 变乱寄存器‌通过硬件链路实现快速相应,‌克制寄存器‌依赖CPU处理处罚异步任务‌。
  • 两者常联合使用,比方:变乱触发DMA传输,传输完成后通过克制关照CPU‌23。
  
    ● 设置对应到外部克制控制器  (EXTI)  的  NVIC  克制通道的使能和屏蔽位,使得  20  个克制线中的      哀求可以被正确地相应。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表