IT评测·应用市场-qidao123.com技术社区

标题: #单片机底子 笔记二 [打印本页]

作者: 北冰洋以北    时间: 2024-9-3 06:13
标题: #单片机底子 笔记二
SPI+中断

   1.SPI总线协议

  1.1协议介绍

     
SPI接口是Motorola (motorola | Smartphones, Accessories & Smart Home Devices)首先提出的全双工三线/四线同步串行外围接口采用主从模式(Master Slave)架构。

   
时钟由Master控制,在时钟移位脉冲下,数据按位传输,高位在前,低位在后(MSB first);SPI接口有2根单向数据线,为全双工通讯。

   
SPI总线被广泛地利用在FLASH、LCD等装备与MCU间,要求通讯速率较高的场合。

    1.2 SPI总线拓扑布局

  
SPI统共有4根总线,分别是:装备选择线、时钟线、串行输出数据线、串行输入数据线。

  

    
三线布局:片选接地

  

  
三线布局:一主一从

  
四线布局:一主多从,片选线选择和哪个从机之间举行通讯

  

  

  

  1.3 SPI总线协议

  

  
起始信号:NSS的电平信号由高电平变成了低电平,阐明主机选择好了从机举行通讯

  
竣事信号:NSS的电平信号由低电平变成了高电平。

  
数据传输:SPI利用MOSI和MISO信号来传输数据,利用SCK信号举行同步。MOSI及MISO数据线在SCK的每个时钟周期传输一位数据高位在前低位在后,且数据输入输出是同时举行的。SPI每次数据传输可以 8 位或 16 位为单位,每次传输的单位数不受限制

  1.4 SPI的四种通讯模式

     
在SPI操纵中,时钟信号有两项重要的参数设置就是时钟极性(CPOL)和时钟相位(CPHA)这两项即是主从装备间数据采样的约定方式。

   
时钟极性(CPOL):设置时钟信号空闲时的电平

   
CPOL = 0,CPOL = 1

   
时钟相位(CPHA):时钟的采样边沿。

   
CPHA = 0,CPHA = 1

   

   

   
SPI四种工作模式

      
CPOL = 0,SCK在空闲状态时保持低电平。

   
CPOL = 1,SCK在空闲状态时保持高电平。

   
     2. 当CPHA = 1时,时钟线的偶数边沿会被采样。

   
CPOL = 0,SCK在空闲状态时保持低电平。

   
CPOL = 1,SCK在空闲状态时保持高电平。

   

   
注意:只有在雷同模式下的两台呆板才能举行通讯,主机根据从机的模式举行配置

   
  2. LCD液晶显示屏

  2.1 液晶的构成

  
某些物质在熔融状态或被溶剂溶解之后,尽管失去固态物质的刚性,却获得了液体的易活动性,并保存着部分晶态物质分子的各向异性有序分列,形成一种兼有晶体和液体的部分性质的中间态,这种由固态向液态转化过程中存在的取向有序流体称为液晶。

  

  

  
物理特点

  
当通电时导通,分列变得有秩序,使光线容易通过;不通电时分列紊乱,阻止光线通过。

  2.2液晶显示屏内部构造

  

  2.3 颜色深度

  
每一个像素点内都有一个RGB三基色

  
① R,G,B三基色组合形成各种颜色。

  
② 能显示的颜色数由RGB的数字信号的位数来决定

  

  
例如,以3位数字信号来表现颜色深度

  

  

         
RGB24(24位真彩色)

   
R:8位 G:8位 B:8位

   
颜色深度:2^8*2^8*2^8;

   

   
STM32G030开发版的显示屏RGB16(16位真彩色)RGB565

   
R:5位 G:6位 B:5位

   
颜色深度:2^5*2^6*2^5;

      
  3. 点亮LED屏

  实验分析

  
主机---->芯片STM32G030

  
从机---->LCD屏幕

  
屏幕的丝印(J5)

  原理与分析

  

  

  

  

  

  实验过程

  

  

  

  

  

  

  

  

  

  
在主函数里添加头文件

  

  图片显示

  
制作图片

  

  

  

  
图片取模

  
打开取模软件

  

  
生存生成.h的文件

  

  

  

  字符显示

  

  汉字显示

  

  

  
汉字显示

  

  

  4. 中断系统

  4.1根本概念

  

  
中断相称是对于突发变乱的处理过程。当遇到内部/外部的紧遽变乱需要处理时,暂时中止当前程序,转而去处理紧遽变乱,待处理完毕后,再返回被打断的程序继续向下运行。

  

  4.2 中断存在的意义

  首先中断是一个突发变乱,在执行主程序的同时能对突发变乱做出及时处理,实现程序的并行化(时间片),进而提高CPU的工作效率。假如期待程序执行完毕再去执行中断,会影响操纵系统的及时性。
         
面试题

   
时间片相识吗?

   
时间片轮转调治是一种常见的调治算法,其原理是将所有就绪状态的进程按照顺序分配一个时间片,每个进程只在时间片内执行,时间片到就被挂起,以便给其他进程机会。

       4.3 中断的处理过程

  

  
        
sp:指向栈顶的指针

   
1.

   

   
京海旧厂街老默正在杀鱼 (正常的执行程序)

   
2.

   

   
小虎找到老默跟他说强哥想吃鱼了 (产生了一个外部中断的信号)

   
3.

   

   
老默放动手里没杀完的鱼 ,把鱼放进了冰箱里 (保护现场,生存程序的当前状态)

   
4.

   

   
去强哥家领使命 (根据异常向量表举行跳转)

   
5.

   

   
做了李有田 (执行中断程序)

   
6.

   

   
回到市场接着杀没杀完的鱼 (栈规复现场,继续执行主程序)

    5. NVIC

  
(Nested Vectored Interrupt Controller) 嵌套中断向量控制器

  管理中断变乱
  
每一个中断变乱都有执行和克制两种状态,由NVIC负责将中断变乱标记为打扫和挂起两种状态。 处理器的中断可以是电平的形式的,也可以是脉冲形式的,这样中断控制器就可以处理任何中断源。

  支持中断和异常的向量化处理
  
当中断或异常发生时,处理器会将PC设定到一个指定地点(中断变乱入口函数的地点),进而跳转到指定地点举行执行,这个地点就是所谓的异常向量。由于每一个异常源大概中断变乱都会对应一个服务程序的入口地点,将这些地点按照优先级举行排布后,构成的一张表就称为异常向量表。

  
向量:有大小有方向,指明去哪里处理中断

  

  
数越小优先级越高,三个固定优先级,复位最高。

     
面试题

      
中断和异常的区别

   
中断和异常指的是当发生某些变乱时,处理器改变当前正常执行的程序,转而去响应该变乱的环境。

   
异常:通常是由处理器内部导致的,源于内部变乱,大多数上都是一些软件错误

   
中断:由外部变乱引起,通过中断通道将外部信号送入处理器内部,再由CPU举行处理,大多都是由硬件引起的。

   
无论是中断还是异常,处理器都有相应的中断/异常服务程序。

       支持中断的嵌套
  
要启用中断嵌套,首先需要在NVIC模块中配置中断优先级。每个中断都有一个相应的优先级,中断嵌套使得某个中断能够打断正在执行的较低优先级中断,从而及时响应更高优先级的中断请求。

  

  

  
注意:3个固定的优先级

  
可改变的优先级:四个可编程优先级,用两个bit位表现,00,01,10,11

  注意:

  
差别优先级的中断同时发生,优先处理中断优先级编号偏小的那个(中断的优先级)

  
同样优先级的中断同时发生,中断向量号较小的那个优先相应(响应优先级)

  
范围(0—255)

  

  6. EXTI( 外部中断和变乱控制器)

  
相称于小助理的小助理

  
NVIC在内部,EXTI在外部

  
专门用来管理外部中断和变乱的。

         
面试题

   
变乱和中断的区别?

   
中断:中断是一个过程,只要发生就能打断CPU正常工作

   
变乱:送给外部装备执行的信号,本质上是IO的电平信号

      
  6.1 重要功能

  
1. 产生中断

  
产生中断的目的:是将信号送入NVIC,进而运行中断服务程序,实现对应功能,是软件级。

  
2. 产生变乱

  
产生变乱的目的:是将采集到的一个脉冲信号送到某个外设,进而驱动某些装备做出动作,是电路级别的传输,是硬件级的。

  

  6.2 外部中断处理流程

  
        
边沿检测电路以输入线作为信号输入端,监测是否有边沿跳变,检测到有边沿跳变输出有效信号 1 给或门,否则输出无效信号0。

      
  

  7. 外部中断实验(按键中断实验)

  实验要求

  
TM32正常执行LED灯闪耀主程序,当检测到按键按下时处理中断变乱,通过串口打印“HelloWorld!!!”

  实验过程

  

  

  
MX配置

  

  

  

  
代码编程思路

    
代码编写

  

  

  

  

  

  

  
WEAK弱符号

  
weak 顾名思义是“弱”的意思,所以假如函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”。

  
加上了__weak 修饰符的函数,用户可以在用户文件中重新界说一个同名函数,最终编译器编译的时间,会选择用户界说的函数,假如用户没有重新界说这个函数,

  
那么编译器就会执行__weak 修饰的函数,而且编译器不会报错。

  
主函数

  

  
回调函数

  

  8. 内部中断实验

  实验要求

  
主程序发送一句字符串“HelloWorld”,当这条字符串发送完成时触发中断变乱,调用中断服务程序发送“HelloHello”

  实验过程

  
MX配置

  

  
大概

  

  
编程思路

    

  
函数分析

  

  
功能:以中断的模式发送数据

  
参数:句柄 数据 数据的大小

  
返回值:发送状态

  

  
代码实现

  

  
找中断回调函数

  

  

  

  

  

  

  
重写中断回调函数

  

  
练习:实验实现接收完成中断,当接收到4个字符时,产生接收完成中断变乱,并在服务程序中输出“Very OK!”

         时钟系统

   1. 根本概念

   
时钟是嵌入式系统的脉搏,(在电子系统中,时钟信号可以被理解为一个周期性的信号,它确定了系统的节奏和时间基准)处理器内核在时钟的驱动下完成指令执行、状态切换等动作的。外部装备在时钟驱动下完成各项工作。比如:串口通讯(异步通讯,每一个装备都有自己单独的时钟系统)、AD转换、定时器计数...

   2. 时钟系统的构成

   
振荡器,叫醒定时器,倍频器,分频器

   

   

   
振荡器:产生信号的源头

   
叫醒定时器:使能,关闭功能

   
倍频器:放大信号(频率)

   
分频器:减小频率

   
时钟的作用:时钟系统在单片机中起着提供时序控制、计时功能、通讯同步等多种重要作用,是单片机正常运行的关键构成部分。

   2.1 振荡器(信号源)

   
振荡器分类:晶体振荡器,RC,LC

   

   晶体振荡器

   
晶体振荡器是一种电子元件,用于在电路中提供准确的时钟信号。它由一个晶体振荡器和相应的驱动电路构成,通常用于数字电路、微控制器、盘算机等系统中。

   
晶体振荡器利用石英晶体作为振荡元件。石英晶体具有压电效应,当施加电场时,会以固定频率产生机器振动。晶体振荡器利用石英晶体的这种特性,通过电子电路驱动晶体振荡,产生稳定的振荡信号。晶体振荡器的频率稳定性非常高。

   

   
优点:产生的信号稳定,精度高,连接方式简单。

   
缺点:代价高,需要一个较长的启动时间。(起振时间)

   RC振荡器

   
RC振荡器利用电阻和电容器构成一个简单的振荡回路。当电容器充放电到达某个阈值时,会产生周期性的振荡信号。RC振荡器通常用于低频、中频等信号的产生和调制。

   
优点:便宜,电阻和电容构成,起振时间短。

   
缺点:精度低,受环境因素影响,不够稳定。

   LC振荡器

   
LC振荡器利用电感和电容器构成一个振荡回路。在LC振荡回路中,电感和电容器通过能量交换产生周期性的振荡信号。通常用于射频、高频等电路的信号产生。

   
优点:稳定性好

   
缺点:尺寸大,布局复杂。

   总结

   
RC振荡器和LC振荡器是简单的振荡器,实用于一些低要求的应用场景,而晶体振荡器则具有更高的频率稳定性和精度,实用于对时钟信号要求较高的电子系统中。

   2.2 倍频器

   
cpu需要更高的频率,但是晶体振荡器的制作成本较高(而且频率越高,自身的频率也不稳定),不适合直接生产高振荡器,所以需要用到倍频器对现有的时钟频率举行放大。

   2.3 分频器

   
外设需要差别的频率,为了降低功耗,举行分频,以保证差别的时钟信号。

   3. G030的时钟源

   
(英文参考121页)

   

      时钟树

   

   

   MX时钟树

   

   
配置高速外部时钟

   STM32CubeMX时钟树配置

   

   

   

   

   4. Systick 定时器

   4.1 概念

   
SysTick又称滴答定时器。是一个定时装备,位于Cortex-M0+内核中,和NVIC捆绑(可以产生中断信号),产生SysTick异常(IRQ异常号15)可以对输入的时钟举行计数,系统定时器一般用于操纵系统,用于产生时基,维持操纵系统的心跳。

      
补充:

   
频率的单位 f :HZ KHZ MHZ 1s振荡多少次

   
1MHZ = 1000KHZ = 1000 000HZ

   
周期:T 单位:s ms us 振荡一次需要的时间

      4.2 原理图

   

   4.3 工作原理

      
滴答定时器本质上就是一个24位递减计数器,也就是最大计数是2^24 - 1(0xFFFFFF)。 在给Systick设定初值后,每当到来一个时钟信号,计数值则减1,直到计数值减到0时,触发一次异常变乱,处理异常服务程序,处理完成后计数器再主动重装初值并继续减一,依次循环。

      
比如如今输入时钟频率是1MHZ的话,定时1ms该怎么定?

   
算出1MHZ的周期(计数一次所需的时间)1us,那计时这样的时钟信号1000就是1ms,主动重装载寄存器1000-1。这样一设置计数器就会在999开始计数,每来1个时钟周期计数器就减1,直到减到0再来一次就会触发异常,此时计数器已经计数1000次,1000*1us=1ms,正好计时1ms;同时重载数值寄存器会重新给定时器写入1000-1;云云一来实现了1ms触发一次中断;

   
所谓的定时器,就是对输入的时钟信号举行计数,当到达计数个数的时间触发中断/异常,并重新开始计数,可以说定时器就是计数器!!!

   
      
假如说如今给的频率是16MHZ,那我计1ms该计多少个数,如何配置重载数值寄存器?

   
16MHZ--》1/16us 1us振荡16次--》1ms振荡16000次--》

   
主动重装载寄存器16000-1

   

   
32KZH 计200ms

   
32KHZ-》1/32ms -->1MS振荡32次--》200ms--》计6400次 主动重载寄存器 6400-1

      
   
滴答定时器系统默认开启

   

   

   

   
追第一个参数

   

   

   

   

   
HAL_SYSTICK_Config(SystemCoreClock / (1000U /(uint32_t)uwTickFreq)

   
16000000 / 1000 / 1 = 16000

   

   

   
      
时钟频率:16MHZ

   
重装载寄存器:16000-1

   
1ms触发一次中断

      
   
中断服务程序的执行

   

   

   

   
每隔1ms让uwtick自加1

   

   
修改成1s

   

   5. 定时器

   
Systick(滴答定时器)是在内核中(ARM公司计划)、定时器(合作商:ST\GD)

   5.1 根本概念

   
定时器本质上是一个计数器,可对输入的时钟举行计数,并在计数值到达设定值时触发中断,当这个计数器的输入是一个准确可靠的基定时钟时,对基定时钟计数的过程就是计时的过程。

   5.2 定时器的分类

   
定时器的根本布局是通用的,许多模块电路都能用到,所以STM32定时上扩展了非常多的功能,根据复杂度和应用场景分为了高级定时器、通用定时器、根本定时器三种类型。高级定时器通常提供更多的功能和扩展性,例如可以支持编码器模式、PWM输入输出等。而通用定时器通常可以利用多种计数/工作模式,包括输入捕获、输出比力等。根本定时器相对简单,只能举行单一模式的计数。

   
STM32G030具有多个定时器,包括根本定时器(TIM6/TIM7)、通用定时器

   
(TIM3/TIM4/TIM14/TIM15/TIM16/TIM17)和高级控订定时器(TIM1)

   

   

      
互补输出:具有两个输出引脚,分别称为主输出和互补输出。主输出引脚和互补输出引脚是成对利用的,用于产生相位差为180度的两个信号。主输出和互补输出引脚的电平变化是互补的,即当主输出引脚上的电平上升时,互补输出引脚上的电平降落,反之亦然。互补输出还可以用于减小电磁干扰和噪声,并提高系统的可靠性。

      5.3 时基单元

   
PSC预分频器

   
CNT 计数器

   
ARR 主动重装载寄存器

   预分频器

   

   主动重装寄存器

   

   
2^8=256 2^16=65536

   

   计数器

   

   
向上计数模式:计数器从0开始计数,当到达主动装载寄存器(TIMx_ARR)里的值时,主动清零且产生一个溢出变乱,然后再从0开始向上计数。

   
向下计数模式:计数器从主动装载寄存器(TIMx_ARR)里的值开始递减计数,当计数值到达0时产生一个定时器溢出变乱,并重装初值,继续向下计数。

   
中央对齐模式:又称为向上/向下计数,计数器从0开始递增到达ARR的值,产生一个定时器溢出变乱,再从ARR的值递减到0,产生一个定时器溢出变乱。

   定时器计数原理

   
【STM32】第16集 动画告诉你, STM32的定时器到底怎么回事_哔哩哔哩_bilibili

   5.4 定时器的配置

   定时时间(s为单位) = (预分频器值+1)x (目的值(主动重装载寄存器)+1)/时钟频率
      
32MHZ 计时10ms 需要配置那些寄存器,如何配置?

   
预分频器:32000-1----》32000分频--》 计数频率1MHZ-》1us-》10ms--》10000-》ARR-》10-1

   

   
输入频率 72MHZ 计时500ms 该如何配置?

   
预分频器:7200-1----》7200分频--》 计数频率1MHZ-》1us-》500ms--》5000-》ARR-》5000-1

   

   
16MHZ初始频率,计时700ms如何配置?

   
预分频:16000-1 --》16000分频 ---》计数器频率:1KHZ---》1ms----》700ms计数700次

   
---》ARR:700-1

   
预分频:1600-1---》1600分频---》计数器计数频率:10KHZ-->计一个数:100us----》700ms计数7000次---》ARR:7000-1

      
   6. 定时器实验

   实验一

   
实验要求

   
利用定时器中断实现1s打印一个“hellowolrd”

   
MX配置

   
配置串口

   

   

   

   
生成工程后,找到TIM14的入口

   

   

   

   

   
HAL函数分析

   

   
功能:以中断的模式启动定时器

   
参数:句柄

   
返回值:状态

   

   

   实验二

   
实验要求

   
利用两个定时器中断实现蓝灯1s间隔闪耀,绿灯2s间隔闪耀

   
实验过程

   
MX配置

   

   

   

   

   
代码编写

   

   

   拓展:看门狗(面试会问)

   
单片机STM32的看门狗(Watchdog)是一种硬件定时器,用于监控系统的运行状态并在出现故障或死锁时采取措施以规复正常操纵。看门狗的重要功能是定期检查系统是否正常运行,并在系统出现标题时触发复位操纵。

   
STM32系列单片机通常配备了内置的看门狗定时器(通常称为独立看门狗,IWDG)和窗口看门狗定时器(WWDG),以提供更可靠的系统保护。

   
独立看门狗(IWDG)是STM32中常用的看门狗,它是一个独立的硬件模块,可以在系统内部独立运行。通过配置IWDG定时器的计数器和预分频器,可以设置看门狗的定时时间。当看门狗定时器计数器到达预设的值时,会产生看门狗超时变乱,触发系统复位。

   

   

   

   
功能:喂狗

   
参数:狗名

   
返回值:状态

   

   

   
头文件别忘了

          ADC +PWM

   
ADC的全称(Analog Digtail Converter)

   
Analog:模拟信号

   
模拟信号是指外界的连续变化的物理量所能表达的信息,如温度、湿度、压力、长度、电流、电压等等,我们通常又把模拟信号称为连续信号,它在一定的时间范围内可以有无限多个差别的取值。模拟信号传输过程中,先把信息信号转换成几乎“千篇一律”的波动电信号(因此叫“模拟”)(传感器可以将非电学量转换成电学量)

   
D(Digital)数字信号

   

   

   
数字信号,是指自变量是离散的、因变量也是离散的信号,这种信号的自变量用整数表现,因变量用有限数字中的一个数字来表现。在盘算机中,数字信号的大小常用有限位的

   
C:Converter(转换器)

   
转换器(converter)是指将一种信号转换成另一种信号的装置。信号是信息存在的形式或载体。在主动化仪表装备和主动控制系统中,常将一种信号转换成另一种与标准量或参考量比力后的信号,以便将两类仪表联接起来,因此,转换器常常是两个仪表(或装置)间的中间环节。最直观的体现,模拟信号是连续变化的曲线,而数字量是不连续的一个个离散的点。

   

    1. ADC

    1.1 根本概念

   
ADC,全称模数转换器(Analog-to-Digital Converter),模拟数字转换器即A/D转换器,ADC的作用就是将连续变化的电信号转换为离散的数字信号。通常的模数转换器是将一个输入电压信号转换为一个输出的数字信号。由于数字信号自己不具有现实意义,仅仅表现一个相对大小。故任何一个模数转换器都需要一个参考模拟量作为转换的标准,比力常见的参考标准为最大的可转换信号大小。而输出的数字量则表现输入信号相对于参考信号的大小 。

   
例子:电压表

    1.2 转换过程

   

    1.3 ADC介绍

   

   

   

   
三个内部的通道

   

    1.4 ADC的特性

   
量程:能测量的电压的范围(0—3.6v),单片机的供电范围(1.8—3.6)

   

   
分辨率:ADC的分辨率通常以输出二进制数的位数表现,位数越多,分辨率越高,一般来说分辨率越高,转化时间越长。

   
可配置的精度:12位、10位、8位、6位 (咱们配置的ADC就是12位的)

   
转换时间:模拟输入电压在答应的最大变化范围内,从转换开始到获得稳定的数字量输出所需要的时间称为转换时间

   

   
这三个量息息干系,也就是说配置的精度越高,转换的分辨率越高,但是对应的所需要的转换时间也就越长。

    1.5 ADC的时钟

   

   
SYSCLK:系统时钟

   
HSI:高速内部时钟

   
PLLP:锁相环倍频器(高速内部/外部)

    1.6 ADC的工作模式

   

   
         
EOC:通道转换竣事的信号

     
EOS:序列转换竣事的信号

     
1、单次转换模式:ADC只执行一次转换;(CHx:通道 )

          
ADC单通道:

     
单次转换:只举行一次ADC转换:配置为“单次转换模式”,扫描模式关闭。ADC通道转换一次后,就制止转换。期待再次使能后才会重新转换

     
连续转换:举行连续ADC转换:配置为“连续转换模式”,扫描模式关闭。ADC通道转换一次后,接着举行下一次转换,不断连续。(没有STOP)

     

     
ADC多通道:

     
单次转换: 只举行一次ADC转换:配置为“单次转换模式”,扫描模式使能。ADC的多个通道,按照配置的顺序依次转换一次后,就制止转换。期待再次使能后才会重新转换。

     
连续转换:举行连续ADC转换:配置为“连续转换模式”,扫描模式使能。ADC的多个通道,按照配置的顺序依次转换一次后,接着举行下一次转换,不断连续。

     

        
    2. ADC转换实验

    单通道单次转换实验

   
实验要求

   
采集光照值,并将数值打印到串口

   
实验过程

       

   

   

   

   
2. MX配置

   

   

   
3.HAL库函数分析

   

   
         
功能:启动ADC,开始转换

     
参数:句柄

     
返回值:状态

        
   

   
         
功能:期待转换结果

     
参数:句柄 超时时间

     
返回值:状态

        
   

   
         
功能:获取转换结果

     
参数:句柄

     
返回值:转换完成的数据

        
   

   
         
功能:制止转换

     
参数:句柄

     
返回值:状态

        
   
4.代码实现

   
头文件别忘记加

   

   

   
  1. int fputc(int ch, FILE * p)
  2. {
  3.     while(!(USART1->ISR & 1<<7));
  4.     USART1->TDR=ch;
  5. }
复制代码
   
    多通道单次转换实验

   
实验要求

   
采集光照值和按键的值打印到串口

   
实验过程

   
原理图

   

   

   

   
MX配置

   

   
编程实现

   

   

   
代码实现

   

   

   
练习:浅易火灾警报装置

         
ADC 采集火焰值(光敏传感器)

     
(每个人采集的值大概不一样,自行调整)

     
一级 亮绿灯 正常没有火 800

     
二级 亮黄灯 有小火 2000

     
三级 亮蓝灯 有大火 4000

     
开启按键中断 按键按下的时间 串口打印“楼层 + 火势环境”

     
(楼层用五向按键判断 上下左右中分别代表1-5层)

     
1 1900 2000

     
2 300 400

     
3 1350 1550

     
4 2800 2900

     
5 2400 2500

     
提升:

     
屏幕显示楼层,火势,时间

        3. PWM

    3.1 界说

         
PWM,全称为脉冲宽度调制(Pulse Width Modulation),是一种调节信号的方法。简单来说,PWM 就是通过改变信号的高电平和低电平的时间比例来控制输出的平均电压或功率。

        3.2 应用

   
应用于惯性系统。

        3.3 PWM参数

   

   
         
周期:高低电平变化所需的时间。

     
占空比:在一个脉冲周期中,高电平在这个周期内所占的比例(0-100%)。

     
频率:在一秒内信号的变化的次数,PWM在一秒内有多少个周期。

     

     
占空比:

     

     
输入的电压是5v的话

     
占空比%20,输出平均电压 1V

     
占空比%50,输出平均电压 2.5V

     
占空比%75,输出平均电压 3.75v

        
    3.4 PWM的工作原理

   
过调节信号的占空比(duty cycle)来控制电能输送的技能。它的根本原理是通过快速切换电源的开关状态,使负载获得所需的平均功率。

   
主动重装载寄存器 (TIMx_ARR)-》目的值

   
计数器寄存器 (TIMx_CNT)-》通常是向上计数

   
捕获/比力寄存器(TIMx_CCRx)-》占空比(高电平连续的时间)

   
设定一个比力值,当计数器的值与这个比力值相称时,触发输出动作。

    输入捕获:

   
输入捕获可以用来捕获外部变乱,比如引脚的电平变化(上升沿,降落沿),并记录下变化的时间,通常可以用来测量外部信号的频率大概电平连续的时间

   

   

   
         
输入捕获的详细原理

             输出比力:

   
本质上那个就是一个定时器

   
此项功能是用来控制一个输出波形,当计数器与捕获/比力寄存器的内容雷同时,输出比力功能做出相应动作,比如电平的翻转。通常用于生成PWM波形

   

   
         
输出的过程

     
当0_t1这段时间,计数器CNT小于CCR,输出高电平。

     
当t1_t2这段时间,计数器CNT大于CCR,小于ARR,输出低电平。

     
当CNT大于ARR时产生溢出变乱,主动清零,重新开始计时。

     

     
占空比:t1/(t1+t2)

        
    4. 实验

   
实验要求

   
通过PWM控制LED灯的亮度。

    实验过程

       

   

   

   

   

   

   

   

   
功能:启动PWM信号生成

   
参数:句柄 通道

   
返回值:状态

   
代码实现

   

   

    5. 蜂鸣器

    简介

   
蜂鸣器是采用直流电压供电的一个电子讯响器。

    分类

    有源蜂鸣器

   
内部带有震荡源(时钟源),一通电就可以震荡发出响声,驱动较容易。

   
由于是内部集成好的震荡电路,所以频率是固定的。

    无源蜂鸣器

   
内部没有震荡源,直流电无法驱动,所以用一个方波信号来举行驱动,

   
代价便宜,且频率可控。需要通过编程控制声调和响度,驱动稍麻烦。

   

    蜂鸣器发送实验

   
查看原理图

   

   

   
MX配置

   

   

    利用定时器输出PWM信号控制蜂鸣器

   

   

   

   
蜂鸣器的声调和响度是由什么决定的?

   
ARR-》周期--》频率

   
周期越大,频率越小,声调越低

   
周期越小,频率越大,声调越高

   

   
CCR-》脉冲-》占空比

   
占空比越高-》响度越大

   
占空比越低-》响度越小

    蜂鸣器播放音乐

   

   

   

   

   

   

   

   

             DMA+DHT11

     1. DMA(数据搬运工)

     1.1 DMA介绍

     

           
DMA,全称为:Direct Memory Access,即直接存储器访问。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保存现场和规复现场的过程,通过硬件为 RAM 与 I/O 装备开发一条直接传送数据的通路,能使 CPU 的效率大为提高。

      

         
     1.2 DMA的作用

     
DMA传输数据不需要CPU,可以直接的传输控制

     
目的:为了给CPU节省资源,提高CPU的工作效率

     1.3 DMA重要特性

     

     

                    
     1.4 DMA传输流程

     

     

     
           
举例:外设到外设

      
DMA通常不直接支持外设到外设的直接传输(由于外设自己并不具有像内存那样的直接寻址能力),但我们可以将其理解为数据从一个外设的缓存或寄存器先传输到内存,然后再从内存传输到另一个外设的缓存或寄存器。

      
请求产生:外设A(源装备)在需要传输数据时,产生一个DMA请求信号。这个请求信号被发送到DMA控制器。

      
请求仲裁:DMA控制器有一个仲裁器,用于决定各个请求源的优先级。假如同时有多个外设请求DMA服务,仲裁器会根据预设的优先级决定先响应哪个请求。

      
数据传输开始:一旦外设A的请求被仲裁器接受,DMA控制器会开始从外设A的数据缓存或寄存器中读取数据。DMA控制器会设置源地点(外设A的数据缓存或寄存器的地点)和目的地点(内存中用于暂存数据的地点)。

      
数据传输:DMA控制器通过DMA通道将数据从外设A传输到内存。这个过程完全由DMA控制器控制,无需CPU的干预。

      
内存中的数据预备传输到外设B:当数据完全传输到内存后,另一个DMA请求大概会由外设B(目的装备)发起,要求将数据从内存传输到其数据缓存或寄存器。同样地,这个请求会经过仲裁器的处理,并由DMA控制器执行。

      
数据从内存传输到外设B:DMA控制器设置新的源地点(内存中存储数据的地点)和目的地点(外设B的数据缓存或寄存器的地点)。数据通过DMA通道从内存传输到外设B。

      
传输竣事:当所有数据都成功传输到外设B后,DMA控制器会发送一个中断信号给CPU,关照传输完成。CPU可以处理这个中断,举行必要的后续操纵或启动新的使命。

         
     1.5 DMA寄存器

     

     1.6 DMA的增量模式和循环模式

     
增量:外设搬移到存储器的时间 ,不盼望覆盖上一个数据,会将内存设置为增量模式

     
循环:DMA不绝循环的搬移数据,一组的数据传输完成时,计数寄存器将会主动地被规复成配置该通道时设置的初值(外部装备可以循环的读取同一块地点区域)

     1.7 DMA中断

     
每个 DMA 通道都可以在 DMA 传输过半、传输完成和传输错误时产生中断。为应用的灵活性考虑,通过设置寄存器的差别位来打开这些中断

     

     

     
           
总结:数据从哪来,数据到哪里去,数据的宽度,数据的大小。

      
注意:DMA传输数据只能传输物理内存地点上连续存储的一块数据。

         
     2. DMA实验

     实验一

     
利用DMA通过串口打印ADC采集的光照值

     
(外设-》内存)

     
MX配置

     
启用串口

     

     
启用ADC

     

     

     
启用DMA

     

     

     

     

     
代码编写

     
什么时间搬?

     
ADC转换完成后再用DMA搬运数据

     

     
功能:启动ADC开始转换,而且将结果搬移

     
参数:句柄 数据存放的地点 数据长度

     
ADC的启动码函数

     

     

     

     

     
注意:此时CPU并未参与ADC转换完成的数据读取工作,节省了CPU的资源。

     
按键发送

     
每按下一次按键发送一次采集的值,要求利用高速外部时钟源

     
MX配置

     

     

     

     
代码编写

     

     

     实验二

     
实验要求

     
采集按键和光照的值

     

     

     

     实验三

     
DMA不定长接收

           
不定长接受的寄义

      
DMA(Direct Memory Access,直接存储器访问)不定长接收的寄义是指在利用DMA举行数据传输时,接收数据的长度不是预先固定的,而是根据现实接收到的数据量动态调整。这种方式特别适合处理长度不确定的连续数据流,如串口通讯、网络数据接收等。

      

      
不定长接收依靠串口空闲中断,就是当RX引脚无后续的输入时,串口从忙碌状态转为空闲状态。

         
     
寄存器利用

     

     

     
MX配置

     

     

     

     

     
大概会用到的函数

     

   
  1. 1)HAL_UART_Receive_DMA(UART_HandleTypeDef * huart,
  2. uint8_t * pData, uint16_t Size) //开启DMA通道并设定通道长度
  3. 2)__HAL_UART_ENABLE_IT(__HANDLE__,__INTERRUPT__)//开启串口空闲中断
  4. 3)__HAL_UART_GET_FLAG(__HANDLE__,__FLAG__)//获得串口空闲中断标志
  5. 4)__HAL_UART_CLEAR_FLAG(__HANDLE__,__FLAG__) //清除串口空闲中断
  6. 5)HAL_UART_DMAStop(UART_HandleTypeDef * huart) //关闭串口DMA通道
  7. 6)设定的传输长度-剩余传输数量(DMA_CNDTRx)=实际长度
  8. 7)HAL_UART_Transmit_DMA(UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size)  //使用DMA通道发送指定长度的字符到串口中
  9. 8)HAL_UART_Receive_DMA(UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size)  //再次开启DMA通道并设定通道长度
复制代码
   
     
代码编写

     

     

     

     3. DHT11

     3.1 DHT11概述

     

     

     
DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±5%RH, 温度±2℃,量程湿度20-90%RH, 温度0~50℃。

     
DHT11温湿度传感器类似于DS18B20采用一线制通讯协议(单总线),所谓“一线制”顾名思义,装备与上位控制器通讯利用1根线,这根线同时负担了时钟和数据线的脚色。   

     
硬件上的简单势必会带来软件上的复杂,像一线制通讯协议,一般都是上位CPU先发开始、复位等电平信号,然后DHT11发送回应信号,然后再发送对应数据,上位CPU接收电平脉冲信号,连续接收固定的字节,然后再举行分析数据。

     3.2 协议分析

     

     

     

     
主机先要发送一个至少18ms的低电平,在这个过程中,DHT11内部完成AD转换等操纵,当主机拉高后,有20-40us时间,这个时间用于主机做输入输出切换,当主机释放总线控制权(此时主机为输入状态,总线被上拉电阻拉高),DHT11实验将总线拉低,成功拉低后就开始预备发送数据了,再拉高一次就开始传输数据了。

     

     

     
40位:8湿度整 8湿度小 8温度整 8温度小 8校验和

          3.3 原理图分析

     

     

     3.4 MX配置

     

     3.5 源码分析

   
  1. //设置IO为输入模式
  2. static void DHT11_IO_IN(void)
  3. {
  4.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  5.     GPIO_InitStruct.Pin = DHT11_GPIO_PIN;
  6.     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  7.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  8.     HAL_GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct);
  9. }
  10. //设置IO为输出模式
  11. static void DHT11_IO_OUT(void)
  12. {
  13.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  14.     GPIO_InitStruct.Pin = DHT11_GPIO_PIN;
  15.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  16.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  17.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  18.     HAL_GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct);
  19. }
  20. //复位DHT11      \\起始信号
  21. void DHT11_Rst(void)
  22. {
  23.     DHT11_IO_OUT();         //SET OUTPUT  转换成输出模式
  24.     HAL_GPIO_WritePin(DHT11_GPIO_PORT, DHT11_GPIO_PIN, GPIO_PIN_RESET);        
  25.      //拉低DQ
  26.     HAL_Delay(20);            //拉低至少18ms
  27.     HAL_GPIO_WritePin(DHT11_GPIO_PORT, DHT11_GPIO_PIN, GPIO_PIN_SET);                     
  28.      //拉高DQ
  29.     delay_us(30);             //主机拉高20~40us
  30. }
  31. //等待DHT11的回应
  32. //返回1:未检测到DHT11的存在
  33. //返回0:存在
  34. uint8_t DHT11_Check(void)
  35. {
  36.     uint8_t retry=0;
  37.     DHT11_IO_IN();//SET INPUT
  38.     while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
  39.     {
  40.         retry++;
  41.         delay_us(1);
  42.     };
  43.     if(retry>=100)return 1;
  44.     else retry=0;
  45.     while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
  46.     {
  47.         retry++;
  48.         delay_us(1);
  49.     };
  50.     if(retry>=100)return 1;
  51.     return 0;
  52. }
  53. //从DHT11读取一个位
  54. //返回值:1/0
  55. uint8_t DHT11_Read_Bit(void)
  56. {
  57.     uint8_t retry=0;
  58.     while(DHT11_DQ_IN&&retry<100)//等待变为低电平
  59.     {
  60.         retry++;
  61.         delay_us(1);
  62.     }//延时100
  63.     retry=0;
  64.     while(!DHT11_DQ_IN&&retry<100)//等待变高电平
  65.     {
  66.         retry++;
  67.         delay_us(1);
  68.     }
  69.     delay_us(40);//等待40us
  70.     if(DHT11_DQ_IN)return 1;
  71.     else return 0;
  72. }
  73. //从DHT11读取一个字节
  74. //返回值:读到的数据
  75. uint8_t DHT11_Read_Byte(void)
  76. {
  77.     uint8_t i,dat;
  78.     dat=0;
  79.     for (i=0; i<8; i++)
  80.     {
  81.         dat<<=1;
  82.         dat|=DHT11_Read_Bit();
  83.     }
  84.     return dat;
  85. }
  86. //从DHT11读取一次数据
  87. //temp:温度值(范围:0~50°)
  88. //humi:湿度值(范围:20%~90%)
  89. //返回值:HAL_OK,正常;1,读取失败
  90. uint8_t DHT11_Read_Data(uint8_t *humiH,uint8_t *humiL,uint8_t *tempH,uint8_t *tempL)
  91. {
  92.     uint8_t buf[5];
  93.     uint8_t i;
  94.     DHT11_Rst();
  95.     if(DHT11_Check()==0)
  96.     {
  97.         for(i=0; i<5; i++) //读取40位数据
  98.         {
  99.             buf[i]=DHT11_Read_Byte();
  100.         }
  101.         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
  102.         {
  103.             *humiH=buf[0];     //湿度高八位,整数位
  104.             *humiL=buf[1];      //湿度低八位,小数位
  105.             *tempH=buf[2];     //温度高八位,整数位
  106.             *tempL=buf[3];      //温度低八位,小数位
  107.         }
  108.     } else
  109.         return HAL_ERROR;
  110.     return HAL_OK;
  111. }
  112. //初始化DHT11的IO口 DQ 同时检测DHT11的存在
  113. //返回1:不存在
  114. //返回0:存在
  115. uint8_t FS_DHT11_Init(void)
  116. {
  117.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  118.     GPIO_InitStruct.Pin = DHT11_GPIO_PIN;
  119.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  120.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  121.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  122.     HAL_GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct);
  123.     HAL_GPIO_WritePin(DHT11_GPIO_PORT, DHT11_GPIO_PIN, GPIO_PIN_SET);       
  124.     // 输出高电平
  125.     DHT11_Rst();  //复位DHT11
  126.     return DHT11_Check();//等待DHT11的回应
  127. }
复制代码
   
     3.6 延时函数分析

   
  1. void delay_us(uint32_t nus)  // 延时函数,延时的时间以微秒为单位
  2. {
  3.   uint32_t ticks;            // 需要的节拍数
  4.   uint32_t told, tnow, tcnt = 0;  // told: 进入函数时的SysTick值; tnow: 当前的SysTick值; tcnt: 累计的节拍数
  5.   uint32_t reload = SysTick->LOAD; // 记录SysTick计数器的重装载值
  6.   ticks = nus * fac_us;  // 计算需要的节拍数,fac_us是系统时钟的频率因子,具体值由初始化函数delay_init设置
  7.   told = SysTick->VAL;  // 记录当前SysTick计数器的值(SysTick是一个递减计数器)
  8.   while (1)
  9.   {
  10.     tnow = SysTick->VAL;  // 获取当前SysTick计数器的值
  11.     if (tnow != told)     // 如果当前SysTick值与上一次记录的值不同
  12.     {
  13.       if (tnow < told)    // 如果当前值小于之前记录的值,说明没有发生重装载
  14.         tcnt += told - tnow;  // 计算这一段时间内经过的节拍数
  15.       else                // 如果当前值大于之前记录的值,说明发生了重装载
  16.         tcnt += reload - tnow + told;  // 计算重装载期间经过的节拍数
  17.       told = tnow;  // 更新记录的SysTick值
  18.       if (tcnt >= ticks)  // 如果累计的节拍数达到或超过需要的节拍数
  19.         break;  // 退出循环,延时结束
  20.     }
  21.   };
  22. }
复制代码
   
 


     

     

     

     

        

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

      

   

   

   

   

   

   

   

   


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4