嵌入式学习--江协stm32day1

失踪人口回归了,stm32的学习比起51要慢一些,因为涉及插线,可能存在漏插,不牢固等问题。

相对于51直接对寄存器的设置,stm32因为是32位修改起来比较麻烦,江协课程是基于标准库的,是对封装函数进行操作,这要求我们对于模块的使用在开始就规划好。

GPIO通用输入输出口

APB2是外设总线

输入模式

  1. 浮空输入
    • 原理:GPIO 端口无内部上拉或下拉电阻,电平状态完全由外部输入决定,引脚悬空时电平不确定。
    • 使用场景:用于串口通信接收端(如 UART、USART 的 RX 引脚 ),接收外部设备电平变化信号;检测有稳定高低电平的外部传感器信号(如霍尔、红外传感器 );外部中断信号输入检测;数字输入信号检测。
    • 特点:能真实反映外部电平,但易受干扰,引脚悬空时读数无参考意义。
  2. 上拉输入
    • 原理:内部连接上拉电阻,无外部输入信号时,GPIO 端口保持高电平。
    • 使用场景:机械按键或拨动开关输入,未按下时为高电平,按下接地变低电平;IIC 通信 SDA 引脚,保证总线数据传输默认高电平;SPI 通信从设备选择引脚(NSS),无信号时保持高,主设备选择时拉低 ;继电器状态等开关量信号输入检测;电源检测引脚,检测电源供电状态。
    • 特点:确保无外部信号时输入为高电平,增强信号稳定性,防信号漂移。
  3. 下拉输入
    • 原理:内部连接下拉电阻,无外部输入信号时,GPIO 端口保持低电平。
    • 使用场景:CAN_RX 引脚接收 CAN 总线信号,确保总线无信号时引脚低电平;按钮接地触发的按键输入,未按下时低电平,按下拉高 ;默认低电平的数字电路信号输入;下拉电阻保持低电平的光电开关等传感器输入;检测外部设备低电平状态的电路。
    • 特点:确保无外部信号时输入为低电平,适用于外部信号常态为高的检测场景。
  4. 模拟输入
    • 原理:输入信号不经施密特触发器处理,直接接入内部 ADC,将模拟信号转为数字信号。
    • 使用场景:连接温度、光照、湿度、气压等模拟传感器采集信号;电池电压检测;电流检测(通过分流电阻和运算放大器转换为电压信号 );光强检测等。
    • 特点:用于采集连续变化的模拟量,供 MCU 处理分析。

输出模式

  1. 推挽输出
    • 原理:由两个互补晶体管组成,可输出高电平(接 VDD )和低电平(接 VSS ),能向负载灌电流或抽取电流,导通损耗小、效率高。
    • 使用场景:驱动 LED、继电器、蜂鸣器;控制小型直流电机;SPI 通信的 SCK、MOSI、MISO 等需强电平信号的总线通信引脚;各类状态指示灯控制。
    • 特点:驱动能力强,可快速切换高低电平,适合直接驱动数字负载。
  2. 开漏输出
    • 原理:输出端类似三极管集电极,只能输出低电平(接 VSS ),输出高电平时为高阻态,需外部上拉电阻拉高。
    • 使用场景:IIC 总线通信的 SCL 和 SDA 引脚;多设备共享数据线的通信总线;GPIO 中断信号输出(通过外部上拉电阻共享中断信号线 );不同电压域电源管理切换电路;电平转换(适配不同电压器件 )。
    • 特点:可实现线与逻辑,方便电平匹配,适合多设备通信及跨电压域应用,但高电平需外部上拉。
  3. 复用推挽输出
    • 原理:GPIO 端口由片上外设控制,如定时器 PWM 输出、SPI 的 MOSI 和 MISO 等,兼具推挽输出特性,能主动提供电流驱动负载。
    • 使用场景:UART 通信发送端(TX 引脚 );SPI 通信的时钟线(SCK)、主输出从输入(MOSI)、主输入从输出(MISO)引脚 ;CAN 通信发送端(TX 引脚 );伺服电机或 DC 电机控制的 PWM 信号输出;外部设备的时钟、使能等控制信号输出。
    • 特点:用于特定外设功能,借助推挽输出特性提供稳定驱动。
  4. 复用开漏输出
    • 原理:GPIO 端口由片上外设控制,输出模式为开漏输出,高电平需外部或内部上拉电阻,可实现线与逻辑。
    • 使用场景:IIC 通信的 SDA 和 SCL 引脚(多设备共享 );SMBus 通信(类似 IIC 协议 );1 - Wire 单总线通信;MCU 接收多个外设中断信号(避免电平冲突 );电源管理信号(控制电压域转换 )。
    • 特点:适用于特定外设多设备共享总线通信,需外部上拉电阻配合,可解决电平冲突问题。

这里只需要大概了解一下即可,后面结合具体外设理解

GPIO在后面会频繁使用,我们要熟悉使用流程

1.配置时钟2.初始化结构体

GPIO输出

以LED介绍GPIO的使用

#include "stm32f10x.h"                  // Device header
void LED_Init()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2);
}
void LED1_ON()
{GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
void LED1_OFF()
{GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
void LED1_Turn()
{if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)==0){GPIO_SetBits(GPIOA,GPIO_Pin_1);}else{GPIO_ResetBits(GPIOA,GPIO_Pin_1);}
}

LED闪烁

#include "stm32f10x.h"                  // Device header
#include "Delay.h"int main(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟//使用各个外设前必须开启时钟,否则对外设的操作无效/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;					//定义结构体变量GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式,赋值为推挽输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				//GPIO引脚,赋值为第0号引脚GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度,赋值为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);					//将赋值后的构体变量传递给GPIO_Init函数//函数内部会自动根据结构体的参数配置相应寄存器//实现GPIOA的初始化/*主循环,循环体内的代码会一直循环执行*/while (1){/*设置PA0引脚的高低电平,实现LED闪烁,下面展示3种方法*//*方法1:GPIO_ResetBits设置低电平,GPIO_SetBits设置高电平*/GPIO_ResetBits(GPIOA, GPIO_Pin_0);					//将PA0引脚设置为低电平Delay_ms(500);										//延时500msGPIO_SetBits(GPIOA, GPIO_Pin_0);					//将PA0引脚设置为高电平Delay_ms(500);										//延时500ms/*方法2:GPIO_WriteBit设置低/高电平,由Bit_RESET/Bit_SET指定*/GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);		//将PA0引脚设置为低电平Delay_ms(500);										//延时500msGPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);			//将PA0引脚设置为高电平Delay_ms(500);										//延时500ms/*方法3:GPIO_WriteBit设置低/高电平,由数据0/1指定,数据需要强转为BitAction类型*/GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);		//将PA0引脚设置为低电平Delay_ms(500);										//延时500msGPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);		//将PA0引脚设置为高电平Delay_ms(500);										//延时500ms}
}

LED流水灯

#include "stm32f10x.h"                  // Device header
#include "Delay.h"int main(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟//使用各个外设前必须开启时钟,否则对外设的操作无效/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;					//定义结构体变量GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式,赋值为推挽输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;				//GPIO引脚,赋值为所有引脚GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度,赋值为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);					//将赋值后的构体变量传递给GPIO_Init函数//函数内部会自动根据结构体的参数配置相应寄存器//实现GPIOA的初始化/*主循环,循环体内的代码会一直循环执行*/while (1){/*使用GPIO_Write,同时设置GPIOA所有引脚的高低电平,实现LED流水灯*/GPIO_Write(GPIOA, ~0x0001);	//0000 0000 0000 0001,PA0引脚为低电平,其他引脚均为高电平,注意数据有按位取反Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0002);	//0000 0000 0000 0010,PA1引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0004);	//0000 0000 0000 0100,PA2引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0008);	//0000 0000 0000 1000,PA3引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0010);	//0000 0000 0001 0000,PA4引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0020);	//0000 0000 0010 0000,PA5引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0040);	//0000 0000 0100 0000,PA6引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0080);	//0000 0000 1000 0000,PA7引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100ms}
}

   蜂鸣器

这个是有源蜂鸣器   ,没法唱天空之城,差评

#include "stm32f10x.h"                  // Device header
#include "Delay.h"int main(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//开启GPIOB的时钟//使用各个外设前必须开启时钟,否则对外设的操作无效/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;					//定义结构体变量GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式,赋值为推挽输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;				//GPIO引脚,赋值为第12号引脚GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度,赋值为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);					//将赋值后的构体变量传递给GPIO_Init函数//函数内部会自动根据结构体的参数配置相应寄存器//实现GPIOB的初始化/*主循环,循环体内的代码会一直循环执行*/while (1){GPIO_ResetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为低电平,蜂鸣器鸣叫Delay_ms(100);							//延时100msGPIO_SetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为高电平,蜂鸣器停止Delay_ms(100);							//延时100msGPIO_ResetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为低电平,蜂鸣器鸣叫Delay_ms(100);							//延时100msGPIO_SetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为高电平,蜂鸣器停止Delay_ms(700);							//延时700ms}
}

GPIO输入

 按键控制LED

IPU为上拉输入(这里还没学定时器,还是用delay消抖)

#include "stm32f10x.h"                  // Device header
#include "Delay.h"/*** 函    数:按键初始化* 参    数:无* 返 回 值:无*/
void Key_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟/*GPIO初始化*/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);						//将PB1和PB11引脚初始化为上拉输入
}/*** 函    数:按键获取键码* 参    数:无* 返 回 值:按下按键的键码值,范围:0~2,返回0代表没有按键按下* 注意事项:此函数是阻塞式操作,当按键按住不放时,函数会卡住,直到按键松手*/
uint8_t Key_GetNum(void)
{uint8_t KeyNum = 0;		//定义变量,默认键码值为0if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)			//读PB1输入寄存器的状态,如果为0,则代表按键1按下{Delay_ms(20);											//延时消抖while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);	//等待按键松手Delay_ms(20);											//延时消抖KeyNum = 1;												//置键码为1}if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)			//读PB11输入寄存器的状态,如果为0,则代表按键2按下{Delay_ms(20);											//延时消抖while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);	//等待按键松手Delay_ms(20);											//延时消抖KeyNum = 2;												//置键码为2}return KeyNum;			//返回键码值,如果没有按键按下,所有if都不成立,则键码为默认值0
}

光敏电阻控制蜂鸣器

  也是化身电报专家了

#include "stm32f10x.h"                  // Device header/*** 函    数:光敏传感器初始化* 参    数:无* 返 回 值:无*/
void LightSensor_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);						//将PB13引脚初始化为上拉输入
}/*** 函    数:获取当前光敏传感器输出的高低电平* 参    数:无* 返 回 值:光敏传感器输出的高低电平,范围:0/1*/
uint8_t LightSensor_Get(void)
{return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);			//返回PB13输入寄存器的状态
}

        学习stm32过程中,感觉自己真的要成为工程师了,cv工程师(bushi)。在使用外设前,要先去函数库找到需要使用的函数,然后一个个复制过去,然后再去查看函数的定义,配置里面的参数,需要逻辑的大多都是在主函数里面写(也有可能是入门学习的原因)

今日语录:打不倒我的,只会让我更加强大(农p无疑了)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/907856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue+elementUi+axios实现分页(MyBatis、Servlet)

vueelementUiaxios实现分页 文章目录 vueelementUiaxios实现分页1.代码实现【HTML】**【Servlet层】****【Service层】****【Dao层】** 2.总结步骤3.实现要点4.注意事项4.注意事项 注:此项目 前端为 html、 后端采用 mybatis、servlet实现 1.代码实现 【HTML】…

vue-10( 动态路由匹配和路由参数)

动态路由匹配和路由参数 动态路由匹配是 Vue Router 的一个强大功能,它允许你创建灵活且可重用的路由。您可以使用参数来捕获 URL 的动态段,而不是为每个可能的值定义特定路由。这在处理具有唯一标识符的资源(如用户配置文件、产品详细信息或…

劫持进程注入

劫持进程注入和远程线程注入的区别就是 远程线程注入是向一个正在运行中的进程注入 而劫持进程注入则是自己打开一个进程(以挂起的方式) 然后再进行注入的操作 这样做的原因是当进程在挂起的状态时他的所有线程都是处于未启用的阶段 这样就可以避免目标进程的反注入线程的…

uni-app学习笔记二十--pages.json页面路由pages设置

uni-app 通过 pages 节点配置应用由哪些页面组成,pages 节点接收一个数组,数组每个项都是一个对象,其属性值如下: 属性类型默认值描述pathString配置页面路径styleObject配置页面窗口表现,配置项参考下方 pageStylene…

VScode编译调试debug,gpu的cuda程序,Nsight

进行下面操作的前提是,我们的环境已经能跑简单的CUDA程序了。 一、安装Nsight 二、创建launch.json文件 {"version": "0.2.0","configurations": [{"name": "CUDA C: Launch","type": "cuda-gdb…

链表题解——合并两个有序链表【LeetCode】

1. 算法思路 这段代码的核心思想是 合并两个有序链表。具体步骤如下: 初始化哨兵节点: 创建一个哨兵节点 dummy,用于简化链表操作,避免处理头节点的特殊情况。使用指针 cur 指向 dummy,用于构建新的链表。 遍历两个链…

K8S集群主机网络端口不通问题排查

一、环境: k8s: v1.23.6 docker: 20.10.14 问题和故障现象:devops主机集群主机节点到端口8082不通(网络策略已经申请,并且网络策略已经实施完毕),而且网络实施人员再次确认,网络策…

qemu安装risc-V 64

参考这篇文章https://developer.aliyun.com/article/1323996,其中在wsl下面安装可能会报错环境变量中有空格。 # clean_path.sh#!/bin/bash# 备份旧 PATH OLD_PATH"$PATH"# 过滤掉包含空格、制表符、换行的路径 CLEAN_PATH"" IFS: read -ra PA…

python爬虫:RoboBrowser 的详细使用

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、RoboBrowser概述1.1 RoboBrowser 介绍1.2 安装 RoboBrowser1.3 与类似工具比较二、基本用法2.1 创建浏览器对象并访问网页2.2 查找元素2.3 填写和提交表单三、高级功能3.1 处理文件上传3.2 处理JavaScript重定向3.3…

CTFSHOW-WEB-36D杯

给你shell 这道题对我这个新手还是有难度的&#xff0c;花了不少时间。首先f12看源码&#xff0c;看到?view_source&#xff0c;点进去看源码 <?php //Its no need to use scanner. Of course if you want, but u will find nothing. error_reporting(0); include "…

CentOS_7.9 2U物理服务器上部署系统简易操作步骤

近期单位网站革新&#xff0c;鉴于安全加固&#xff0c;计划将原有Windows环境更新到Linux-CentOS 7.9&#xff0c;这版本也没的说&#xff08;绝&#xff09;了&#xff08;版&#xff09;官方停止更新&#xff0c;但无论如何还是被sisi的牵挂着这一大批人&#xff0c;毕竟从接…

LVS-DR高可用-Keepalived

目录 Keepalved双机热备 核心概念 关键组件 工作流程 实例环境 配置keepalived Web服务器配置 Keepalved双机热备 Keepalived双机热备是一种基于VRRP&#xff08;Virtual Router Redundancy Protocol&#xff0c;虚拟路由冗余协议&#xff09;实现的高可用性解决方案&am…

Polar编译码(SCL译码)和LDPC编译码(BP译码)的matlab性能仿真,并对比香农限

目录 1.算法仿真效果 2.算法涉及理论知识概要 2.1香农极限 2.2 Polar码编译码原理与SCL译码 2.3 LDPC码编译码原理与BP译码 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2024b仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a…

AI 产品的 MVP 构建逻辑:Prompt 工程 ≠ 产品工程?(实战增补篇)

一. 系统思维&#xff1a;产品工程的全局把控&#xff08;实战增补篇&#xff09; 1. 某智能风控系统的弹性架构实践 某消费金融公司在开发「30 秒极速贷」产品时&#xff0c;面临两大挑战&#xff1a; Prompt 优化困境&#xff1a;传统风控模型依赖 “提取用户信用报告关键…

Unity程序集

对于Unity的程序集&#xff0c;具体内容可以参考Unity官方文档&#xff0c;程序集定义 - 预定义程序集 比如Unity的默认程序集&#xff0c;Assembly-CSharp.dll&#xff0c;还有其他的比如 Assembly-CSharp-Editor.dll&#xff0c;Assembly-CSharp-firstpass.dll 没有指定或…

【架构艺术】平衡技术架构设计和预期的产品形态

近期笔者因为工作原因&#xff0c;开始启动team内部部分技术项目的重构。在事情启动的过程中&#xff0c;内部对于这件事情的定性和投入有一些争论&#xff0c;但最终还是敲定了下来。其中部分争论点主要在于产品形态&#xff0c;因为事情涉及到跨部门合作&#xff0c;所以产品…

React和原生事件的区别

一、核心差异对比表 维度原生事件React 事件绑定语法HTML 属性&#xff08;onclick&#xff09;或 DOM API&#xff08;addEventListener&#xff09;JSX 中使用驼峰式属性&#xff08;onClick&#xff09;绑定位置直接绑定到具体 DOM 元素统一委托到根节点&#xff08;React …

大模型-modelscope下载和使用chatglm3-6b模型

前言 由于官方chatglm3-6b大模型文件下载比较慢&#xff0c;找到国内modelscope代替方案 1.SDK下载 pip install modelscope2.下载大模型文件 ✅方法1:通过pip下载 1.安装 setuptools 在当前使用的 Python 环境中安装 setuptools pip install setuptools2.通过如下命令安…

【unity游戏开发——编辑器扩展】AssetDatabase公共类在编辑器环境中管理和操作项目中的资源

注意&#xff1a;考虑到编辑器扩展的内容比较多&#xff0c;我将编辑器扩展的内容分开&#xff0c;并全部整合放在【unity游戏开发——编辑器扩展】专栏里&#xff0c;感兴趣的小伙伴可以前往逐一查看学习。 文章目录 前言一、AssetDatabase常用API1、创建资源1.1 API1.2 示例 …

css实现文字渐变

在前端开发中&#xff0c;给文字设置渐变色是完全可以实现的&#xff0c;常用的方式是结合 CSS 的 background、-webkit-background-clip 和 -webkit-text-fill-color 属性。下面是一个常见的实现方法&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> …