深入解析GPIO初始化及其在主程序中的配置

版权申诉
5星 · 超过95%的资源 0 下载量 2 浏览量 更新于2024-10-16 收藏 2KB ZIP 举报
资源摘要信息:"GPIO初始化" 1. GPIO基础概念: GPIO(General Purpose Input/Output)即通用输入输出端口,是微控制器(MCU)上常见的硬件资源。它可以让使用者自由配置为输入或输出模式,并通过编程控制这些引脚的状态。在微控制器的多种应用场景中,GPIO扮演着非常重要的角色。 2. GPIO初始化过程: 在使用GPIO端口进行各种功能的控制之前,首先需要对GPIO进行初始化。初始化主要包括配置GPIO的工作模式(输入、输出、复用、模拟)、输出类型(推挽或开漏)、速度(低速、中速、高速)以及上拉/下拉电阻等参数。不同的微控制器其GPIO初始化的函数和参数可能有所不同,但一般都需要设置这些基本属性。 3. 时钟配置: 微控制器的每个外设,包括GPIO,都需要时钟信号才能正常工作。在进行GPIO初始化之前,需要打开相应的GPIO端口时钟,否则GPIO端口将无法被控制。时钟配置涉及到时钟树的设计和时钟源的选择,确保每个需要工作的外设都有稳定的时钟信号。 4. TIM(定时器)初始化和配置: 定时器是微控制器中用于时间测量、计数、脉冲宽度调制(PWM)输出等功能的关键外设。初始化TIM通常包括配置定时器的工作模式、预分频器、计数模式(向上计数、向下计数或中心对齐计数)、自动重装载值、输出比较模式以及中断使能等。确保定时器能够根据设定的参数正常工作。 5. USART(通用同步/异步收发传输器)初始化和配置: USART是用于实现串行通信的重要外设,允许微控制器与其他设备或PC机通过串行线进行数据交换。初始化USART涉及到设置通信模式(异步、同步、单线或全双工)、波特率、字符长度(5至9位)、停止位(1位或2位)以及校验位(无校验、奇校验或偶校验)。正确配置USART可以实现稳定可靠的串行通信。 6. 主要代码分析(以main.c为例): 假设一个基于C语言的项目中,main.c文件包含主函数,其将调用各种初始化函数来配置GPIO、时钟、TIM和USART。在main函数的开始部分,通常会调用一个名为"main_GPIO_init"的函数,该函数将包含上述所有初始化步骤的代码实现。例如: ```c int main(void) { // 系统初始化代码(省略) // GPIO初始化代码 main_GPIO_init(); // 其他初始化代码(时钟、TIM、USART)(省略) // 主循环 while(1) { // 用户代码(省略) } } void main_GPIO_init(void) { // 打开GPIO端口时钟(代码示例) RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); // 配置GPIO引脚为输出模式,并设置推挽输出、高速(代码示例) GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_High; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOx, &GPIO_InitStructure); // 其他外设初始化代码(省略) } ``` 以上代码展示了在C语言项目中如何通过函数调用和参数设置来完成GPIO以及其他外设的初始化工作。初始化完成后,微控制器的GPIO端口及外设即可按照预期进行工作。
2023-05-25 上传

float speed; int main(void) { Breath_Init (); KEY_InitU(); OLED_Init(); Motor_init(); OLED_ShowString(1,1,"Rspeed:"); while (1) { Motor_derection(20); } } #include "stm32f10x.h" // Device header void Breath_Init () { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); GPIO_InitTypeDef GPIO_Initstucture; GPIO_Initstucture.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽 GPIO_Initstucture.GPIO_Pin=GPIO_Pin_0; GPIO_Initstucture.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_Initstucture); TIM_InternalClockConfig(TIM2); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstucture; TIM_TimeBaseInitstucture.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitstucture.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitstucture.TIM_Period=100-1;//72M/TIM_Period为频率也是ARR TIM_TimeBaseInitstucture.TIM_Prescaler=72-1;//分频也是PSC TIM_TimeBaseInitstucture.TIM_RepetitionCounter=0;//周期数 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitstucture); TIM_OCInitTypeDef TIM_OCInitstructure; TIM_OCStructInit(&TIM_OCInitstructure); TIM_OCInitstructure.TIM_OCMode=TIM_OCMode_PWM1; TIM_OCInitstructure.TIM_OCPolarity=TIM_OCPolarity_High; TIM_OCInitstructure.TIM_OutputState=TIM_OutputState_Enable; TIM_OCInitstructure.TIM_Pulse=0;//CCR TIM_OC1Init(TIM2,&TIM_OCInitstructure); TIM_Cmd(TIM2,ENABLE); } void TIM_Compare(uint16_t compare) { TIM_SetCompare1(TIM2,compare); } void KEY_InitD (void)//下拉 { //GPIOB初始化 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_Initstructure; GPIO_Initstructure.GPIO_Mode =GPIO_Mode_IPD ; GPIO_Initstructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_Initstructure); } void KEY_InitU (void)//上拉 { //GPIOB初始化 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_Initstructure; GPIO_Initstructure.GPIO_Mode =GPIO_Mode_IPU ; GPIO_Initstructure.GPIO_Pin = GPIO_Pin_1; GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_Initstructure); } uint16_t Key_GetNum () { uint8_t KeyNum = 0; if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { Delay_ms(20); while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0); Delay_ms(20); KeyNum = 1; } } void Motor_init () { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5; GPIO_Init(GPIOA, &GPIO_InitStructure); } void Motor_derection (float speed) { if(speed>0) { GPIO_SetBits(GPIOA,GPIO_Pin_4);//in1 GPIO_ResetBits(GPIOA,GPIO_Pin_5);//in2 TIM_Compare(speed); } else GPIO_ResetBits(GPIOA,GPIO_Pin_4);//in1 GPIO_SetBits(GPIOA,GPIO_Pin_5);//in2 TIM_Compare(-speed); } 为什么直流电机不转

2023-07-23 上传