物联网|可变参数的使用技巧|不一样的点灯实验|访问外设的寄存器|操作寄存器实现点灯|硬件编程的基本流程-学习笔记(11)

news2024/9/20 22:48:44

文章目录

  • 可变参数的使用技巧
  • 第三阶段-初级实验
    • Lesson5:不一样的点灯实验---学习I/O的输出
  • ☆点灯的电路图分析
    • 1 一起看看点灯的电路图
    • Tip1:另一种点灯的电路
    • Tip1:如何访问外设的寄存器
    • 2 STM32F407中操作GPIO的方法
  • 通过直接操作寄存器实现点灯实验
    • Tip1:硬件编程的基本流程
  • 2代码实现及分析

可变参数的使用技巧

void fixed_args_func(int a, double b, char c)
{
        printf("a = 0x%p\n", &a);
        printf("b = 0x%p\n", &b);
        printf("c = 0x%p\n", &c);
if(&a==MCULowPower)
}
void var_args_func(const char * fmt, ...)
{
    ... ...
}
void var_args_func(const char * fmt, ...)
{
    char    *ap;

    ap = ((char*)&fmt) + sizeof(fmt);
    printf("%d\n", *(int*)ap);

    ap =  ap + sizeof(int);
    printf("%d\n", *(int*)ap);

    ap =  ap + sizeof(int);
    printf("%s\n", *((char**)ap));
}

在这里插入图片描述

第三阶段-初级实验

Lesson5:不一样的点灯实验—学习I/O的输出

1: 理论基础 CPU工作机制 如何对CPU编程
外设的的原理
2:代码实现以及分析
3:在板实验和调试
嵌入式开发必知会之三—
了解LED☆点灯的电路图分析区
STM32F407中GPIO的特性及操作方法
1.LED的功能,特点和用途
在这里插入图片描述

发光二极管
在这里插入图片描述

2.LED的工作原理

课后作业:请同学们课后了解电阻,电容和电感的功能,特点,用途及电路符号表示

☆点灯的电路图分析

1 一起看看点灯的电路图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Tip1:另一种点灯的电路

1 STM32F407中GPIO的特性
Tip1:如何访问外设的寄存器

2 STM32F407中操作GPIO的方法

  • 输出的配置

  • 高低电平的配告

  • 手册描述
    通用IO (GPIO)
    除非特别说明,否则本部分适用于整个STM32F4xx系列。

    • 7.1 GPIO简介
      每个通用IO端口包括4个32位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR和 GPIOx_PUPDR)、2个32位数据寄存器(GPIOx_IDR和
      GPIOx_ODR)、1个 32位置位/复位寄存器(GPIOx_BSRR)、1个32位锁定寄存器(GPIOx_LCKR)和2个32位复用功能选择寄存器(GPIOx_AFRH 和GPIOx_AFRL)。

    • 7.2 GPIO主要特性受控IO多达16个
      输出状态:推挽或开漏+上拉/下拉
      从输出数据寄存器(GPIOx_ODR)或外设(复用功能输出)输出数据可为每个IO选择不同的速度
      输入状态:浮空、上拉/下拉、模拟
      将数据输入到输入数据寄存器(GPIOx_IDR)或外设(复用功能输入)置位和复位寄存器(GPIOx_BSRR),对GPIOx_ODR具有按位写权限锁定机制(GPIOx_LCKR),可冻结IO配置
      模拟功能
      复用功能输入/输出选择寄存器(一个IO最多可具有16个复用功能>快速翻转,每次翻转最快只需要两个时钟周期
      引脚复用非常灵活,允许将IO引脚用作GPIO或多种外设功能中的一种

    • 7.3 GPIO功能描述
      根据数据手册中列出的每个lO端口的特性,可通过软件将通用IVO(GPIO)端口的各个端口位分别配置为多种模式;
      输入浮空
      输入上拉
      输入下拉模拟功能
      具有上拉或下拉功能的开漏输出具有上拉或下拉功能的推挽输出具有上拉或下拉功能的复用功能推挽具有上拉或下拉功能的复用功能开漏
      每个IO端口位均可自由编程,但IO端口寄存器必须按32位字、半字或字节进行访问。GPIOx_BSRR寄存器旨在实现对GPIO ODR寄存器进行原子读取/修改访问。这样便可确保在读取和修改访问之间发生中断请求也不会有问题。
      在这里插入图片描述

    • 8.3.10 Output配置
      在这里插入图片描述 在这里插入图片描述
      当lO口编程为输出时:。输出缓冲区被启用:
      在这里插入图片描述

    -漏极模式:输出寄存器中的“O”激活N-MOS,而“1”激活N-MOS
    在输出寄存器中离开Hi-Z端口(P-MOS从未激活)
    推挽模式:输出寄存器中的“O”激活N-MOS,而输出寄存器中的“1”激活P-MoS
    施密特触发器输入被激活
    弱上拉和下拉电阻是否激活取决于GPIOx_PUPDR寄存器中的值
    l/O引脚上的数据在每个AHB1时钟周期中被采样到输入数据寄存器中
    对输入数据寄存器的读访问获得I/O状态。
    对输出数据寄存器的区域访问获得最后写入的值。
    图29显示了IO端口位的输出配置。
    原文:
    8.3.10 Output configuration
    When the I/O port is programmed as output:
    • The output buffer is enabled:
    – Open drain mode: A “0” in the Output register activates the N-MOS whereas a “1”
    in the Output register leaves the port in Hi-Z (the P-MOS is never activated)
    – Push-pull mode: A “0” in the Output register activates the N-MOS whereas a “1” in
    the Output register activates the P-MOS
    • The Schmitt trigger input is activated
    • The weak pull-up and pull-down resistors are activated or not depending on the value
    in the GPIOx_PUPDR register
    • The data present on the I/O pin are sampled into the input data register every AHB1
    clock cycle
    • A read access to the input data register gets the I/O state
    • A read access to the output data register gets the last written value
    Figure 29 shows the output configuration of the I/O port bit.

Tip1:如何访问外设的寄存器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2 STM32F407中操作GPIO的方法

  • 输出的配置
  • 高低电平的配置

通过直接操作寄存器实现点灯实验

  • 实验的需求分析(实验目的)
    • 学会基本的硬件操作—I/O的输出高低电平
    • 操作学习利用系统时钟实现较为精确的延时
    • 学习规范的模块化编程
    • 学会使用CMSIS的支持库
  • 通过直接操作寄存器实现点灯代码
  • 代码下载及调试演示
    1程序流程分析
    • 如何利用系统时钟实现较为精确的延时
      9.5SysTick 定时器
      9.5.1 为什么要有SysTick 定时器
      Cortex-M处理器内集成了一个小型的名为SysTick(系统节拍)的定时器,它属于NVIC的一部分,且可以产生SysTick 异常(异常类型#15)。SysTick 为简单的向下计数的24位计数器,可以使用处理器时钟或外部参考时钟(通常是片上时钟源)。
      在现代操作系统中,需要一个周期性的中断来定期触发OS内核,如用于任务管理和上下文切换,处理器也可以在不同时间片内处理不同任务。处理器设计还需要确保运行在非特权等级的应用任务无法禁止该定时器,否则任务可能会禁止SysTick 定时器并锁定整个系统。
      之所以在处理器内增加一个定时器,是为了提高软件的可移植性。由于所有的Cortex-M处理器都具有相同的SysTick定时器,为一种Cortex-M3/M4微控制器实现的OS也能适用于其他的Cortex-M3/M4微控制器。
      若应用中不需要使用OS,SysTick定时器可用作简单的定时器外设﹐用以产生周期性中断、延时或时间测量。
      9.5.2SysTick定时器操作

      在这里插入图片描述
      如表9.6所示,SysTick定时器中存在4个寄存器。CMSIS-Core头文件中定义了一个名为SysTick的结构体,方便对这些寄存器的访问。
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

      SysTick内部包含一个24位向下计数器,如图9.15所示。它会根据处理器时钟或一个参考时钟信号(在ARM Cortex-M3或Cortex-M4 技术参考手册中也被称作STCLK)来减小计数。参考时钟信号取决于微控制器的实际设计,有些情况下﹐它可能会不存在。由于要检测上升沿,参考时钟至少得比处理器时钟慢两倍。
      在设置控制和状态寄存器的第О位使能该计数器后,当前值寄存器在每个处理器时钟周期或参考时钟的上升沿都会减小。若计数减至0,它会从重加载寄存器中加载数值并继续运行。
      另外一个寄存器为SysTick校准值寄存器。它为软件提供了校准信息。由于CMSIS-Core提供了一个名为SystemCoreClock 的软件变量(CMSIS 1.2 及之后版本可用,CMSIS 1.1或之前版本则使用变量SystemFrequency) ,因此它就未使用SysTick校准值寄存器。系统初始
      化函数SystemInit()函数设置了该变量,而且每次系统时钟配置改变时都要对其进行更新。这种软件手段比利用SysTick校准值寄存器的硬件方式更灵活。
      SysTick寄存器的细节如表9.7~表9.10所示。
      9.5.3使用 SysTick定时器
      若只想产生周期性的SysTick中断,最简单的方法就是使用CMSIS-Core函数 SysTick_Config :
      uint32_t SysTick_Conf ig(uint32_t ticks) ;
      该函数将SysTick 中断间隔设置为ticks,使能计数器使用处理器时钟,然后设置SysTick异常为最低优先级。
      例如,若要在30MHz的时钟频率下产生1kHz的SysTick异常,则可以使用:SysTick_Config(SystemCoreClock / 1000) ;
      变量SystemCoreClock应该存放正确的时钟频率数值,也就是30×10°。另外,只需使用:
      SysTick_Config( 30000) ;
      //30MHz / 1000 = 30000
      SysTick_Handler( void)的触发频率就变成了1kHz。
      若SysTick_Config 函数的输入参数不满足24位重加载数值寄存器(大于0xFFFFFF),SysTick_Config函数返回1,否则会返回0。
      许多情况下,可能会使用参考时钟或者不想使能SysTick 中断,那么就不要使用SysTick_Config 函数。此时需要直接操作 SysTick寄存器,推荐使用下面的流程:
      (1)将0写人 SysTick->CTRL禁止 SysTick定时器。这个操作是可选的。若重用了其他代码,则由于SysTick之前可能已经使能过了,因此本操作是推荐使用的。
      (2)将新的重加载值写入SysTick->LOAD,重加载值应该为周期数减1。
      (3)将任何数值写人SysTick当前值寄存器SysTick->VAL,该寄存器会被清零
      (4)写入 SysTick控制和状态寄存器SysTick->CTRL启动SysTick定时器。
      由于SysTick定时器向下计数到0,因此,若要设置SysTick周期为1000,则应该将重加载值(SysTick->LOAD)设置为999。
      若要在轮询模式中使用SysTick定时器,则可以利用SysTick 控制和状态寄存器(SysTick->CTRL)中的计数标志来确定定时器何时变为0。例如,可以将SysTick定时器设置为特定数值,然后等它变为0,并以此实现延时:
      SysTick-> CTRL = 0;
      /禁止SysTick
      SysTick - > LOAD = OxFF;
      //计数范围255~0 (256个周期)
      SysTick-> VAL = 0 ;
      //清除当前值和计数标志
      SysTick- > CTRL = 5;
      //使能SysTick定时器并使用处理器时钟 5的二进制是0101
      while ( (SysTick - >CTRL & Ox00010000) == 0);//等待计数标志置位
      SysTick - > CTRL= 0 ;
      /!禁止 SysTick
      若要将SysTick中断用作在一定时间后触发的单发操作,则可以将重加载值减小12个周期,以补偿中断等待时间。例如,要使SysTick定时器在300个时钟周期后执行:
      volatile int SysTickFired;
      1/全局软件标志,表示 SysTickAlarm已执行

      SysTick-> CTRL= 0 ;
      /禁止 SysTick
      SysTick -> LOAD = (300-12);
      //设置重加载值,由于异常等待减去12
      SysTick - > VAL=0;
      //将当前值清为0
      SysTickFired = 0;
      //将软件标志设为0
      SysTick - > CTRL= 0x7;
      1/使能SysTick,使能 SysTick异常且使用处理器时钟 0x7=0111
      while (SysTickFired == 0 );
      1/等待SysTick处理将软件标志置位
      在单发SysTick处理中﹐需要禁止SysTick,以防SysTick 异常再次产生。若由于所需的处理任务花费的时间太长而导致挂起状态再次置位﹐则可能还需要清除SysTick 的挂起状态:
      void SysTick_Handler(void)
      // SYSTICK异常处理
      {
      SysTick ->CTRL = Ox0 ;
      /1禁止SysTick
      …;
      //执行所需任务
      SCB->ICSR | = 1 <<25;
      //清除SYSTICK挂起位,防止再次挂起
      sysTickFired++ ;
      //更新软件标志,主程序据此可以知道SysTick
      定时任
      务已执行
      return;
      若同时产生了另一个异常,则 SysTick异常可能会延迟。
      SysTick 定时器可用于时间测量。例如,可以用下面的代码测量一个短函数的持续时间:
      unsigned int start_time,stop_time,cycle_count;
      SysTick - > CTRL= 0 ;
      /I/禁止SysTick
      SysTick - > LOAD =0xFFFFFFFF;
      //将重加载值设置为最大
      SysTick -> VAL= 0 ;
      //将当前值清为0
      SysTick ->CTRL= 0x5;
      /1使能SysTick,使用处理器时钟
      while(SysTick- > VAL != 0);
      //等待SysTick重加载
      start_time = SysTick - > VAL;
      //获取开始时间
      function();
      //执行要测量的函数
      stop_time =SysTick- > VAL;
      1/获取停止时间
      由于SysTick定时器向下计数, start_time的数值比 stop_time要大。可能还需要在时间
      测量的结尾检查一下count_flag。若count_tlag 置位时测则风的NE大了 A旧 t六敝还要能SysTick异常且在SysTick处理中计算SyslicK T效奋恤出的认效。nW川心欢u一考虑SysTick 异常。
      SysTick定时器还提供了一个校准值寄存器。若该信息存在,则SysTick->CALIB寄存
      器的最低24位表示要得到10ms SysTick间隔所需的重加载值。个过,计多似丘润’P开仅有这个信息,TENMS位域读出为0。CMSIS-Core方案则提供」一个表水频平信忌的队什受量,这种方式更加灵活且得到了多数微控制器供应商的支持。
      可以利用 SysTick校准值寄存器的第31位确定参考时钟是否存在。9.5.4其他考虑
      在使用SysTick定时器时需要考虑以下几点:
      . SysTick定时器中的寄存器只能在特权状态下访问。·参考时钟在一些微控制器设计中可能会不存在。
      ·若应用中存在嵌入式OS,SysTick定时器会被OS使用,因此就不能冉放应用在方使用了。
      ·当处理器在调试期间暂停时,SysTick定时器会停止计数。
      ·根据微控制器的实际设计,SysTick定时器可能会在某些休眠模式中停止计数。

/初始化延迟函数
//当使用uoo=的时候,此函数会初始化uco=的时钟节拍7/SYSTICK的时钟固定为AHB时钟的1/8
//sYSCLK:系统时钟频率
void delay_init (u8 sYSCLK)
{
SysTick->CTRL&=~(1<<2);//SYSTICR使用外部时钟源 只操作了第2位
fac_us=SYSCLK/8;//每个us需要的systick时钟数
fac_ms= (u16) fac_us*1000;//每个ns需要的systick时钟数
}
  • 如何初始化I/O

Tip1:硬件编程的基本流程

1、初始化硬件:总线始终初始化,申请区域存放寄存器,配置IO的输出形式,设置IOspeed,是否需要AF(第2功能)

2代码实现及分析

#include "sys tick.h"
#include "led.h"

#define SYS_MAX_CLK 168

int main(void)
{
		Led_init();//初始化LED0
		delay_init(SYS_MAX_CLK);//初始化系统时钟
		while(1)
		{
			LED0_ON;//点亮LED0
			delay_ms(1000);//延时1s
			LED0_OFF;//关闭led
			delay_ms(1000);//延时1s
		}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

数据可视化(4)散点图及面积图

1.简单散点图 #散点图 #scatter(x,y) x数据&#xff0c;y数据 x[i for i in range(10)] y[random.randint(1,10) for i in range(10)] plt.scatter(x,y) plt.show()2.散点图分析 #分析广告支出与销售收入相关性 dfcarpd.read_excel(广告支出.xlsx) dfdatapd.read_excel(销售…

VS开发Qt程序,无法打印QDebug调试信息,VS进行Qt开发时Qt Designer无法使用“转到槽”选项

VS开发Qt程序&#xff0c;无法打印QDebug调试信息&#xff0c;VS进行Qt开发时Qt Designer无法使用“转到槽”选项 VS开发Qt程序&#xff0c;无法打印QDebug调试信息VS进行Qt开发时Qt Designer无法使用“转到槽”选项 VS开发Qt程序&#xff0c;无法打印QDebug调试信息 解决方案…

使用Idea提交项目到远程仓库

使用Idea提交项目到远程仓库 1.在Idea中打开本地要推送的项目2.创建远程仓库并提交 1.在Idea中打开本地要推送的项目 tips: 首先你得有git工具&#xff0c;没有的话可以参考下面的这篇文章 git与gitee结合使用&#xff0c;提交代码&#xff0c;文件到远程仓库 从导航栏中选择 V…

如何快速开拓海外华人市场?附解决方案!

开拓华人市场对于企业来说是非常必要的。华人市场庞大且潜力巨大&#xff0c;拥有巨额的消费能力。随着华人经济的不断增长&#xff0c;越来越多的企业开始意识到华人市场的重要性。 通过开拓华人市场&#xff0c;企业可以获得更多的销售机会&#xff0c;并且在竞争激烈的市场…

Go语言time库,时间和日期相关的操作方法

time库 用于处理时间、日期和时区的核心库。在实际开发中&#xff0c;常常需要与时间打交道&#xff0c;例如记录日志、处理时间差、计算时间间隔等等。因此&#xff0c;掌握time库的使用方法对于Go开发者来说非常重要。 在Go语言中&#xff0c;时间表示为time.Time类型&…

嵌入式开发的学习内容和技能包括:

. 熟悉C语言编程 掌握基础电子知识&#xff0c;如数字电路、模拟电路和单片机 .熟练掌握嵌入式操作系统的原理、内核架构和应用&#xff0c;如Linux、RTOS等 了解各种外设接口及其驱动程序开发&#xff0c;如SPI、I2C、USART等 熟悉常用的嵌入式开发工具和软件工程流程&#…

【ASPICE】:学习记录

学习记录 ASPICE中文资料什么是ASPICE过程参考模型 ASPICE全称“Automotive Software Process Improvement and Capability dEtermination”&#xff0c;即“汽车软件过程改进及能力评定”模型框架 ASPICE中文资料 主要资料来源 什么是ASPICE 过程参考模型

神经网络原理概述

文章目录 1.神经元和感知器1.1.什么是感知器1.2.什么是单层感知器1.3.多层感知机&#xff08;Multi-Layer Perceptron&#xff0c;MLP&#xff09; 2.激活函数2.1.单位阶跃函数2.2.sigmoid函数2.3.ReLU函数2.4.输出层激活函数 3.损失函数4.梯度下降和学习率5.过拟合和Dropout6.…

python学到什么程度算入门,python从入门到精通好吗

本篇文章给大家谈谈python学到什么程度算入门&#xff0c;以及python从入门到精通好吗&#xff0c;希望对各位有所帮助&#xff0c;不要忘了收藏本站喔。 学习 Python 之 进阶学习 一切皆对象 1. 变量和函数皆对象2. 模块和类皆对象3. 对象的基本操作 (1). 可以赋值给变量(2). …

JAVA- SQL注入案例(黑马程序员)和避免 超级详细

文章目录 sql注入准备1.创建应该新的数据库用于测试&#xff1b;2.修改配置3.启动jar包4.打开网页测试5.测试sql注入 sql注入避免1. java中的登录逻辑代码2.演示sql注入3.原因5.参数化查询-PreparedStatement SQL注入是什么&#xff1f; SQL 注入&#xff08;SQL Injection&…

【Python】Web学习笔记_flask(2)——getpost

flask提供的request请求对象可以实现获取url或表单中的字段值 GET请求 从URL中获取name、age两个参数 from flask import Flask,url_for,redirect,requestappFlask(__name__)app.route(/) def index():namerequest.args.get(name)agerequest.args.get(age)messagef姓名:{nam…

【LeetCode 75】第十七题(1493)删掉一个元素以后全为1的最长子数组

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码运行结果&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给一个数组&#xff0c;求删除一个元素以后能得到的连续的最长的全是1的子数组。 我们可以先单独统计出连续为1的子数组分别长度…

命令模式-请求发送者与接收者解耦

去小餐馆吃饭的时候&#xff0c;顾客直接跟厨师说想要吃什么菜&#xff0c;然后厨师再开始炒菜。去大点的餐馆吃饭时&#xff0c;我们是跟服务员说想吃什么菜&#xff0c;然后服务员把这信息传到厨房&#xff0c;厨师根据这些订单信息炒菜。为什么大餐馆不省去这个步骤&#xf…

【JVM】(一)深入理解JVM运行时数据区

文章目录 一、JVM 运行流程二、虚拟机栈&#xff08;线程私有&#xff09;三、本地方法栈 &#xff08;线程私有&#xff09;四、方法区&#xff08;元数据区&#xff09;五、堆&#xff08;线程共享&#xff09;六、程序计数器&#xff08;线程私有&#xff09; 一、JVM 运行流…

安装Apache遇到的问题

安装Apache服务 httpd -k install -n Apache2.4 #-n后面表示自定义访问名称 问题1&#xff1a; 此时去 windows 的开始摁扭里找到控制器右键管理员运行 问题2&#xff1a; 命令行没用对 应该用&#xff1a; .\httpd -k install -n Apache2.4 #-n后面表示自定义访问名称

远程控制平台四之优化部署

服务器端打包 把服务器打成jar包对于后台开发的朋友来说小菜一碟,但对于前端开发可能有些细节要注意一下,尤其是有依赖其他第三方库的情况下,这里梳理了一下流程: File – Project Structure – Artifacts – add – JAR – From modules and dependencies 选中module和主…

前端构建(打包)工具发展史

大多同学的前端学习路线&#xff1a;三件套框架慢慢延伸到其他&#xff0c;在这个过程中&#xff0c;有一个词出现的频率很高&#xff1a;webpack 。 作为一个很出名的前端构建工具我们在网上随便一搜&#xff0c;就会有各种教程&#xff1a;loader plugin entry吧啦吧啦。 但…

嵌入式Linux的学习嵌入式一开始该怎么学?

把握以下几点&#xff1a; 文件 进程&#xff0c;线程&#xff0c;信号 进程&#xff0c;线程通信同步 网络&#xff1a;这个简单&#xff0c;就那几个API&#xff0c;TCP和udp。 嵌入式Linux 目前我正在学&#xff0c;我看到资料是正点原子&#xff0c;野火和韦东山作为参…

在中国人民大学与加拿大女王大学金融硕士项目中蜕变,成长

毕业十年后&#xff0c;还想得起大学时你的样子吗&#xff1f;有人这十年浑浑噩噩&#xff0c;或过着按部就班的日子&#xff0c;渐渐认命了&#xff1b;也有人用这十年实现了底层逆袭&#xff0c;完成了华丽的人生转身。如中国人民大学与加拿大女王大学金融硕士项目&#xff0…

栈的压入,弹出序列

栈的压入弹出序列问题可以通过模拟栈的压入和弹出过程来解决。 具体思路如下&#xff1a; 定义一个辅助栈&#xff0c;用于模拟压栈和弹栈操作。遍历给定的压栈序列&#xff0c;在每一次循环中执行以下操作&#xff1a; 将当前元素压入辅助栈。循环检查辅助栈的栈顶元素是否与…