当前位置: 首页 > wzjs >正文

做网站论文站长工具综合查询

做网站论文,站长工具综合查询,青岛北京网站建设公司哪家好,长沙网站seo推广公司哪家好一、概述 1、GPIO,即通用I/O(输入/输出)端口,是STM32可控制的引脚。STM32芯片的GPIO引脚与外部设备连接起来,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 2、GPIO的复用:引脚复用是指将单个引脚配置为多个功能的能力。在 STM32 中&…

一、概述

1、GPIO,即通用I/O(输入/输出)端口,是STM32可控制的引脚。STM32芯片的GPIO引脚与外部设备连接起来,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。

 2、GPIO的复用:引脚复用是指将单个引脚配置为多个功能的能力。在 STM32 中,每个引脚都可以配置为多个不同的功能,如GPIO(输入/输出数据)、定时器、UART、SPI等。这样一来,通过配置引脚复用功能,可以实现多种硬件功能的连接和实现,提高了芯片的灵活性和可扩展性。引脚默认为IO口。

二、GPIO的工作模式

 1、八大模式和四种输出速度

4种输入模式

(1)浮空输入(即不连接内部上下拉电阻)

(2)上拉输入(连接上拉电阻)

(3)下拉输入(连接下拉电阻)

(4)模拟输入(用于检测模拟信号的输入)

4种输出模式 

(5)开漏输出(带上拉或者下拉)

(6)复用开漏输出(带上拉或者下拉)

(7)推挽输出(带上拉或者下拉):程序员可以输出高电平与低电平

(8)复用推挽输出(带上拉或者下拉):程序员可以低电平,想要输出电平,芯片外部需要有上拉电阻。

4种最大输出速度

(1)2MHZ  (低速)

(2)25MHZ  (中速)

(3)50MHZ  (快速)

(4)100MHZ  (高速)

2、上下拉电阻

上拉电阻:

  • 将一个不确定的信号,通过一个电阻与电源VCC相连,固定在高电平;
  • 上拉是对器件注入电流;灌电流
  • 当一个接有上拉电阻的IO端口设置为输入状态时,它的常态为高电平;

下拉电阻:

  • 将一个不确定的信号,通过一个电阻与地GND相连,固定在低电平;
  • 下拉是从器件输出电流;拉电流
  • 当一个接有下拉电阻的IO端口设置为输入状态时,它的常态为低电平;

 三、寄存器编程

1、基本概念

寄存器是微处理器或微控制器内部的小型存储单元,用于临时存储数据、指令或控制信号。寄存器通常由硬件实现,并且可以直接通过CPU访问。寄存器的设计目的是为了提高处理器的性能,因为它们比内存访问更快。在微控制器如STM32F407中,寄存器用于配置和控制各种外设的功能。

2、寄存器分类

  1. 通用寄存器:用于存储数据或作为临时存储空间。
  2. 状态寄存器:存储有关处理器状态的信息,如标志位。
  3. 控制寄存器:用于控制处理器的行为。
  4. 外设寄存器:用于配置和控制微控制器中的外设。

 3、常见寄存器及用途

GPIO寄存器:- GPIOx_MODER:配置GPIO引脚的工作模式(输入、输出、复用功能等)。
- GPIOx_OTYPER:配置GPIO引脚的输出类型(推挽或开漏)。
- GPIOx_OSPEEDR:配置GPIO引脚的输出速度。
- GPIOx_PUPDR:配置GPIO引脚的上拉/下拉电阻。
- GPIOx_IDR:读取GPIO引脚的输入值。
- GPIOx_ODR:设置GPIO引脚的输出值。
- GPIOx_BSRR:设置或清除GPIO引脚的输出值。
- GPIOx_LCKR:锁定GPIO引脚的配置。时钟控制寄存器:
- RCC_CR:控制时钟源的选择和启动。
- RCC_PLLCFGR:配置PLL(Phase-Locked Loop)时钟。
- RCC_CFGR:配置时钟树,包括AHB/APB总线时钟。
- RCC_CIR:时钟中断寄存器。中断寄存器:
- NVIC_ISER:中断使能寄存器。
- NVIC_ICER:中断清除使能寄存器。
- NVIC_ISPR:中断挂起寄存器。
- NVIC_ICPR:中断清除挂起寄存器。
- NVIC_IPR:中断优先级寄存器。

4、寄存器地址 = 外设的基地址+偏移地址

下面的边界地址即为外设的基地址

例如

RCC_AHB1ENR寄存器地址 = RCC基地址+偏移地址

RCC_AHB1ENR寄存器地址 = 0x40023800+0x30

寄存器分析;

5、寄存器点灯例子:

(1)理解LED电路原理图

LED0连接在PF9

PF9输出低电平,灯亮;输出高电平,灯灭

led.c文件代码:

#include "led.h"/************************************
引脚说明:
LED0连接在PF9
PF9输出低电平,灯亮;输出高电平,灯灭************************************/void Led_Init(void)
{    //将第5位置1,你使能GPIOF组时钟RCC_AHB1ENR |= (0x01<<5);//配置PF9输出模式GPIOF_MODER &= ~(0x01<<19); //19位清0GPIOF_MODER |= (0x01<<18);  //18位置1//配置PF9推挽输出GPIOF_OTYPER &= ~(0x01<<9); //9位清0//配置PF9中速 25MHZGPIOF_OSPEEDR &= ~(0x01<<19); //19位清0GPIOF_OSPEEDR |= (0x01<<18);  //18位置1    //配置PF9中速无上下拉GPIOF_PUPDR &= ~(0x01<<19); //19位清0GPIOF_PUPDR &= ~(0x01<<18); //18位清0
}

main.c文件:


#include <stdio.h>
#include "led.h"//粗延时(就是延时不一定准确的意思)void delay(int n)
{int i, j;for(i=0; i<n; i++)for(j=0; j<10000; j++);
}int main(void)
{//初始化后GPIOF_ODR默认为低电平,所以灯亮Led_Init();while(1){//灯亮GPIOF_ODR &= ~(0x01<<9);  //9位清0delay(1000);//灯灭GPIOF_ODR |= (0x01<<9);  //9位置1delay(1000);        }return 0;
}

led.h文件:

#ifndef __LED_H
#define __LED_H//注意:0x40023800这个地址是根据不同的寄存器来决定的,编写多个寄存器的时候要非常注意有没有改
#define  RCC_AHB1ENR   	*((volatile unsigned int *)(0x40023800 + 0x30)) //值强制转换为地址  通过解引用访问地址空间
#define  GPIOF_MODER   	*((volatile unsigned int *)(0x40021400 + 0x00)) 
#define  GPIOF_OTYPER   *((volatile unsigned int *)(0x40021400 + 0x04)) 
#define  GPIOF_OSPEEDR  *((volatile unsigned int *)(0x40021400 + 0x08)) 
#define  GPIOF_PUPDR    *((volatile unsigned int *)(0x40021400 + 0x0C)) 
#define  GPIOF_ODR    	*((volatile unsigned int *)(0x40021400 + 0x14))
void Led_Init(void);#endif

四、使用库函数编程来点灯的例子

1、背景

🔸优点:

  • 性能优化: 直接通过寄存器进行操作可以减少中间层的调用,提高程序执行效率。
  • 灵活性高: 寄存器编程允许开发者直接控制硬件,提供最大的灵活性来定制特定的功能。
  • 代码紧凑: 通常情况下,寄存器级别的编程会生成更紧凑的代码,有助于节省内存空间。

🔸缺点:

  • 易出错: 寄存器编程需要对硬件有深入的理解,容易因为配置错误而导致问题。
  • 移植性差: 不同的微控制器可能有不同的寄存器布局和功能,这使得代码难以在不同的硬件之间移植。
  • 调试困难: 错误往往不易被发现,调试过程可能会比较复杂且耗时。

2、库函数的使用步骤

1、需要在keil5中添加RCC和GPIO库

2、使能端口F(PF9属于GPIOF组)的硬件时钟(芯片所有外设都是关闭时钟,原因为了降低功耗)

//使能GPIOF组时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);

3、(3)初始化引脚功能(推挽输出 速度 上/下拉)

  GPIO_InitTypeDef    GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_9; //引脚9GPIO_InitStruct.GPIO_Mode    = GPIO_Mode_OUT;//输出GPIO_InitStruct.GPIO_OType    = GPIO_OType_PP;//推挽模式GPIO_InitStruct.GPIO_Speed    = GPIO_Speed_25MHz;//25MHZ速度GPIO_InitStruct.GPIO_PuPd    = GPIO_PuPd_NOPULL; //无上下拉GPIO_Init(GPIOF, &GPIO_InitStruct);

4、设置引脚电平

GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) //设置引脚为高电平
GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)//设置引脚为低电平

3、库函数开发例子2(按键)

(1)理解KEY电路原理图

KEY0连接PA0

KEY0按下,PA0为低电平

KEY0未按下,PA0为高电平

2、使能GPIO时钟

    //使能GPIOA组时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);    

3、配置PA0引脚

引脚输入时,不需要配置GPIO 端口输出类型及GPIO 端口输出速度

    //结构体变量GPIO_InitTypeDef    GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_0;     //引脚0GPIO_InitStruct.GPIO_Mode    = GPIO_Mode_IN;    //输入模式GPIO_InitStruct.GPIO_PuPd    = GPIO_PuPd_UP; //根据外面电路来设置即可

4、读引脚电平

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

具体代码:四个按键控制四个灯

key.h文件:

#ifndef   _KEY_H
#define   _KEY_H#include "stm32f4xx.h"void key_init(void);
void led_init(void);enum
{key0 = 1,key1,key2,key3,
};u8 Key_Scan(u8 mode);#endif

key.c文件:

#include "key.h"//key2,key3,key4的引脚为PE组的2,3,4void key_init(void)
{// 使能GPIOA组时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; // 入GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // 上拉GPIO_Init(GPIOA, &GPIO_InitStruct);// 使能GPIOE组时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);GPIO_InitTypeDef GPIO_InitStruct1;GPIO_InitStruct1.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;GPIO_InitStruct1.GPIO_Mode = GPIO_Mode_IN; // 入GPIO_InitStruct1.GPIO_PuPd = GPIO_PuPd_UP; // 上拉GPIO_Init(GPIOE, &GPIO_InitStruct1);
}void led_init(void)
{// 使能GPIOF组时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // 引脚9GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;			 // 输出GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;			 // 推挽模式GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;		 // 25MHZ速度GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;		 // 无上下拉GPIO_Init(GPIOF, &GPIO_InitStruct);// 使能GPIOE组时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);GPIO_InitTypeDef GPIO_InitStruct1;GPIO_InitStruct1.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; // 引脚13GPIO_InitStruct1.GPIO_Mode = GPIO_Mode_OUT;			   // 输出GPIO_InitStruct1.GPIO_OType = GPIO_OType_PP;		   // 推挽模式GPIO_InitStruct1.GPIO_Speed = GPIO_Speed_25MHz;		   // 25MHZ速度GPIO_InitStruct1.GPIO_PuPd = GPIO_PuPd_NOPULL;		   // 无上下拉GPIO_Init(GPIOE, &GPIO_InitStruct1);// 关闭所有LED(假设低电平点亮LED)GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10);GPIO_SetBits(GPIOE, GPIO_Pin_13 | GPIO_Pin_14);
}void delays(int n)
{int i, j;for (i = 0; i < n; i++)for (j = 0; j < 10000; j++);
}// u8 == unsigned char
/************************************
函数功能:按键扫描
返回值:
成功:按下返回按键标志位,如:KEY0标志位1,KEY1标志位2,KEY2标志位3,KEY3标志位4
失败:0u8 mode:是否支持连按
0:不支持连按
1:支持连按*************************************/
u8 Key_Scan(u8 mode)
{// key_up保存上一次的值static u8 key_up = 1; // 按键标志,表示未按下if (mode == 1) // 支持连按key_up = 1;if (key_up && (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) | (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2) == 0) | (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == 0) | (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) == 0)){delays(15);key_up = 0; // 表示按下(防止重复触发)if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0){return key0; // KEY0标志值为1}if (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2) == 0){return key1; // KEY0标志值为1}if (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == 0){return key2; // KEY0标志值为1}if (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) == 0){return key3; // KEY0标志值为1}}else if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 1 | GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2) == 1 | GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == 1 | GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) == 1) // 未按下--也可以理解为松开{key_up = 1; // 按键松开key_up == 1}// 未操作按键(按键松开)return 0;
}

main.c文件:

#include <stdio.h>
#include "key.h"//粗延时(就是延时不一定准确的意思)void delay(int n)
{int i, j;for(i=0; i<n; i++)for(j=0; j<10000; j++);
}int main()
{//初始化后GPIOF_ODR默认为低电平,所以灯亮key_init();led_init();u8 value = 0;u8 key = 0;while(1){     //支持连按key = Key_Scan(1);if(key == key2){GPIO_ToggleBits(GPIOE, GPIO_Pin_13);}//不支持连按value = Key_Scan(0);if(value == key0){GPIO_ToggleBits(GPIOF, GPIO_Pin_9);}if(value == key1){GPIO_ToggleBits(GPIOF, GPIO_Pin_10);}
//		if(value == 3)
//		{
//			GPIO_ToggleBits(GPIOE, GPIO_Pin_13);
//		}if(value == key3){GPIO_ToggleBits(GPIOE, GPIO_Pin_14);}}return 0;
}

五、应用领域:如常见家里的电子门锁。

http://www.dtcms.com/wzjs/40710.html

相关文章:

  • 南昌哪家网站建设最好百度竞价推广什么意思
  • 只有一个域名怎么做网站药品网络营销公司
  • oem网站建设源码自己怎么做网址
  • winscp怎么做网站快速建站工具
  • 广州网站设计公司兴田德润在那里推特最新消息今天
  • 网站建设开发方式包括购买网站搜索排名优化价格
  • 陕西省住房和建设委员会网站品牌传播推广方案
  • 医院网站规划方案国内新闻最新消息
  • 网站建设全套教程下载站长工具忘忧草
  • 中国知名设计网站百度搜索推广的五大优势
  • 代做网站转账截图线上营销推广的公司
  • 一个网站的制作过程关键词推广seo怎么优化
  • 网站链接怎么做跳转结构优化
  • 装修网站模板源码网络营销品牌策划
  • 南宁哪里有网站建设培训班网站建设价格
  • 网站网站建设公成人用品推广网页
  • 牡丹江网站制作铜川网络推广
  • 海淀做网站公司app001推广平台官网
  • 找人做网站不算诈骗罪吗网站推广在线
  • 乐清疫情最新消息今天新增seo关键词排名
  • 做本地团购网站营销网络建设
  • 网站后台怎么修改前台的某个超链接网址广州网络运营课程培训班
  • 房地产网站设计公司做网站建设的公司
  • 描写做网站专业的句子潍坊网站建设优化
  • 平板电脑可以做网站不seo专员岗位职责
  • 宁波网站建设托管企业网站搭建
  • 如何查询网站后台地址宁德市古田县
  • 免费网站赚钱建站快车
  • asp网站配置伪静态网站友情链接的作用
  • 阿里云 网站根目录全球十大网站排名