打印
[STM32F1]

STM32F1库函数之GPIO

[复制链接]
112|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一.STM32F103C8T6
(1)命名规则



Flash 存储器

Flash 存储器 是一种非易失性存储器,用于存储程序代码、常量数据(如字符串、表格等)和配置信息。即使在断电后,Flash 中的数据仍然保留。
在 STM32 中,Flash 主要用于存储用户编写的固件代码,以及一些需要在启动时加载的初始化数据。
特点
非易失性:数据在断电后不会丢失。
可编程:可以通过特定的编程接口(如 JTAG、SWD)进行擦除和编程。
读取速度快:相对于 EEPROM 等其他非易失性存储器,Flash 的读取速度更快。
擦写次数有限:Flash 的擦写次数是有限的,通常在数万到数十万次之间。因此,在频繁更新的数据存储中,应避免直接使用 Flash。
STM32 中的 Flash
容量:不同的 STM32 系列和型号,其 Flash 容量不同。例如,STM32F103C8T6 的 Flash 为 64KB,而 STM32F103RCT6 的 Flash 为 256KB。
组织结构:Flash 通常被组织为多个扇区(sector)或页(page),每个扇区或页可以单独擦除和编程。
启动模式:STM32 可以从 Flash 启动,也可以从 SRAM 启动,具体取决于启动配置。
SRAM(静态随机存取存储器)
定义与用途
SRAM 是一种易失性存储器,用于存储程序运行时的临时数据,如变量、堆栈、堆等。在断电后,SRAM 中的数据会丢失。
在 STM32 中,SRAM 主要用于存储程序运行时需要频繁访问和修改的数据。
特点
易失性:数据在断电后丢失。
读写速度快:SRAM 的读写速度非常快,适合用于需要高速数据访问的应用。
静态:不需要刷新电路,功耗较低。
容量相对较小:相对于 Flash,SRAM 的容量通常较小,成本较高。
STM32 中的 SRAM
容量:不同的 STM32 系列和型号,其 SRAM 容量不同。例如,STM32F103C8T6 的 SRAM 为 20KB,而 STM32F103RCT6 的 SRAM 为 64KB。
组织结构:SRAM 通常被组织为多个区域,如堆栈区、堆区、变量区等。
启动模式:STM32 可以从 SRAM 启动,但这需要特殊的配置和编程,通常用于调试或特定的应用场景。
Flash 和 SRAM 的比较



程序存储

Flash 用于存储用户编写的固件代码,以及一些需要在启动时加载的初始化数据。

SRAM 用于存储程序运行时需要频繁访问和修改的数据,如变量、堆栈等。

数据存储

Flash 可以用于存储需要长期保存的数据,如配置参数、日志等。但需要注意擦写次数的限制。

SRAM 不适合用于长期数据存储,因为断电后数据会丢失。

启动模式

STM32 可以配置不同的启动模式,从 Flash 或 SRAM 启动。具体配置方法可以参考 STM32 的参考手册。

优化与使用建议

Flash 编程:尽量减少对 Flash 的擦写操作,特别是在频繁更新的数据存储中。可以考虑使用 EEPROM 或外部 Flash 来存储需要频繁更新的数据。
SRAM 管理:合理管理 SRAM 的使用,避免内存泄漏和碎片化。可以使用内存管理工具或库来帮助管理内存。
缓存与缓冲:利用 SRAM 作为缓存或缓冲,提高数据访问速度。例如,可以使用 SRAM 作为 DMA 缓冲区,提高数据传输效率。
(2)系统结构



(3)引脚定义




二.新建工程模板
(1)型号分类及缩写



在 STM32 微控制器中,Flash 和 SRAM 是两个关键的存储器类型,它们在嵌入式系统的运行中扮演着不同的角色。以下是对这两个存储器的详细解释:

(2)工程建立
1)新建工程文件夹,Keil中新建工程,选择型号

2)工程文件夹中新建文件夹Start、Library、User,复制固件库文件到工程文件
(Start)内核寄存器描述:core_cm3.c/h
(Start)外设寄存器描述:stm32f10x.h
(Start)定义SystemInit:System_xx.c/h
(Start)启动调用函数描述:startup_md.s
(Library)库函数描述:misc.c/h;stm32f10x_adc.c/h;…
(User)库函数配置描述:stm32f10x——conf.h
(User)定义中断处理函数:stm32f10x_it.c/h
(User)定义main函数:main.c

3)keil工程里建分组Start、Library、User,将文件夹内的文件添加到工程分组中

4)工程选项,C/C++,Include Paths内声明所有包含头文件的文件夹

5)工程选项,C/C++Define输入USE_STDPERIPH_DIRVER

6)工程选项,Debug选择对应调试器,Setting,Flash Download勾选Reset and run

三.GPIO输出:LED和蜂鸣器
1)GPIO的8种工作模式



选择STM32的GPIO工作模式时,需要根据具体的应用场景和需求来决定。以下是一些选择工作模式时的考虑因素:
1.
输入模式:
如果你需要读取外部设备的状态,并且外部设备可以提供稳定的高或低电平信号,可以选择浮空输入。
如果外部设备可能处于高阻态或未连接状态,为了确保读取到稳定的电平,可以选择上拉输入或下拉输入。上拉输入适用于外部设备通常为低电平或未连接时,下拉输入适用于外部设备通常为高电平时。
2.
输出模式:
如果你需要控制一个LED灯或驱动一个简单的数字设备,推挽输出模式通常是最合适的选择,因为它可以提供稳定的高电平和低电平输出。
如果你需要实现如I2C总线上的多主机通信,或者需要实现一个集电极开路输出,那么开漏输出模式会更适合。(软件IIC)
3.
模拟模式:
如果你的应用需要读取模拟信号,如温度传感器的输出,那么需要将GPIO配置为模拟输入模式,并连接到ADC模块。
STM32的GPIO不支持直接的模拟输出,但可以通过DAC模块输出模拟信号。
4.
特殊模式(复用功能模式):
当你需要使用STM32的内置外设(如UART、SPI、I2C等)时,需要将相应的GPIO引脚配置为复用功能模式。根据外设的需要,可能还需要配置为复用推挽输出或复用开漏输出。(硬件IIC:复用开漏输出,SPI:复用推挽输出)
在选择GPIO工作模式时,还需要考虑以下因素:
电气特性:不同的模式下,GPIO引脚的电气特性(如输出电流能力、输入/输出电平标准等)会有所不同。
功耗:某些模式(如开漏输出)可能更适合低功耗应用。
电路设计:根据电路设计的需要,选择合适的上拉/下拉电阻值或是否需要外部上拉/下拉电阻。
最后,确保在配置GPIO之前,仔细阅读STM32的参考手册和数据手册,了解每个引脚的复用功能和电气特性,以便做出正确的选择。在实际应用中,可能还需要通过实验和调试来验证所选模式是否满足设计要求。
2.LED接线图





3.LED驱动文件封装LED.c和LED.h
头文件led.h

#ifndef __LED_H
#define __LED_H        //避免重复引用



#endif


源代码led.c
1.RCC_APB2PeriphClockCmd()函数
使能端口时钟(PC)
2.GPIO_Init()函数
定义结构体,GPIO结构体成员初始化
配置输出模式(PP)
输出速率(50MHZ)
2.GPIO_SetBits()函数
初始化PC8电平(高)
LED.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int main(void)
{
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
       
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        while (1)
        {
                GPIO_ResetBits(GPIOA, GPIO_Pin_0);
                Delay_ms(500);
                GPIO_SetBits(GPIOA, GPIO_Pin_0);
                Delay_ms(500);
               
                GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
                Delay_ms(500);
                GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
                Delay_ms(500);
        }
}




四.GPIO输入:按键和传感器
1)接线图








#include "stm32f10x.h"                  // Device header
#include "Delay.h"

void Key_Init(void)
{
        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_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
}

uint8_t Key_GetNum(void)
{
        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;
        }
        if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
        {
                Delay_ms(20);
                while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);
                Delay_ms(20);
                KeyNum = 2;
        }
       
        return KeyNum;
}




#include "Key.h"

uint8_t KeyNum;

int main(void)
{
        LED_Init();
        Key_Init();
       
        while (1)
        {
                KeyNum = Key_GetNum();
                if (KeyNum == 1)
                {
                        LED1_Turn();
                }
                if (KeyNum == 2)
                {
                        LED2_Turn();
                }
        }
}




————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_55389449/article/details/139620779

使用特权

评论回复
沙发
泰山神泉| | 2025-5-7 09:02 | 只看该作者
谢谢,大师的分享了。受益匪浅!!!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

92

主题

4252

帖子

4

粉丝