STM32 GPIO初始化与模式配置详解

需积分: 9 0 下载量 7 浏览量 更新于2024-09-08 收藏 283KB DOCX 举报
"STM32 GPIO初始化与操作" STM32系列单片机,特别是STM32F0/F1/F2型号,提供了丰富的GPIO(General Purpose Input/Output)功能,相较于传统的51单片机,其GPIO更为灵活且复杂。STM32的GPIO不仅可以配置为不同模式,还具有多个寄存器进行精细化控制。以下将详细阐述STM32 GPIO的特性和初始化过程。 1. STM32 GPIO模式: STM32的每个IO口支持8种不同的工作模式,以适应各种应用场景: - 输入浮空:输入端口不连接任何上拉或下拉电阻,电平状态取决于外部电路。 - 输入上拉:输入端口有内部上拉电阻,未被驱动时呈现高电平。 - 输入下拉:输入端口有内部下拉电阻,未被驱动时呈现低电平。 - 模拟输入:无缓冲,适合连接模拟信号。 - 开漏输出:输出端口不带电源,需要外部上拉电阻来形成高电平。 - 推挽输出:内部有上拉和下拉电路,可输出高低电平。 - 推挽式复用功能:推挽输出同时用于其他外设功能。 - 开漏复用功能:开漏输出同时用于其他外设功能。 2. GPIO寄存器控制: STM32的每个IO端口有7个寄存器进行控制: - CRL和CRH:端口配置寄存器,分别控制低4位和高4位的模式、速度等。 - IDR和ODR:数据寄存器,IDR读取输入数据,ODR设置输出数据。 - BSRR和BRR:置位/复位和复位寄存器,用于快速改变输出状态。 - LCKR:锁存寄存器,用于锁定GPIO配置,防止意外修改。 3. 寄存器初始化示例: 以下代码展示了如何使用寄存器直接配置GPIOB和GPIOE的PB5和PE5为推挽输出,并设置为高电平: ```c void LED_Init(void) { RCC->APB2ENR |= 1 << 3; // 使能PORTB时钟 RCC->APB2ENR |= 1 << 6; // 使能PORTE时钟 GPIOB->CRL &= 0XFF0FFFFF; GPIOB->CRL |= 0X00300000; // PB.5推挽输出 GPIOB->ODR |= 1 << 5; // PB.5输出高 GPIOE->CRL &= 0XFF0FFFFF; GPIOE->CRL |= 0X00300000; // PE.5推挽输出 GPIOE->ODR |= 1 << 5; // PE.5输出高 } ``` 4. 库函数初始化步骤: 使用STM32 HAL库或LL库进行GPIO初始化通常包括以下步骤: - 时钟使能:调用`RCC_APB2PeriphClockCmd()`,确保GPIO所需时钟开启。例如,使能GPIOB和GPIOE的时钟。 - 配置GPIO初始化:调用`GPIO_Init()`函数,设定GPIO引脚、模式、速度等参数。 - 设置IO口值:通过`GPIO_SetBits()`、`GPIO_ResetBits()`或直接访问ODR寄存器设置输出状态。 STM32的时钟系统复杂,涉及多个时钟源和分频器,而GPIO的时钟通常挂载在APB2总线上。通过库函数操作GPIO更加简洁,但理解寄存器的工作原理对于故障排查和性能优化至关重要。 总结,STM32的GPIO特性为开发者提供了强大的输入输出控制能力,通过细致的寄存器配置和库函数的使用,可以灵活应对各种硬件接口需求。无论是寄存器级编程还是库函数方式,都需要熟悉STM32的GPIO架构和控制机制,以便实现高效可靠的嵌入式系统设计。

import RPi.GPIO as GPIO from LCD1602 import LCD_1602 import time BtnPin = 13 R = 4 G = 12 B = 6 TRIG = 17 ECHO = 18 buzzer = 20 GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(TRIG, GPIO.OUT, initial=GPIO.LOW) GPIO.setup(ECHO, GPIO.IN) GPIO.setup(R, GPIO.OUT) GPIO.setup(B, GPIO.OUT) GPIO.setup(G, GPIO.OUT) GPIO.setup(buzzer, GPIO.OUT) GPIO.setup(BtnPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.output(buzzer, GPIO.HIGH) m_lcd = LCD_1602(Address=0x27, bus_id=1, bl=1) flag = m_lcd.lcd_init() def get_distance(): GPIO.output(TRIG, GPIO.HIGH) time.sleep(0.000015) GPIO.output(TRIG, GPIO.LOW) while not GPIO.input(ECHO): pass t1 = time.time() while GPIO.input(ECHO): pass t2 = time.time() distance = round((t2-t1) * 340 / 2, 5) return distance def display_distance(distance): a = '%f'%distance m_lcd.lcd_display_string(0, 0, 'The distance is') m_lcd.lcd_display_string(0, 1, a) m_lcd.lcd_display_string(8, 1, 'm') def turn_on_red(): GPIO.output(R, GPIO.HIGH) def turn_on_green(): GPIO.output(G, GPIO.HIGH) def turn_on_blue(): GPIO.output(B, GPIO.HIGH) def turn_off_leds(): GPIO.output(R, GPIO.LOW) GPIO.output(G, GPIO.LOW) GPIO.output(B, GPIO.LOW) def turn_on_buzzer(): GPIO.output(buzzer, GPIO.LOW) def turn_off_buzzer(): GPIO.output(buzzer, GPIO.HIGH) def main(): while True: if GPIO.input(BtnPin) == 0: flag += 1 elif GPIO.input(BtnPin) == 1: pass if flag % 2 == 0: turn_off_leds() turn_on_buzzer() distance = get_distance() if distance < 0.2: turn_on_blue() turn_off_buzzer() display_distance(distance) time.sleep(1) elif flag % 2 == 1: turn_on_green() if __name__ == '__main__': main() GPIO.cleanup(),帮我把每一行代码注释一下

2023-05-24 上传