第一章、STM32基本介绍
总内容- 计算机技术简介
- 环境安装、项目流程搭建
- 最小系统
- 时钟系统
- 启动相关:启动文件、启动流程、启动方式
- GPIO
- USART
- NVIC: 外部中断_串口中断( DMA )
- TIMER
- ADC
- DHT11: 单总线协议
- SPI : LCD屏
1.通用计算机/专用计算机?各自的定义?优点缺点?
通用计算机(General-Purpose Computer)
定义:能够执行多种任务和应用程序的计算机,具有灵活性和可编程性。它们可以运行不同类型的软件,适用于各种计算需求。
优点:
灵活性:可以执行多种类型的任务,适应不同的应用需求。
可编程性:用户可以根据需要编写和运行不同的程序。
广泛应用:适用于个人、商业、科研等多个领域。
缺点:
性能:在特定任务上可能不如专用计算机高效。
资源消耗:由于需要支持多种功能,可能会消耗更多的资源(如内存和处理能力)。
专用计算机(Special-Purpose Computer)
定义:为特定任务或应用而设计和优化的计算机,通常用于执行特定的计算或控制功能。
优点:
高效性:在特定任务上性能优越,能够快速处理特定类型的数据。
资源优化:针对特定应用进行优化,通常消耗更少的资源。
可靠性:在特定环境下运行时,通常更稳定和可靠。
缺点:
灵活性差:只能执行特定的任务,无法适应其他类型的应用。
开发成本:设计和开发专用计算机的成本可能较高。
更新困难:一旦设计完成,更新和扩展功能可能比较困难。
2.嵌入式技术成为趋势的原因?嵌入式计算机硬件/软件有哪些?
**智能化需求:**随着物联网(IoT)、智能家居、智能交通等领域的发展,对智能化设备的需求不断增加。
**成本效益:**嵌入式系统通常具有较低的成本和功耗,适合大规模生产和应用。
**实时性:**嵌入式系统能够提供实时响应,适用于对时间敏感的应用,如工业控制和医疗设备。
**小型化:**嵌入式设备通常体积小,便于集成到各种产品中。
**可靠性:**嵌入式系统通常设计为长期运行,具有较高的稳定性和可靠性。
3.嵌入式计算机硬件
微控制器(MCU):如ARM Cortex-M系列、AVR、PIC等,广泛用于控制和数据处理。
单片机(SoC):集成了处理器、内存和外设的系统,如Raspberry Pi、BeagleBone等。
传感器:用于采集环境数据,如温度传感器、加速度计、光传感器等。
执行器:用于执行控制命令的设备,如电机、继电器等。
通信模块:如Wi-Fi、蓝牙、Zigbee等,用于设备间的无线通信。
4.嵌入式计算机软件
实时操作系统(RTOS):如FreeRTOS、VxWorks、μC/OS等,提供实时任务调度和管理。
嵌入式Linux:如Yocto、Buildroot等,适用于需要复杂功能的嵌入式系统。
固件:直接运行在硬件上的软件,负责设备的基本功能和控制。
驱动程序:用于控制硬件设备的程序,确保软件与硬件之间的通信。
应用程序:实现特定功能的用户级软件,如数据采集、控制界面等。
常见问题3、嵌入式处理器分类(复杂/精简指令集)?具体有哪些?ARM属于哪种处理器?
4、如何理解SOC ?
5、实时操作系统与linux、windows有何区别 ?
6、ARM 的具体含义 ?
7、cortex- A/R/M 具体含义 ?
8、STM与ARM之间的关系 ?
9、STM32G030具体含义是什么 ?命名规则 ?
10、STM32G030与 cortex- A/R/M 的关系 ?
11、STM与 ARM的关系 ?
计算机技术,分为通用计算机技术和专用计算机技术
这里我们去学习了解专用计算机技术:
分为软件和硬件——
**软件:**驱动层、应用层、RTOS;
**硬件:**处理器、内存、外围电路
5.计算机发展历史(四阶段)
1945-1955:电子管时代:体积大,功耗大,算力低下
1955-1965:晶体管时代:体积减小,功耗降低,算力提升
1965-1975(第一台商用计算机):中小规模的集成电路时代
1975至今:大规模的集成电路时代
6.SOC
也就是片上系统——
片:电路板 系统:CPU+内存加外设
7.ARM
3个义项:ARM公司;一种技术;处理器
芯片(ARM提供电路设计方案)现在芯片代号为:
**confex ** A系列、R系列、M系列等等
A系列应用在电脑,手机等设备上;
R系列芯片应用在实时系统上,比如无人驾驶等;
M系列芯片应用于微处理器(单片机),比如Contex-M0
8.STM
意法半导体公司
2、环境安装
1.keil 安装 ?如何破解 ?如何添加固件 ?
通过“Project” -> “Manage” -> “Pack Installer”来添加固件库
2.ubeMX 安装 ?如何添加固件 ?
在CubeMX中,选择“Firmware Package”选项,下载并安装所需的固件库。
3.串口驱动 安装 ?
4.ST-Link驱动安装 ?如何手动更新驱动程序 ?注意保存安装路径
在设备管理器中找到ST-Link设备,右键选择“更新驱动程序”,然后选择“浏览计算机以查找驱动程序”,并指定安装路径。
5.ubeMX搭建项目流程 ?
打开CubeMX,选择新项目。
选择目标微控制器或开发板。
配置外设和引脚。
生成代码,选择Keil作为工具链。
打开生成的Keil项目,进行编译和调试。
6.cubeMX使用细节 ?界面菜单和选项说明 ?
7.cubeMX 和 keil 联动时,出现的常见问题 ?
代码生成问题:确保在CubeMX中正确配置所有外设。
路径问题:确保CubeMX生成的代码路径与Keil项目路径一致。
库文件缺失:确保在Keil中正确添加了所需的库文件。
3、最小系统
常见问题1、五大电路详解 ?
2、电源为什么要有多个输入 ?
3、Reset复位条件 ?
4、复位电路设计结构 ?上电复位、软件复位、按键手动复位 ?
5、晶振电路设计结构 ?晶振简单原理说明 ?
6、启动电路设计结构 ?三种启动流程详解 ?
****1.STM32G030C8T6
(contex-M0系列的芯片)
系统架构——2主3从: 2主:cpu,dma
内存,硬盘,始终总线以及时钟总线上面的一些外设
2.stm32最小系统的电路
电源电路,时钟/晶振电路,启动电路,复位电路
1.电源电路,为什么存多个电源入口?
主要是为了满足不同的电源需求和应用场景;主要原因:
- 电源冗余
多个电源入口可以提供冗余电源选择,确保在一个电源失效时,系统仍然可以通过其他电源正常工作。这在关键应用中尤为重要。
- 不同电压需求
STM32微控制器可能需要不同的电压供电(如3.3V、5V等),而其他外设(如传感器、模块等)可能需要不同的电压。多个电源入口可以方便地为不同的部分提供所需的电压。
- 便于调试和开发
在开发和调试阶段,设计者可能希望使用不同的电源(如USB供电、外部电源等)进行测试。多个电源入口可以简化这一过程。
- 电源管理
通过多个电源入口,可以实现更灵活的电源管理。例如,可以在不同的工作模式下选择不同的电源,以优化功耗。
- 模块化设计
在模块化设计中,某些模块可能需要独立供电。多个电源入口可以使得系统设计更加灵活,便于后续的扩展和维护。
- 外部设备供电
如果系统中有外部设备(如传感器、显示器等),这些设备可能需要独立的电源供电。多个电源入口可以满足这些设备的供电需求。
2.晶振电路
单片机4个晶振:内部/外部;高速/低速:
内部晶振:
高速内部晶振(HSI):通常为8MHz,适用于快速启动和低成本应用。
低速内部晶振(LSI):通常为32kHz,主要用于实时时钟(RTC)等低功耗应用。
外部晶振:
高速外部晶振(HSE):可以使用外部晶振(如8MHz、12MHz等),提供更高的精度和稳定性,适用于对时钟精度要求较高的应用。
低速外部晶振(LSE):通常为32.768kHz,主要用于RTC等低功耗应用,提供更高的精度和稳定性。
3.选择晶振的考虑因素
精度:外部晶振通常比内部晶振提供更高的频率精度。
稳定性:外部晶振在温度变化和电压波动时更稳定。
功耗:内部晶振在某些低功耗模式下可能更适合。
启动时间:内部晶振通常启动时间较短,适合快速启动的应用。
4.复位电路
复位条件:
上电复位:当电源电压达到一定阈值时,单片机自动复位。
外部复位:通过外部按键或信号触发复位。
看门狗复位:当看门狗定时器超时未被重置时,触发复位。
软件复位:通过软件指令触发复位。
5.电容的特性
去耦作用:电容可以平滑电源电压,减少电源噪声。
延迟复位:在复位电路中,电容可以与电阻形成 RC 延迟电路,确保复位信号在电源稳定后才解除。
复位形式:上电复位,手动复位,软件复位
上电复位:电源接通时自动复位。
手动复位:通过按下复位按钮手动触发复位。
软件复位:通过程序指令实现复位。
6.启动电路
boot0;boot1
Boot0:用于选择启动模式的引脚。可以选择从用户闪存、系统内存或其他外部设备启动。
Boot1:在某些 STM32 系列中,Boot1 也用于选择启动模式,具体功能取决于芯片型号。
7.下载调试电路
ST-Link
ST-Link 是 STM32 的调试和编程工具,提供了与单片机的通信接口。
功能:
编程:将程序下载到 STM32 的闪存中。
调试:通过 SWD 或 JTAG 接口进行单步调试、断点设置等。
连接:
ST-Link 通过 SWD 或 JTAG 接口连接到 STM32 的调试引脚(如 SWDIO、SWCLK、NRST 等)。
需要确保 ST-Link 和 STM32 之间的电源和地线连接正确。
4、时钟系统
1.时钟系统结构说明 ?时钟源 ?时钟总线 ? 外部设备 ?
关键点: 选 乘 除
STM32 最小系统的时钟系统,主要包括:主时钟源、时钟分频器、时钟树和时钟输出。
1.主时钟源
STM32 最小系统的主时钟源可以是内部晶振(HSI)或外部晶振(HSE)。内部晶振是芯片内部集成的振荡器,通常具有较低的精度和稳定性,适用于低功耗应用。外部晶振是通过外部引脚连接的晶振,提供更高的频率稳定性和精度,适用于对时钟要求较高的应用。
2.时钟分频器
STM32 最小系统的时钟分频器用于将主时钟源的频率分频得到其他时钟信号。通过时钟分频器,可以得到系统时钟(SYSCLK)、AHB 总线时钟、APB1 总线时钟和 APB2 总线时钟等不同频率的时钟信号。
3.时钟树
时钟树是由时钟源、时钟分频器和各个外设模块的时钟控制寄存器组成的层次结构。时钟树用于控制和分配时钟信号给不同的外设模块,以满足各个模块的时钟要求。通过配置时钟树,可以灵活地控制各个外设模块的时钟频率和工作模式。
4.时钟输出
STM32 最小系统通常提供了一些时钟输出引脚,用于将特定的时钟信号输出到外部。这些时钟输出可以用于外部设备的时钟同步或其他需要时钟信号的应用。
选择器(Multiplexer,简称MUX):
选择器是一种多路数据选择器,用于从多个输入信号中选择一个输出信号。在时钟系统中,选择器可以用于选择不同的时钟源或时钟信号。通过选择器,可以在多个时钟源之间进行切换,以满足不同的应用需求。例如,在某些系统中,可以使用选择器从外部晶振或内部晶振中选择主时钟源。
5.分频器(Divider)
分频器是一种用于将输入信号的频率进行分频的电路。它可以将高频率的输入信号分频为较低频率的输出信号。在时钟系统中,分频器常用于将主时钟源的频率分频为其他模块所需的频率。通过设置分频器的分频系数,可以得到不同频率的时钟信号,以满足各个模块的时钟要求。
6.倍频器(Multiplier)
倍频器是一种用于将输入信号的频率进行倍频的电路。它可以将低频率的输入信号倍频为高频率的输出信号。在时钟系统中,倍频器常用于将主时钟源的频率倍频,以提供更高的时钟频率给特定的模块或应用。通过设置倍频器的倍频系数,可以得到所需的高频时钟信号。
7.系统架构图
2.启动相关:启动文件、启动流程、启动方式
1.启动文件代码详解 ? 栈、堆、向量表 ?
2、启动文件、启动方式、启动流程,区别和联系?
启动文件:
**定义:**启动文件是一个汇编语言文件,负责设置系统的初始状态,包括堆栈指针、数据段初始化、BSS段清零等。
**内容:**通常包含向量表、堆栈初始化、全局变量初始化、调用main()函数的代码。
**作用:**为C语言程序提供一个合适的运行环境。
启动方式:
**定义:**启动方式指的是微控制器上电或复位后,如何开始执行程序的方式。
上电启动:当设备上电时,MCU从预定义的地址(通常是0x08000000)开始执行。
复位启动:当MCU复位时,执行复位向量,通常指向Reset_Handler。
启动流程:
**定义:**启动流程是指从上电或复位到程序开始执行的整个过程。
**复位:**MCU复位后,硬件会将程序计数器(PC)指向复位向量。
**执行启动文件:**执行启动文件中的代码,初始化堆栈指针、清零BSS段、初始化数据段。
**调用main():**完成初始化后,调用main()函数,开始用户程序的执行。
区别和联系:
**区别:**启动文件是具体的代码实现,启动方式是启动的方式,启动流程是整个过程的描述。
**联系:**启动文件是启动流程的一部分,启动方式决定了如何进入启动流程。
3、Reset_Handler()具体实现了什么 ?
Reset_Handler()是启动文件中定义的一个函数,负责系统复位后的初始化工作:
初始化堆栈指针:将堆栈指针设置为RAM的末尾。
初始化数据段:将数据段从闪存复制到RAM。
清零BSS段:将BSS段(未初始化的全局变量)清零。
调用SystemInit():进行系统时钟和外设的初始化。
调用main():最终调用用户定义的main()函数,开始程序执行。
3.STM32三种启动模式
1.常规启动模式
常规启动模式是 STM32 的默认启动模式,也是最常用的启动模式。在常规启动模式下,STM32 从 Flash 存储器中读取程序代码,并执行程序。常规启动模式可以通过将 BOOT0 引脚设置为低电平来选择。(BOOT0设置为0)
2.系统内部Bootloader启动模式
系统内部Bootloader启动模式是一种特殊的启动模式,它可以通过系统内部的 Bootloader 程序来加载和执行用户程序。在这种启动模式下,用户可以通过串口或 USB 等接口将新的程序代码下载到 STM32 的 Flash 存储器中,并在下一次启动时执行新的程序。系统内部Bootloader启动模式可以通过将 BOOT0 引脚设置为高电平来选择。(BOOT0设置为1)
3.系统内部Flash编程启动模式
系统内部Flash编程启动模式是一种用于在出厂时对 STM32 进行编程的启动模式。在这种启动模式下,STM32 通过内部的 Bootloader 程序从 Flash 存储器中读取编程数据,并将其写入到 Flash 存储器中。系统内部Flash编程启动模式可以通过将 BOOT1 引脚设置为高电平来选择。(两个都设置为1)
启动相关,启动文件主要有,栈,堆以及中断向量表
启动方式:程序下载位置和上电读取位置
4.启动流程
上电->Reset/MSP的位置->获取MSP的值->获取PC值->resrt_Handler->启动文件startup_stm32xxx.s->main函数
TM32 芯片上电或复位时,会按照一定的启动流程进行初始化和执行程序:
1.Reset(复位)
当 STM32 芯片上电或复位时,会进入复位状态。在复位状态下,芯片的所有寄存器和外设都会被初始化为默认值。
2.获取MSP的值
在复位状态下,首先会获取主堆栈指针(Main Stack Pointer,MSP)的值。MSP 是一个特殊的寄存器,用于指向主堆栈的顶部。通过获取MSP的值,可以确定主堆栈的起始地址。
3.获取PC值
接下来,会获取程序计数器(Program Counter,PC)的值。PC 是一个特殊的寄存器,用于指向下一条将要执行的指令的地址。在复位状态下,PC 的值会被设置为复位向量表的起始地址。
4.reset_Handler
在获取完MSP和PC的值后,会跳转到复位中断处理函数(reset_Handler)。复位中断处理函数是一个特殊的函数,它位于启动文件(startup_stm32xxx.s)中,并负责进行一些必要的初始化操作,例如初始化堆栈、初始化数据段和清零BSS段等。
5.启动文件startup_stm32xxx.s
启动文件(startup_stm32xxx.s)是一个汇编语言文件,它包含了一些启动代码和初始化代码。在复位中断处理函数之后,会执行启动文件中的代码,完成一些底层的初始化工作,例如设置中断向量表、初始化系统时钟、配置中断控制器等。
6.main函数
在启动文件的初始化工作完成后,会调用C语言的main函数。main函数是用户程序的入口点,它是应用程序的主要逻辑所在。在main函数中,可以编写应用程序的各种功能和逻辑代码。
第二章、GPIO
常见问题1、一般芯片,每个引脚单独命名 ?引脚分组 (A-F) (0-15) ?
2、GPIO 含义 ? 输入/输出 ?高低电平定义 ?
3、框图:复用、模拟、整流、寄存器 ?
4、施密特触发器的整流规则 ?
5、框图:保护电路、整流器、上下拉电阻 、驱动器、MOS管 ?
6、框图:8大模式 ?每个模式对应的框图 ?
7、推挽和开漏的区别 ?缩写是什么 ?如何实现开漏输入高电平 ?
## 1、推挽和开漏的区别 ### 1.推挽(Push-Pull) 定义:推挽输出是指输出端可以驱动高电平和低电平,通常由两个晶体管(一个NPN和一个PNP)组成。优点:能够提供较强的驱动能力,适合直接驱动负载。
缺点:在输出高电平时,输出端直接连接到电源,可能会导致短路(如果两个输出同时为高低电平)。
2.开漏(Open-Drain)
定义:开漏输出只有一个晶体管(通常是NPN),输出端在低电平时导通,高电平时处于高阻态。需要外部上拉电阻来实现高电平。
优点:可以实现多个设备共享同一信号线(如I2C总线),避免短路问题。
缺点:需要外部上拉电阻,驱动能力相对较弱。
缩写:推挽:PP(Push-Pull) 开漏:OD(Open-Drain)
如何实现开漏输入高电平:
连接上拉电阻:在开漏输出端和电源之间连接一个上拉电阻(通常为几千欧姆),这样在输出高阻态时,电源通过上拉电阻将信号拉高。
配置引脚:在微控制器中,将对应引脚配置为开漏输出模式。
控制输出:通过控制引脚的状态,输出低电平时,信号被拉低;输出高阻态时,信号通过上拉电阻被拉高。
2、核心外设:GPIO 理论
**GPIO:**通用输入输出——全称为General-purpose I/O ports,STM32中最基础的外设之一。
GPIO基本的框图:
芯片引脚分布与命名:PA10:(A组,第11个引脚)
P2.1:(第2组的第2个引脚)
输入和输出,是站在芯片的角度来说的;芯片对外的行为叫做输出
通用/复用:为了节约引脚,让一个引脚负责更多的外设;
具有GPIO功能,则为通用引脚;不具有GPIO功能就是复用引脚
3、GPIO八大模式
1.模式(8个)
输入:
模拟输入、数字输入:(上拉输入、下拉输入、浮空输入)
输出:
通用推挽输出、通用开漏输出、复用推挽输出、复用开漏输出
2.GPIO一些通用的特点
1.IO口数量
不同型号的微控制器,芯片,或者开发板上的 GPIO 数量可能不同。通过查阅相应的选型手册、数据手册或者开发板文档,可以了解每个型号上可用的 GPIO 引脚数量和功能。
2.快速翻转
GPIO 可以快速地翻转其输出状态。每次翻转的速度可能取决于具体的芯片型号和工作频率。一些微控制器甚至可以在极短的时间内完成翻转,例如在几个时钟周期内。
3.中断支持
每个 GPIO 引脚都可以配置为中断触发源。当引脚的电平状态变化(上升沿、下降沿、或者边沿触发)时,可以触发相应的中断服务程序。这使得 GPIO 可以用于实时事件处理。
4.工作模式
GPIO 支持多种工作模式,具体的工作模式可能因芯片型号而异。常见的工作模式包括输入模式、输出模式、复用功能模式(例如,配置 GPIO 为串口、SPI、I2C 等功能)、模拟输入模式等。
4、stm32相关电气特性
工作电压范围:2V<=VDD<=3.6V GPIO输出电流:单个IO,最大是25mA
stm32引脚类型:电源引脚、晶振引脚、复位引脚、下载引脚、BOOT引脚、GPIO引脚
1.施密特触发器
(Schmitt Trigger)是一种特殊类型的比较器电路,其主要特点是具有正向和负向的阈值电压,使得输出在输入信号上升沿和下降沿之间产生突变。施密特触发器被广泛用于信号整形和去除噪声的电路中。
2.工作原理
上升沿:当输入信号上升到正向阈值以上时,输出由低变高;
下降沿:当输入信号下降到负向阈值以下时,输出由高变低
它还有滞回特性,即输出状态改变后,输入必须越过相反方向的阈值才能再次触发状态变化。
3.施密特触发器作用
信号整形:
用于将不稳定的输入信号整形为稳定的方波信号。
去噪声:
对于具有噪声的输入信号,施密特触发器可以通过设置适当的阈值来消除小幅度的干扰,提高抗噪声性能。
数字电路应用:
在数字电路中,施密特触发器经常用于去抖动开关信号和数字信号的整形。
4.MOS管
是压控型元件,通过控制栅源电压(Ygs)来实现导通或者关闭
P-MOS(P型MOS):
导电条件:
当栅源电压(Vgs)为负值时,P-MOS导通。P-MOS的栅极为正电压。
特性:
通常被用作逻辑门等电路的开关元件。
在CMOS技术中,P-MOS通常和N-MOS一起组成互补对(CMOS对)。
N-MOS(N型MOS):
导电条件:
当栅源电压(Vgs)为正值时,N-MOS导通。N-MOS的栅极为负电压。
特性:
通常被用作逻辑门等电路的开关元件。
在CMOS技术中,N-MOS通常和P-MOS一起组成互补对(CMOS对)。
5、GPIO的八种模式分析
浮空输入(Floating Input):
特点: 输入用,完全浮空,状态不定。
应用: 适用于需要读取外部信号的场景,但外部信号状态不确定。
上拉输入(Input Pull-Up):
特点: 输入用,使用内部上拉电阻,初始状态是高电平。
应用: 适用于外部信号默认为高电平的情况,如按钮按下时会拉低信号。
下拉输入(Input Pull-Down):
特点: 输入用,使用内部下拉电阻,初始状态是低电平。
应用: 适用于外部信号默认为低电平的情况,如按钮按下时会拉高信号。
模拟输入(Analog Mode):
特点: 用于连接模拟外设,如ADC(模数转换器)、DAC(数模转换器)等。
应用: 适用于需要进行模拟信号处理的场景。
通用开漏输出(Open-Drain Output):
特点: 用于实现开漏输出,常用于构建总线,如I2C。
应用: 适用于需要多个输出端口共享同一信号线的场景,例如I2C的SDA、SCL线。
通用推挽输出(Push-Pull Output):
特点: 驱动能力强,支持通用输出,可提供较大电流。
应用: 适用于需要输出到外部设备,需要较大驱动能力的场景。
开漏复用输出(Open-Drain Alternate Function):
特点: 用于实现开漏输出,并复用了片上外设功能。
应用: 适用于需要实现外设功能,同时共享信号线的场景,例如硬件I2C的SDA、SCL线。
推挽复用输出(Push-Pull Alternate Function):
特点: 用于实现推挽输出,并复用了片上外设功能。
应用: 适用于需要实现外设功能,同时需要提供较大驱动能力的场景,例如SPI的SCK、MISO、MOSI线。
GPIO回顾:
查找原理图的流程:
实物led—电路板上的丝印—原理图上的丝印—led元器件符号—对应的引脚的网络标签—芯片引脚
6、实验
- 输出实验:点灯、流水灯、蜂鸣器
- 输入实验:按键控灯
利用轮询方式、、、、轮询主要用在:
输入设备监测:如按键、开关等输入设备的状态检测。
传感器数据读取:定期检查传感器的输出数据。
网络数据接收:在某些网络协议中,定期检查是否有新数据到达。
按键控灯实验:
需求是:通过开关、控制灯的亮/灭
元件:开关、led
检测出开关的状态:接法和输入模式------输入模式有上拉输入、下拉和浮空输入三个模式
GPIO小总结上拉输入(Pull-Up Input):
在这种模式下,GPIO 引脚通过内部电阻连接到高电平(Vcc),当开关按下时,引脚被拉到低电平(GND)。这种方式可以有效防止引脚在未连接时出现浮空状态,避免误触发。
下拉输入(Pull-Down Input):
在这种模式下,GPIO 引脚通过内部电阻连接到低电平(GND),当开关按下时,引脚被拉到高电平(Vcc)。这种方式同样可以防止引脚浮空,但在按键按下时,状态与上拉输入相反。
浮空输入(Floating Input):
在这种模式下,GPIO 引脚没有连接到任何电平,可能会导致引脚状态不稳定,容易受到噪声干扰,通常不推荐使用。
接法:
上拉输入接法:
将开关的一端连接到 GPIO 引脚,另一端连接到 GND。配置GPIO为上拉输入模式。
下拉输入接法:
将开关的一端连接到 GPIO 引脚,另一端连接到 Vcc。配置GPIO为下拉输入模式。
在按键控灯实验中,最好使用上拉输入:
抗干扰能力:上拉输入模式可以有效防止引脚在未按下时浮空,避免电磁干扰导致的误触发。
默认状态:在未按下开关时,GPIO引脚保持在高电平状态,按下开关时引脚拉到低电平,易于理解和调试。
简化电路:使用内部上拉电阻可以简化电路设计,无需外部电阻。
内部声源:振荡电路
有源:MP3+喇叭 无源:喇叭
有源声源内置放大器,无源声源则需要外部放大器驱动
三极管:放大电流、、、、、详细介绍:
三极管是一种重要的半导体器件,广泛应用于放大、开关和信号调制等电路中。
三极管主要分为两种类型:NPN型和PNP型。
三极管的结构:
三极管由三层半导体材料构成,分别称为发射极(Emitter)、基极(Base)和集电极(Collector)。根据掺杂类型的不同,三极管可以分为:
NPN型:发射极和集电极为N型半导体,基极为P型半导体。
PNP型:发射极和集电极为P型半导体,基极为N型半导体。
工作原理:
三极管的工作原理基于半导体的PN结特性。
NPN型三极管:当基极施加正电压时,基极与发射极之间的PN结导通,电子从发射极注入基极,部分电子会被基极吸引,形成基极电流(IB),而大部分电子会流向集电极,形成集电极电流(IC)。集电极电流与基极电流之间的关系由放大倍数(β)决定,通常有IC= β * IB。
PNP型三极管:工作原理与NPN型相似,但电流方向相反。基极施加负电压时,发射极的孔洞注入基极,形成基极电流,集电极电流则由基极流向发射极。
特性参数:
放大倍数(β):表示集电极电流与基极电流的比值,通常在几十到几百之间。
饱和电压(VCE(sat)):当三极管处于饱和状态时,集电极与发射极之间的电压。
截止电流(IC(off)):在基极电流为零时,集电极电流的值。
应用:
放大器:三极管可以用作信号放大器,广泛应用于音频放大、射频放大等。
开关:三极管可以作为电子开关,控制大电流的开关操作,常用于继电器驱动和LED控制等。
振荡器:三极管可以用于产生振荡信号,应用于无线电发射和接收等。
接法:
共发射极配置:最常用的配置,输入信号接基极,输出信号从集电极取出,具有较高的电压增益。
共基极配置:输入信号接发射极,输出信号从集电极取出,适用于高频信号放大。
共集极配置:输入信号接基极,输出信号从发射极取出,具有较高的电流增益。
注意事项:
极性:在使用三极管时,必须注意其极性,确保正确连接。
功率:根据应用选择合适的功率三极管,以避免过热和损坏。
外设的本质:
硬件:电路+元器件 进行功能的集合
软件:寄存器
硬件部分:
电路+元器件:外设通常由电路和各种元器件(如传感器、执行器、显示器等)组成。这些硬件组件共同工作,完成特定的功能。例如,一个温度传感器可以通过电路将温度信号转换为电压信号,进而被微控制器读取。
软件部分:
寄存器:在微控制器中,外设的控制和状态信息通常通过寄存器来管理。寄存器是微控制器内部的一小块存储空间,用于存储外设的配置、状态和控制信息。通过对这些寄存器的读写操作,软件可以控制外设的行为。例如,设置一个定时器的寄存器可以启动定时器,读取一个状态寄存器可以获取外设的当前状态。
也就是:一个外设的硬件部分提供了物理功能,而软件部分通过寄存器与硬件进行交互,实现对外设的控制和数据处理。硬件和软件的结合使得外设能够完成复杂的任务,例如读取传感器数据、控制电机、显示信息等。
void MX_GPIO_Init(void) GPIO_InitTypeDef GPIO_InitStruct GPIO引脚配置的结构体
第三章、USART
常见问题通讯定义 ?通讯分类 (有无时钟源、通讯方式、传输方向)?
波特率的本质:隐形的时钟
电平转换 ?TTL、COMS、RS232、RS485、USB电平标准 ?
STM32串口与RS-232通讯 ?
STM32串口与电脑USB通讯 ?
USART 含义 ?为什么使用异步方式 ?USART 通讯框图 ?
## 1、USART USART是一种通用的串行通信接口,支持同步和异步数据传输。它用于微控制器和其他设备之间的串行通信。为什么使用异步方式:
简单性:异步通信不需要时钟信号,简化了硬件设计。
灵活性:可以在不同的波特率下进行通信,适应多种设备。
成本:减少了对额外时钟线的需求,降低了成本和复杂性。
USART的主要组成部分:
数据寄存器:用于存储要发送或接收的数据。
控制寄存器:配置USART的工作模式、波特率等。
状态寄存器:提供USART的状态信息,如发送完成、接收完成等。
2、USART 通讯协议
记忆关键:1 8 n 1 、9600/115200
也就是一个停止位,8个数据位,无奇偶校验位;常用波特率表示每秒传输的比特数
STM32串口编程方式? 轮询、中断、DMA ?
3、什么是DMA ?作用 ?通道、仲裁、方向、字节长度、循环/普通?
通道:DMA控制器通常有多个通道,每个通道可以独立地处理一个外设与内存之间的数据传输。
仲裁:在多个外设请求DMA服务时,DMA控制器需要进行仲裁,以决定哪个外设可以使用DMA通道。
方向:
内存到外设:数据从内存传输到外设。
外设到内存:数据从外设传输到内存。
字节长度:DMA可以配置为传输不同长度的数据(如字节、半字、字等),以适应不同外设的需求。
循环/普通:
普通模式:DMA传输完成后,控制器会停止,CPU需要重新启动传输。
循环模式:DMA可以在传输完成后自动重新启动,适合于需要持续数据流的应用,如音频播放。
4、UART
(Universal Asynchronous Receiver/Transmitter) 代表通用异步收发器(异步串行通信协议中的一种)。它是微控制器内部的硬件外围设备。能够将传入和传出的数据转换为串行二进制流。使用串行到并行转换的方式,能将从外围设备接收的8位串行数据(8位)转换为并行形式(一个字节)。
**UART(通用异步收发传输器)和USART(通用同步异步收发传输器)**是两种串行通信协议,主要区别:
同步与异步:
UART:仅支持异步通信。数据在没有时钟信号的情况下传输,发送和接收设备必须在相同的波特率下工作。
USART:支持同步和异步通信。可以使用外部时钟信号进行同步通信,也可以像UART一样进行异步通信。
数据传输方式:
UART:数据以字节为单位传输,通常使用起始位、数据位、校验位和停止位。
USART:除了支持UART的传输方式外,还可以在同步模式下使用时钟信号进行数据传输,允许更高的传输速率和更可靠的数据传输。
应用场景:
UART:广泛用于简单的串行通信,如微控制器与计算机之间的通信。
USART:适用于需要更高数据传输速率或更复杂通信协议的场合,如在某些工业应用中。
同步/异步收发器
通讯:对话的实现,将一方的信息,以一个合适的方式合理准确地传送给另一方
通信的分类:全双工、半双工、单工 串行/并行 同步/异步
单工:通道是唯一的,接收方Rx 和 发送方Tx身份是唯一的
全双工:通道同时发生
半双工:通道唯一,同一时间只有一个方向的信号传递
5、几个不同的电平标准
1.TTL(晶体管-晶体管逻辑)
逻辑0:0V到0.8V
逻辑1:2V到5V
2.CMOS(互补金属氧化物半导体)
逻辑0:0V到0.3V(相对于电源电压)
逻辑1:0.7V到VDD(电源电压,通常为3V或5V)
3.RS-232
逻辑0(标记状态):+3V到+15V
逻辑1(空闲状态):-3V到-15V
4.LVTTL(低电压TTL)
逻辑0:0V到0.8V
逻辑1:1.5V到3.6V
5.LVCMOS(低电压CMOS)
逻辑0:0V到0.3V(相对于电源电压)
逻辑1:0.7V到VDD(电源电压,通常为1.8V、2.5V或3.3V)
6.USB 2.0
逻辑0(低电平):
电压范围:0V到0.3V
逻辑1(高电平):
电压范围:3.0V到5.0V
接线是需要交叉相连的
6.Stm32串口与RS-232通讯
通讯协议:串口通讯协议
数据线:空闲时,为高电平
起始位:由高电平变成低电平
数据位:7/8/9/10
校验位:奇校验/偶校验
停止位:1/1.5/2 低电平变高电平
1.详细解释
起始位(Start Bit:UART通信的起始位始终为逻辑低电平(0),用于标识数据传输的开始。
数据位(Data Bits):UART通信可以使用5、6、7或8个数据位来传输数据。数据位按照位顺序从最低位到最高位传输。
奇偶校验位(Parity Bit):可选的奇偶校验位用于检测和纠正数据传输中的错误。校验位可以是奇校验(使得数据位的总数包含奇数个1)或偶校验(使得数据位的总数包含偶数个1)。
停止位(Stop Bit):停止位是UART通信的结束位,始终为逻辑高电平(1)。它标识数据传输的结束,并允许接收器进行下一次数据接收的准备。
波特率(Bps): 每秒钟传送的码元数(一个数字脉冲)
USART的框图,主要需要了解数据的传输,与外部的连接以及波特率控制器
UART的实验部分:首先是串口交互的实验
其次是串口控灯实验
最后是串口打印实验
打印:transit或者重定向的方法:用printf进行格式化输出,同时也具有方便的特点
重定向这儿的本质:将要发送的数据,存放到uart的Tx_Data_reg这个寄存器当中
2.Uart 接收和发送思路
PC串口助手发送一个字符串-----G030接收到字符串,并存放到rx数组中,将字符串发送出去—PC中的串口助手显示字符串(将rx中的字符串打印到串口助手的显示界面)
这儿代码存在的问题:发送一次,就不停地打印(因为rx中一直有数据),为了解决这个,引入memset函数,但是还是在空打印,所有再引入if(rx[0]==0)
6、实验
1、串口轮询实验
HAL_UART_Receive()
HAL_UART_Transmit()
2、printf/scanf() 重定向
3、串口控灯
Strstr()
串口控灯实验:
需求:由串口发送指令去控制单片机上的led的亮/灭
“led1_0n” -> led1亮 “led2_on” ->led2亮
流程:串口发送指令,然后是G030接收到指令,并存放在rx数组当中,接着是,用字符串比较函数:strstr,strcmp。。。。。最后是在符合判断的条件下,执行相关应用
第四章、NVIC: 外部中断_串口中断
1、按键按下后,GPIO 会产生一个上升/下降沿,G030内部是如何触发外部中断的呢?
配置GPIO引脚:
首先,需要将特定的GPIO引脚配置为输入模式,并设置为外部中断源。这通常通过配置寄存器来完成。
选择触发方式:
在G030中,可以选择上升沿、下降沿或双边沿触发外部中断。这个设置通常在外部中断控制寄存器(如EXTI寄存器)中进行配置。
中断使能:
需要使能对应的外部中断线,以便在GPIO引脚状态变化时能够触发中断。这通常涉及到设置中断使能寄存器。
中断向量表:
当外部中断被触发时,处理器会根据中断向量表跳转到相应的中断服务程序(ISR)。
中断处理:
在ISR中,可以执行特定的操作,例如读取按键状态、切换LED状态等。ISR执行完毕后,处理器会恢复到中断发生前的状态。
常见问题1、基本概念:异常和中断 ? (处理器的内外部)
2、中断意义和作用 ?
3、中断处理过程 ?
4、NVIC 定义?位置 ?
5、中断向量表 ?在哪儿定义 ?
## 2、中断向量表 是一个存储器区域,其中包含了所有中断服务程序(ISR)的入口地址。当中断发生时,处理器会根据中断类型查找对应的入口地址,并跳转到该地址执行相应的ISR。定义位置:
在STM32等微控制器中,中断向量表通常在启动文件(startup file)中定义。启动文件是编译后生成的二进制文件的一部分,通常包含以下内容:
中断向量表的起始地址:通常位于内存的固定地址(如0x00000000)。
中断向量的具体实现:每个中断向量对应一个ISR的地址。
中断向量表示例:
void (* const g_pfnVectors[])(void) attribute ((section(“.isr_vector”))) = {
(void (*)(void))((uint32_t)&_estack), // 栈顶地址Reset_Handler, // 复位中断NMI_Handler, // NMI中断HardFault_Handler, // 硬故障中断// ... 其他中断向量};
NVIC 工作原理 ?
NVIC 中断优先级及其分组 ? ( 比较原则:抢占 -> 响应 -> 自然 )
3、中断嵌套 ?为什么会发生的嵌套 ?
**优先级机制:**不同中断源可以设置不同的优先级。当一个高优先级的中断在低优先级中断的服务程序执行期间发生时,系统会中断当前的服务程序,转而执行高优先级的中断服务程序。
**中断使能:**在某些微控制器中,ISR可以在执行期间允许其他中断的响应,这样就可能导致中断嵌套。
**硬件设计:**某些微控制器的硬件设计允许中断嵌套,以提高系统的响应能力。
4、外部中断 定义( GPIO 上升沿 下降沿 )
外部中断是指由外部设备或信号触发的中断请求,通常用于响应外部事件,如按键、传感器信号、通信接口等。外部中断允许微控制器在特定事件发生时立即中断当前程序的执行,转而执行相应的中断服务程序(ISR),以处理这些事件。
EXTI工作原理 ? GPIO -> AFIO -> EXTI
5、EXTI支持的触发方式
上升沿触发(Rising Edge Trigger):
当信号从低电平变为高电平时触发中断。
下降沿触发(Falling Edge Trigger):
当信号从高电平变为低电平时触发中断。
双边沿触发(Both Edge Trigger):
当信号在上升沿或下降沿变化时都触发中断。
软件触发(Software Trigger):
通过软件手动触发中断,通常用于调试或特定应用场景。
6、AFIO定义及其工作原理
AFIO(Alternate Function I/O)是STM32微控制器中的一个外设,用于配置和管理引脚的替代功能。它允许用户将某些引脚配置为特定的功能,如外部中断、定时器输入、串口通信等,而不仅仅是普通的GPIO功能。
工作原理:
引脚复用:STM32的每个引脚可以被配置为多种功能。AFIO负责管理这些引脚的复用,确保在不同的外设之间正确分配引脚。
外部中断配置:AFIO可以配置外部中断的触发源。通过设置特定的寄存器,用户可以选择哪个引脚作为外部中断的输入,并指定其触发方式(上升沿、下降沿或双边沿)。
引脚映射:AFIO提供了引脚映射功能,允许用户将外设功能映射到不同的引脚上。这对于设计灵活的电路非常重要,尤其是在资源有限的情况下。
寄存器配置:AFIO的配置通常涉及设置特定的寄存器,如AFIO_MAPR寄存器,用于选择引脚的替代功能。
示例代码:
// 启用AFIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// 配置外部中断线
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); // 将PA0配置为外部中断源
// 配置EXTI触发方式
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line0; // 选择外部中断线0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能外部中断
EXTI_Init(&EXTI_InitStructure);
7、外部中断整体执行流程
中断源配置:
配置外部中断源(如GPIO引脚)以检测特定的事件(如上升沿、下降沿或双边沿)。
设置中断优先级和触发方式。
中断使能:
使能外部中断控制器(如EXTI)和相应的中断线。
确保中断在NVIC(嵌套向量中断控制器)中被使能。
事件触发:
当外部事件发生(如按键按下或释放)时,外部中断被触发。
触发信号会被送到中断控制器。
中断请求:
中断控制器生成中断请求(IRQ),并将其发送到NVIC。
NVIC根据中断优先级决定是否响应该中断。
中断处理:
如果当前没有高优先级中断在执行,NVIC会暂停当前执行的程序,保存上下文。
跳转到相应的中断服务程序(ISR)。
ISR执行:
在ISR中,执行中断处理逻辑,例如读取传感器数据、切换LED状态等。
清除中断标志位,以便下次中断能够被正确触发。
恢复上下文:
ISR执行完毕后,恢复之前保存的上下文。
恢复后,继续执行被中断的程序。
8、NVIC学习
1.NVIC
挂载在AHB下的外设
全称:嵌套向量中断控制器 中断,讲究实时性
异常:由cpu内部发生的错误(不可控),nvic中指的是某个引脚发生上升沿或者下降沿的跳变(触发时机)
中断:由外设引发的错误(可控)
NVIC的中断优先级由优先级寄存器的4位(0-15决定)
抢占优先级高于响应优先级高于自然优先级(抢占和响应,数值小,级别高)
2.AFIO外设
主要用于配置和管理引脚的替代功能
主要功能:
引脚复用:通过 AFIO,可以将多个外设的功能映射到同一组引脚上,从而节省引脚资源。
中断管理:AFIO 还可以用于配置外部中断的触发方式,例如上升沿、下降沿或双边沿触发。
JTAG/SWD 配置:AFIO 允许用户选择是否启用 JTAG 或 SWD 调试接口,以便在开发过程中进行调试。
寄存器:
AFIO 的配置通常涉及到几个寄存器:
AFIO_MAPR:用于配置引脚的复用功能和中断的触发方式。
AFIO_EXTICR:用于配置外部中断的引脚映射。
使用场景:
多功能引脚:在设计中需要使用多个外设时,AFIO 可以帮助实现引脚的灵活配置。
外部中断:在需要响应外部事件时,AFIO 可以配置中断引脚的触发方式。
配置示例:
在 STM32 的开发中,使用 HAL 库或直接操作寄存器来配置 AFIO。例如,配置某个引脚为 USART的TX引脚,通常需要设置相应的AFIO_MAPR寄存器。
与门:都为1才是1 或门:有一个为1就是1
3.EXTI中断流程
PA0-GPIO-AFIO-EXTI-NVIC-CPU
复用输入->引脚复用(将不同分分组但引脚号相同的划分为一组,引出一根外部中断线exti0)EXTI这儿检测上升沿或者下降沿是否发生,或门这儿是判断软件触发还是硬件触发,与门,触发出现,中断线屏蔽,接着是挂起寄存器,起到了缓冲的作用,再到NVIC,起到了打开或者关闭我们的外部中断线的作用,让不让外部中断线进去,为外部中断线赋予抢占或者/响应优先级。
PA0引脚触发外部中断的流程详细说明:
用于接收外部信号的PA0引脚,在使用外部中断时,PA0被配置为输入模式,以便检测外部信号的变化。然后是对GPIO进行配置,通过配置寄存器,可以将PA0设置为输入模式,并选择上拉或下拉电阻,以确保在没有外部信号时引脚的状态是确定的。接着通过AFIO配置 PA0的中断功能。具体来说,就是将PA0的中断线(EXTI Line)与GPIO引脚关联,以便在引脚状态变化时触发中断。
EXTI负责监测GPIO引脚的状态变化,并生成中断请求。对于PA0,EXTI控制器会监测其状态变化(上升沿、下降沿或双边沿),并在状态变化时生成中断请求。
在这里,主要是边沿检测电路,上升沿触发选择寄存器检测到上升沿,接着遇到或门进入下一步,然后中断屏蔽寄存器和这个输出的都是1,接下来的与门也是1,经过挂起请求寄存器,输出至NVIC中断控制器;
一旦NVIC确定要响应中断,它会将CPU的执行流转移到与PA0相关联的中断服务例程。此时,CPU会暂停当前的任务,执行中断服务例程中的代码,以处理外部中断事件。中断服务例程执行完毕后,CPU会恢复到中断发生前的状态,继续执行之前的任务。
4.EXTI
使能和优先级
Hal库中,中断的一般流程:
①中断向量表提供中断服务函数;
②所有外设都有一个总的中断处理函数;
③各种回调函数(weak)
④若要使用回调函数,必须重新声明
EXIO_1_hander 统一处理所有外部中断
EXTI 4_15_hander 统一的外部中断处理函数
Exti的外部中断代码:
中断向量表中提供的外部中断服务函数(这是中断的入口)
外部中断统一处理入口函数:
xxx_Rising_callback(weak)
xxx_fallng_callback(weak)
再根据要求重写相关的回调函数
exti0_1_handler(){
统一的处理函数()
}
9、DMA
全称:Direct Memory Access,即直接存储器访问。
DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。
1.DMA传输方式
DMA的作用就是实现数据的直接传输,而去掉了传统数据传输需要CPU寄存器参与的环节,主要涉及四种情况的数据传输,但本质上是一样的,都是从内存的某一区域传输到内存的另一区域(外设的数据寄存器本质上就是内存的一个存储单元)。
四种情况的数据传输如下:
外设到内存
内存到外设
内存到内存
外设到外设
DMA传输有专门的传输通道;
DMA传输参数:
首先需要①数据的源地址,②数据传输位置的目标地址;③传输数据多少的数据传输量,④进行多少次传输的传输模式;
只要剩余传输数据量不是0,而且DMA是启动状态,就会发生数据传输;
2.DMA的主要特征
每个通道都有专门的硬件DMA请求,每个通道都同样支持软件触发,这些功能通过软件来配置;
在同一个DMA模块上面,多个请求之间的优先权可以用软件编程来设置(四级:很高、高、中等和低)优先权设置相等的时候,由硬件进行决定(请求0优先于请求1);
独立数据源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐;
支持循环的缓冲器管理;
每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求;
存储器和存储器间的传输、外设和存储器、存储器和外设之间的传输;
闪存、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和目标;
可编程的数据传输数目:最大为65535。
大容量的STM32芯片有2个DMA控制器;DMA1有7个通道,DMA有5个通道,每个通道都可以配置一些外设地址
3.DMA工作系统框图
上方的框图,我们可以看到STM32内核,存储器,外设及DMA的连接,这些硬件最终通过各种各样的线连接到总线矩阵中,硬件结构之间的数据转移都经过总线矩阵的协调,使各个外设和谐的使用总线来传输数据。
如果没有DMA,CPU传输数据还要以内核作为中转站,比如要将ADC采集的数据转移到到SRAM中,这个过程是这样的:
内核通过DCode经过总线矩阵协调,从获取AHB存储的外设ADC采集的数据,
然后内核再通过DCode经过总线矩阵协调把数据存放到内存SRAM中。
有DMA的话,
DMA传输时外设对DMA控制器发出请求。
DMA控制器收到请求,触发DMA工作。
DMA控制器从AHB外设获取ADC采集的数据,存储到DMA通道中
DMA控制器的DMA总线与总线矩阵协调,使用AHB把外设ADC采集的数据经由DMA通道存放到SRAM中,这个数据的传输过程中,完全不需要内核的参与,也就是不需要CPU的参与;
专业介绍:在发生一个事件后,外设向DMA控制器发送一个请求信号。DMA控制器根据通道的优先权处理请求。当DMA控制器开始访问发出请求的外设时,DMA控制器立即发送给它一个应答信号。当从DMA控制器得到应答信号时,外设立即释放它的请求。一旦外设释放了这个请求,DMA控制器同时撤销应答信号。DMA传输结束,如果有更多的请求时,外设可以启动下一个周期。
总之,每次DMA传送由3个操作组成:
从外设数据寄存器或者从当前外设/存储器地址寄存器指示的存储器地址取数据,第一次传输时的开始地址是DMA_CPARx或DMA_CMARx寄存器指定的外设基地址或存储器单元;
存数据到外设数据寄存器或者当前外设/存储器地址寄存器指示的存储器地址,第一次传输时的开始地址是DMA_CPARx或DMA_CMARx寄存器指定的外设基地址或存储器单元;
执行一次DMA_CNDTRx寄存器的递减操作,该寄存器包含未完成的操作数目。
4.DMA传输方式
1是正常模式;2是循环传输模式
其中还有一个仲裁器:作用是确定各个DMA传输的优先级
仲裁器根据通道的请求的优先级来启动外设/存储器的访问
5.DMA配置部分
分为DMA寄存器以及DMA库函数:
DMA寄存器:
DMA配置参数包括:通道地址、优先级、数据传输方向、存储器/外设数据宽度、存储器/外设地址是否增量、循环模式、数据传输量。
DMA库函数配置过程:
使能DMA时钟:RCC_AHBPeriphClockCmd();
初始化DMA通道:DMA_Init();
//设置通道;传输地址;传输方向;传输数据的数目;传输数据宽度;传输模式;优先级;是否开启存储器到存储器。
使能外设DMA;
以串口为例:使能串口DMA发送,串口DMA使能函数。调用函数:USART_DMACmd();
使能DMA通道传输;函数:DMA_Cmd();
查询DMA传输状态。函数:DMA_GetFlagStatus();
获取当前剩余数据量大小 函数: DMA_GetCurrDataCounter(DMA1_Channel4);
结合UART的运用: UART DMA传输
DMA就是一个搬运工,可以将数据从一个位置搬运到另一个位置。
以UART为例,如果要接收数据,会触发UART中断,然后CPU介入,在中断中通过CPU将UART输入寄存器的值读出来,存放到内存中;
而DMA方式,产生UART中断后,DMA直接参与,把UART输入寄存器的值搬运到内存中,CPU只需要在去检查内存的值就好了,这样提高了CPU的效率。
10、实验
1、外部中断实验
HAL_GPIO_EXTI_Falling_Callback()
HAL_GPIO_EXTI_Rising_Callback()
2、串口接受中断实验
HAL_UART_Receive_IT()
HAL_UART_RxCpltCallback()
HAL_UART_Transmit_IT()
HAL_UART_TxCpltCallback()
3、串口空闲中断实验
HAL_UARTEx_ReceiveToIdle_IT()
HAL_UARTEx_RxEventCallback()
- 串口空闲中断_DMA实验
HAL_UARTEx_ReceiveToIdle_DMA()
HAL_UARTEx_RxEventCallback()
第五章、TIMER
常见问题1、基本概念:什么是定时器 ?作用 ?分类 ?
2、时基单元 ?组成 ?计数模式 ?溢出条件 ? 溢出时间计算 ?
3、systick原理 ?代码讲解 ?
4、systick与hal_delay的关系 ?为什么不能再中断里使用中断 ?
5、看门狗原理?独立看门狗 ? 窗口看门狗 (下限 0x3f)?
6、RTC ?
7、定时器框图 ?基础、通用、高级的区别 ?
1、定时器
定时->计数
1.定时器分类
三种: 高级定时器(TIM1,TIM8)、通用定时器(TIM2~TIM5)以及基本定时器(TIM6、TIM7)区别:高级定时器具有捕获/比较通道和互补输出,通用定时器只有捕获/比较通道,基本定时器没有以上两者。
计数器模式:通用定时器可以向上计数、向下计数、向上向下双向计数模式。
①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
2.定时器框图
四个大的部分:时钟产生器部分、时基单元部分、输入捕获部分以及输出比较部分
时钟产生器:STM32的定时器有四种时钟源:
①内部时钟(CK_INT)
②外部时钟模式:外部触发输入(ETR)
③内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。
④外部时钟模式:外部输入脚(TIx)
3.输出比较通道(PWM)
有两种模式:边沿对齐模式以及中心对齐模式
频率*周期=1
72MHz的时钟,代表它发射的方波,一秒钟发72000000个方波;
通过方波的个数去计时,就把计数和计时关联了起来;
一个方波的时间72*10的六次方之一秒,可以算出n个方波的时间;
如果某段时间经过了72个方波,就意味着已经经历了1M分之一秒
这样理解,就可以把计时和计数划一个等号
4.定时器
它的计数在某种意义上等于计时
核心组件:时基单元;
时基单元由三个部分组成,第一个部分是预分频器,作用都是对时钟做除法,就是进行分频;第二个是ARR,重装载寄存器;最后一个是CNT,也就是计数寄存器;这三个设备完成定时器的核心功能;
首先,给它一个初始的时钟源,给它一个72M的频率,想要得到1M的频率,那就用预分频器将初始的时钟源除以72;计数要计1M次,将这个1M的次数首先放在重装载寄存器中,计数寄存器进行计数的同时,不停地和ARR进行对比,次数正确的时候,就进行更新事件这么一个处理。
计算思路:比如问,8M的ALK,定时1ms
首先,单位化统一:s
列公式:1/CLK PSCARR=t
得出PSC*ARR等于? 最后合理分配:PSC/ARR
5.计数模式
第一种:向上计数模式:CNT++ ->ARR
CNT等于0,CNT一直加,直到和ARR一样大,最后更新事件,
它的溢出条件(也就是停止计数,触发更新事件:CNT=ARR);
第二种、计数方式是:向下计数:
首先让CNT等于ARR,然后让CNT去趋近于0,就是向下计数模式
在这个模式里,CNT初始值=ARR,对CNT进行–,直到CNT=0,触发更新事件;向下计数的溢出条件就是CNT==0;
第三种:中心对称计数
6.内核定时器
为系统提供时钟,和延时函数有关;
(滴答定时器),不管什么定时器,都离不开时基单元(PSC.ARR.CNT还需要加上一个更新中断)
代码当中寻找;内核定时器的时钟源是内部的一个高速时钟(16M),它的ARR是16000;CNT是0,向上计数;
更新中断:tick++(用来给hel_delay做延时)(每次tick++都代表过了1ms)两次gettick相当于毫秒级的延时,这是本质;
两个用法:第一个是通过修改systick handler的优先级(提高优先级)来实现中断嵌套,就可以在中断中使用延时函数;
第二个用法是自定义延时函数:重写ARR和CNT的代码,分别可以实现毫秒级延时和微秒级延时以及秒级延时;
第二个外设:
2、看门狗
(分为独立看门狗和窗口看门狗)
当代码出现异常或者跑飞的时候,让计算机自动复位
这里重点是,如何实现计算机的自动复位
一个时基单元,看门狗是向下计数的,看门狗启动的时候,CNT的初始值会等于ARR,喂狗的程序也是让CNT等于ARR,如果CNT==0,就会触发复位(程序正常的时候,CNT永远都不等于0)
当程序异常的时候,喂狗的代码就无法执行,此时必然会出现CNT==0的情况,触发条件让计算机进行复位;
1.窗口看门狗
0x3f(64) 它的上限是ARR,也就是我们自己设置的值,窗口看门狗的CNT也会从ARR向0减少,它的喂狗时间必须在窗口期内,0x3f这点设置为更新事件,这时会有一个中断产生,此时喂狗行为进行;
3、RTC
实时时钟:
外部时钟芯片:稳定
专供电供:纽扣电池
专供晶振:32.768k
反映的信息:年、月、日、时、分、秒
内部的时基单元,年月日时分秒不停累加,前提是不断电
需求:定时器每隔1s,打印或者闪烁一次
cubemx:选择一个定时器、
分频定时:clk,psc,arr怎么选择,设置一个合理的值
与定时器相关的nvic打开
uart/gpio
keil:定时器中断开关(只需要打开一次
更新回调函数)
4、定时器分类(三种)
第一种是内核定时器:systick
专用定时器有独立看门狗和窗口看门狗,只需要看代码和应用层,寄存器这儿不用看,只需要到应用层就足够了(应用层相关配置部分)(面试问,你说你用过uart,你用的时候,使用到了哪些:hal库中在使用uart时,在初始化uart时,需要配置的参数:答案都在keil的代码里面,自己课后去寻找)
专用看门狗还有讲到了一个RTC
常用定时器:基础定时器、通用定时器以及高级定时器
如果定时器只弄了时基单元,那就是基础定时器,
如果还有输入通道和输出通道,就是有输入捕获功能和输出比较功能(就是生成PWM波)主动向外发出一些方波,单片机有能力自己创造波形并且输出这个波;有以上两个额外功能的,就叫做通用定时器;
高级定时器,专门为电机服务;电机有专门的通道,实现“刹车”,如果电机要停止,会有一个瞬间的停止,电机具有刹车功能,芯片有意识地迎合这个功能(多一个接口)
此外,高级定时器还有一个死区功能,还能输出互补通道
5、PWM
脉冲宽度调制
每种波,都有自己的周期和频率,这两个可以决定这个波的高电平和低电平的时间
占空比:t1/t*100%,在整个方波的周期内,高电平所占时间的比值
脉冲:时基单元来确定一个波的周期t
周期可以由时基单元分配:分频定时去控制
宽度:高电平的时间t1
调制:动态地改变占空比->应用场景:呼吸灯的亮度,逐渐变亮再逐渐变暗 改变占空比就是改变高电平的持续时间,
比较值:计数为100个,PWM1模式:令CNT在0到x的时候,为高电平,x到100为低电平;;;PWM2模式:x到100的时候为高电平;0到x为低电平
应用:呼吸灯:本质:控制led灯高电平的时间(动态改变占空比)
6、实验
1、systick与han_delay 代码解析
2、RTC
HAL_RTC_GetTime()
HAL_RTC_GetDate()
3、独立看门狗
HAL_IWDG_Refresh()
4、窗口看门狗
HAL_WWDG_Refresh()
HAL_WWDG_IRQHandler()
HAL_WWDG_EarlyWakeupCallback()
#include <stdio.h>
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
HAL_WWDG_Refresh(hwwdg);
printf(“dog eat now…\n”);
HAL_Delay(2000);
printf(“dog eat end…\n”);
}
( 不喂狗时,只会打印部分值,因为不喂狗时会触发中断,然后直接复位)
5、基础定时器 :1s延时
HAL_TIM_Base_Start_IT(&htim14)
HAL_TIM_PeriodElapsedCallback()
void delay_us(uint16_t nus){ // 利用CNT进行微秒延时
__HAL_TIM_SetCounter(&htim14,0);
__HAL_TIM_ENABLE(&htim14);
while( __HAL_TIM_GetCounter(&htim14)< nus);
__HAL_TIM_DISABLE(&htim14);
}
6、通用定时器 PWM : 呼吸灯 ( 微秒级延时 )
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
__HAL_TIM_SetCompare();
第六章、ADC
常见问题
1、基本概念:什么是ADC ?作用 ?逐次逼近型
2、传感器本质 ?传感器、电压、ADC数值转化 ?
3、ADC的特征 ? 转化时间、分辨率、精度、量化误差 ?
4、ADC框图组成部分 ?参考电压/模拟部分电压、输入通道、转换序列、触发源、数据寄存器、转换时间、中断 ?
5、转换模式_扫描模式 ?
## 1、ADC 模数转换器作用:模拟数据->数字数据
整流:3.3V(模拟)->1(数字) 0V->0
而ADC内部也有一套转化规则:
3.3V->1024/8/512 0V->0
2、传感器
压力传感器、光敏传感器、温度传感器、湿度传感器、气压传感器等等
这些传感器内部实现原理:本质是滑动变阻器
将外部环境信息转换成电压信息(比如100N的力对应3.3V)
外部环境数据:100N 变成 模拟电压
ADC就是去继续量化这个模拟电压的,1024量化3.3V
ADC的特征:ADC的厂商定义四个核心的东西:分辨率(意味着ADC可以表示的范围:比如分辨率是3,0到2的3次方-1;分辨率是10就是0到2的10次方-1,分辨率最高的12,精度更大,分的更清楚)、精度、误差(制作的时候,工艺有区别,存在一个理论值与实际值的差别)、转化时间(要给一个充分的时间,要么确定ADC已经转化完成,要么给一个明确的完成信号)
ADC的内部构造:分为并联选择型和逐次逼近型 (电压->ADC值 )
3、实验
1、轮询模式
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 50);
ADC_Value = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
2、 DMA模式
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_Value,2);
printf(“%d %d \r\n”,ADC_Value[0],ADC_Value[1]);
(while循环中 采样周期要大一点 75.5Cycles )
4、实验:单通道读取五向按键
这个五向按键有两个功能:判断是否按下,判断方向;
在五个按键上,接不同的电压,读取到不同的ADC的值,读的时候注意ADC的通道(通过原理图要找到五向按键和ADC的通道是哪个,必须要找到)
找到之后keil编程:第一步开启;第二步等待转化完成;第三步是获取ADC的值;第四步:停止 以上为轮询方式实现;
效果截图:
实验代码:
配置PA1为ADC1,然后设置一个USART1,实验代码:
中断方式实现:首先是ADC的中断开关;
然后找到对应的回调函数(跟着中断向量表中的ADC服务函数,每个服务函数里都有统一的ADC处理(在这个处理中肯定有callback回调函数,然后重写这个回调函数));接着获取ADC的值,处理完之后,把开关闭合上。
实验记录:
在轮询的前提下,加一个nvic:
硬件问题,如何用软件来区分五向按键向右按和不按(用PA8)
第七章、DHT11: 单总线协议
常见问题1、DHT11是什么 ?有什么特性 ?
2、单总线协议是什么 ?原理 ?DHT11的单总线协议的组成 ?
## 1、DHT11定义 单总线协议是一种用于在多个设备之间进行通信的协议,所有设备共享同一条数据线(总线),通过特定的时序和信号来区分不同设备的通信。原理:
单总线协议通过在同一条数据线上发送和接收数据,利用时序控制和信号电平来实现设备之间的通信。每个设备在总线上都有唯一的地址,主设备通过发送特定的命令来选择与之通信的从设备。
DHT11温湿度传感器使用单总线协议进行数据传输,其协议主要包括以下几个部分:
起始信号:主设备向DHT11发送一个起始信号,持续约18毫秒,表示开始通信。
应答信号:DHT11在接收到起始信号后,发送一个应答信号,持续约20-40微秒,表示准备好发送数据。
数据传输:DHT11通过单总线发送40位数据,包括湿度和温度信息。每位数据由一个高电平和一个低电平组成,具体时长决定了数据位的值(0或1)。
校验位:最后,DHT11发送一个校验位,用于验证数据的完整性。
2、微秒延时在其中的作用 ?
时序控制:在数据传输过程中,微秒级的延时确保了主设备和从设备之间的时序同步,避免数据丢失或错误。
信号稳定:在发送和接收信号之间的延时可以确保信号在总线上稳定,避免由于信号抖动导致的误读。
数据完整性:通过精确控制延时,可以确保每一位数据的发送和接收都在预定的时间窗口内完成,从而提高数据的完整性和可靠性。
3、如何实现微秒延时 ?
1.使用循环延时
通过空循环来实现延时,适用于简单的延时需求,但不够精确。
void delay_us(unsigned int us) {
for (unsigned int i = 0; i < us; i++) {// 根据具体的系统时钟频率调整循环次数for (volatile int j = 0; j < 10; j++);
}
}
2. 使用定时器
使用硬件定时器可以实现更精确的延时。
void delay_us(unsigned int us) { // 配置定时器
TIM2->PSC = 72 - 1; // 预分频,假设系统时钟为72MHzTIM2->ARR = us; // 设置自动重装载寄存器TIM2->CNT = 0; // 清零计数器
TIM2->CR1 |= TIM_CR1_CEN; // 启动定时器
while (!(TIM2->SR & TIM_SR_UIF)); // 等待更新中断标志位
TIM2->SR &= ~TIM_SR_UIF; // 清除更新中断标志位
}
3. 使用系统时钟
如果系统支持,使用系统时钟的延时函数(如 HAL_Delay())可以实现毫秒级延时,结合其他方法实现微秒级延时。
4. 使用专用延时库
一些嵌入式开发环境提供了专用的延时库,可以直接调用。
注意事项:
精度:使用循环延时时,延时的精度受编译器优化和系统时钟频率影响,可能不够准确。
中断:在延时期间,可能会影响中断的响应,特别是使用循环延时时。
系统负载:在高负载情况下,延时可能会受到影响,使用定时器通常更可靠。
4、DHT11
(本质也是一个滑动变阻器,把外界的环境信息转化成电压值,内部的一个高级一点的芯片把电压值转化成ADC,又通过内部的计算,把这个转化成十进制)
检测外部温度/湿度信号,当有数据后,
会通过某种通讯协议,发送给主设备,G030拿到数据后自己分析,通过公式转化得到温度和湿度。这是一种传感器;;另一种传感器是DHT11内部直接转化,得到当前的温度和湿度,再传给G030,节省了一步计算(也就是节省了一部分性能)
三根引脚,第一根是VCC,3.3V/5V 第三根是GND(0V),中间的一根是Data数据线,默认使用单总线协议,这是一种通讯方式;;;
5、通讯的分类
单工/全双工/半双工 串行/并行 同步/异步
单总线协议的一般形式:
主机:发送开始信号(18ms的低电平)
从机:给出一个反馈(响应信号是一个低电平,低电平的时间是30us)
从机:发送数据给主机(温度/湿度)
正常数据都由0/1组成,而这里0:由一段电平组成,就是20us的低电平和50us的高电平认定为0; 1由一段电平组成—50us的低电平,50us的高电平-----单总线只有一根线,不参考GND的数据的发送,核心点在于高低电平的时长
主机:停止信号
6、实验
移植步骤
1、写项目框架: printf移植框架
2、 移植 dht11 的 .c/.h 到项目中
3、 在keil中 添加 dht11.c 文件
4、 增加定时器14,写微秒延时函数
5、 确定GPIO_CLK时钟被打开(开启PA8 输出模式)
6、 DTH11单总线协议
开始+响应+4字节数据+1字节校验
毫秒级延时 —》 tim14
// DHT11代码移植
void delay_us(uint16_t nus){ // DHT11 微秒延时
__HAL_TIM_SetCounter(&htim14,0);
__HAL_TIM_ENABLE(&htim14);
while( __HAL_TIM_GetCounter(&htim14)< nus);
__HAL_TIM_DISABLE(&htim14);
}
// 核心代码
FS_DHT11_Init();
uint8_t humiH,humiL,tempH,tempL;
while (1)
{
DHT11_Read_Data(&humiH,&humiL,&tempH,&tempL);
printf(“湿度:%d.%d 温度:%d.%d \r\n”,humiH,humiL,tempH,tempL);
HAL_Delay(1000);
}
第八章、SPI : LCD屏
1、LCD是什么 ?发光原理 ?
1.LCD:液晶显示
当有电流的时候,液晶层中的物质会有序排列
没有电流的时候,无序排列,光不可以透过
当像素点只有黑/白色的时候,灰度图(非黑即白)
三原色RGB:红绿蓝
一个像素点内部是由三个灯组成的
16位真彩色 24位真彩色
16位,就是有16个比特位,R占5位,绿色占5位,蓝色占5位;;;24位分别占8位,24位颜色更加丰富
2.lcd的发光原理
上电,液晶层有序
然后16位真彩色
128*128个像素点(横向纵向都是128个像素点)
lcd的本质也是一个外设,要和单片机进行通讯;
在通讯的时候,有
3.两种通讯方式
第一种是和单片机直接相连,没有低于20个引脚(单片机也需要提供20多个引脚与之相连)
引脚分类:控制引脚;数据传输引脚(数据引脚);接着是地址引脚;还有其他的引脚… 这种通讯方式十分浪费引脚。正常使用第二种通讯方式:
间接相连: lcd控制芯片;;;lcd和控制芯片相连接,控制芯片再和单片机相连接(单片机当主机,控制芯片当从机)----lcd厂商生产lcd的时候,将控制芯片一般都是和lcd一块生产打包组装; 迪文屏,喜欢用uart进行通讯;;;;;我们学习SPI通讯;
OLED用I2C进行通讯
2、16位真彩色 ?24位真彩色 ?
**16位真彩色:**每个像素使用16位来表示颜色,通常采用5-6-5格式,即5位用于红色,6位用于绿色,5位用于蓝色。这样可以表示的颜色总数为 (2^{16} = 65,536) 种颜色。
**24位真彩色:**每个像素使用24位来表示颜色,通常采用8-8-8格式,即8位用于红色,8位用于绿色,8位用于蓝色。这样可以表示的颜色总数为 (2^{24} = 16,777,216) 种颜色。
3、SPI是什么 ?电路 ? 什么主从模式 ?
**主设备:**控制通信的设备,生成时钟信号,发起数据传输。
**从设备:**响应主设备的请求,接收或发送数据。
4、三线制和四线制的区别 ?
(CC/SS)上面加个横线,横线代表低电平有效):片选线
SPI是三线制还是四线制?:如果主机从机都有两个通道两重身份,那么就是四线制;;;如果要么是主往从发要么从往主发,就是三线制;;;;
第二种说法就是,四线制有CSS,三线制没有CSS;
四线制(SCLK,MOSI,MISO,CC)
这是全双工,两个引脚起不同的作用,所以是串行(区分串行还是并行,要看多个引脚执行功能的时候,是同步发还是不同步发)
5、通讯原理
6、SPI 的优缺点
优点:
高速传输:SPI支持较高的传输速率,通常比I2C快,适合需要快速数据传输的应用。
全双工通信:SPI可以同时进行数据的发送和接收,提高了通信效率。
简单的硬件连接:SPI只需要少量的引脚(通常是4个),连接简单。
灵活的时钟频率:SPI的时钟频率可以根据需要进行调整,适应不同的应用场景。
多设备支持:可以通过选择不同的片选信号(CS)来连接多个从设备。
缺点:
引脚占用多:每增加一个从设备,需要额外的片选引脚,导致引脚占用增加。
无硬件地址:SPI没有内置的设备地址机制,所有设备都需要通过片选信号来选择,增加了复杂性。
不支持多主机:SPI通常是单主机的协议,多个主机之间的协调需要额外的设计。
无错误检测机制:SPI协议本身不提供错误检测和纠正机制,需在应用层实现。
7、lcd的通讯协议:SPI
**SPI:**看一个通讯协议,主要看:
看硬件的接线 通讯分类(全半同步异步串行并行)
接线主要是一主多从:SCLK线(时钟线);主机往从机发的线,从机往主机发送的线;这三根线是一根线分出去的
还有一根线叫做片选线,一个主机,很多个从机,每根片选线都是独立相连的;
从机往主机发送的线: MOSI(主发从收。。tx) MISO(主收从发。。rx):I是进,M是主,S是从,O是输出 (TX和RX是uart中的定义,这儿不能使用,所以用MOSI这两个名字定义)
通信协议:
8、极性和相位(SPI里独有的协议)
1.极性
时钟线处于空闲时的状态:0是低电平;
空闲的时候,如果处于1的话,就是高电平;
2.相位
写入/读取数据的时机(时钟线 上/下沿的奇偶沿 0是奇,1是偶)
极性为1,代表高电平的时候没有信号;此时相位=1时,就是在偶数沿(2.4.6.8.10)边沿写入数据
而如果相位是0,那就是在奇数边沿写入数据;;;
3.四种通讯协议
根据极性和相位两两组合就可以得到四种通讯协议;
0/0 0/1 1/0 1/1
00 空闲为低,读写在奇
01 空闲在低,读写在偶
10 空闲为高,读写为奇
11 空闲为高,读写为偶
不需要我们去写,直接通过API调用别人的函数就行
cubemx配置一些引脚,见图
lcd函数:
init初始化函数;;;clear清屏函数
DrawFont GBK16 显示ascll码函数 drawfont 1616显示中文
函数就是初始化先,用lcd-init,然后用一种颜色清屏(清屏函数),设置延时,再用另一种颜色,再设置延时;屏幕换颜色实验操作基本完成。
9、实验
移植步骤
1、写项目框架: printf移植框架
2、 移植 lcd 的 .c/.h 到项目中
3、 配置 MX 中gpio 重命名 (时钟频率不能太高 16M)
4、 汉字/ 图片 取模工具使用、数组
Lcd_Init();
Lcd_Clear(RED); // 屏幕初始化
Gui_DrawFont_GBK16(10,10,BLUE,BLACK,(uint8_t *)“HELLO”); // 打印ASCLL
char str[40];
sprintf(str,“%d.%d”,10,98);
Gui_DrawFont_GBK16(50,50,BLUE,BLACK,(uint8_t *)str); // 打印拼接字符
extern const char hqyj16[][32];
Gui_DrawFont_1616(0,0,RED,BLACK,hqyj16); // 打印汉字
extern const unsigned char gImage_rr[32768]; // 打印图片
showimage(gImage_rr);
首先把重定向函数复制进来;
#include “stdio.h”
#include “string.h”
__ASM (".global __use_no_semihosting"); struct FILE {int handle; };FILE __stdout;void _sys_exit(int x) { x = x; }void _ttywrch(int ch){ ch = ch;} int fputc(int ch, FILE *f) {uint8_t temp[1] = {ch};HAL_UART_Transmit(&huart1, temp, 1, 2);return ch;}