自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(86)
  • 资源 (2)
  • 收藏
  • 关注

原创 [002] [RISC-V] RTT与MRS配置C++环境

C++支持函数重载,所以生成的目标代码的名字和C会有些不同,对于中断服务函数改名后,就与中断向量表中命名不一致,导致程序无法正常跳转到中断。表中,因此需要调用这些函数的代码对变量进行初始化,否则构造函数中全局变量默认初始化为。在C++中,全局变量和静态变量的构造函数需要在main函数执行前执行,这些。,「方法二」最终测试并没有成功调用构造函数的初始化列表,具体原因暂时不知…全局构造函数的代码分配了段,链接时将其所产生的目标文件链接至。异常的结束地址,当异常产生的时候,就会被分配到指定的段地址中。

2022-09-13 16:58:59 1574 2

原创 [022] [STM32] 使用DCMI(DVP)驱动OV2640

STM32F4系列的控制器具有DCMI(Digital camera Interface)数字摄像头接口,它支持使用类似VGA时序获取图像数据流,支持原始的按行、帧格式来组织的图像数据,如YUV、RGB,也支持接收JPEG格式压缩的数据流。9]的10位数据,将其存至16位字的低10位,其余最高有效位清零(位11~15)。使用DVP外设(即STM32的DCMI外设)采集摄像头数据,将DVP的FIFO数据缓存到内部RAM中,再使用DMA的M2M模式搬运到FSMC外设控制的内存中,最后让图像在屏幕上显示。

2022-09-09 17:55:48 9230

原创 [021] [STM32] FSMC外设详解及模拟驱动LCD编程

对于NOR FLASH/PSRAM控制器(存储块1),通过FSMC_BCRx、FSMC_BTRx和FSMC_BWTRx寄存器(其中x=1~4,对应bank的4个区)设置FSMC访问外部存储器的时序参数,拓宽了可选用的外部存储器的速度范围。因此,一般地址与器件挂载的片选引脚相关,当不同的FSMC_NE引脚连接不同的外部存储器时,访问的存储区域不一样,达到控制多块存储器的目的。位时,FSMC使用HADDR[25:1] 地址来作为对外部存储器的寻址地址,即HADDR1对应A0,实际向存储器写入的地址会向。

2022-09-09 17:45:10 6079

原创 [001] [RISC-V] Linker Script 链接脚本说明

每个输出section都有一个类型,如果没有指定TYPE类型,那么连接器根据输出section引用的输入section的类型设置该输出section的类型。一个可执行文件中的所有符号都有自己的地址,并保存在「全局符号表」中,但此时「全局符号表」中的地址还都是原来在各个目标文件中的地址,即相对于零地址的偏移。表示当前地址,它是一个变量,总是代表输出文件中的一个地址(根据输入文件section的大小不断增加,不能倒退,且只用于。来描述,包括段名、段的类型、段的起始地址、段的偏移和段的大小等。

2022-09-05 16:07:00 3564 3

原创 [020] [STM32] CAN总线通信协议分析与应用

STM32ContentsCAN物理层CAN协议层STM32的CAN外设STM32的CAN控制相关结构体CAN通讯实验 1 CAN物理层CAN是一种异步通讯,只具有CAN_High和CAN_Low两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯。物理层形式分为两种:数据传输终端实际上就是两个阻抗为120欧姆的电阻,也称为终端电阻。总线上的总阻抗大概是60-70欧姆左右。 终端电阻的大小和传输线相关。CAN总线上可以挂载多个通讯节点,节点之间的信号经过总线传输,实现节点间通讯。由于CAN通讯协

2022-07-07 20:56:59 2580 1

原创 [006] [ESP32开发笔记] 使用Flash下载工具烧录固件步骤

ESP32Flash下载工具烧录固件步骤

2022-06-04 00:20:43 1833

原创 [005] [ESP32开发笔记] ADF基本框架

ESP32开发笔记ADF整体框架音频元素音频流音频事件音频管道注意事项 1 ADF整体框架esp-adf主要是基于运行,每个中最基本的运行单元就是,每个都由一个连接,每个之间靠传送音频数据()。例如,将MP3解码器和I2S流两个元素添加进管道,解码器的输入是MP3文件数据流,I2S流将解码后的音频输出到音频解码器芯片(Codec chip):通过链表管理,即每个元素通过链表连接在一起,和基于FreeRTOS的任务实现,即运行同时会启动了几个任务,基于队列、信号量、互斥体等机制实现数据的传输和消息的

2022-06-04 00:05:15 3826 4

原创 [004] [ESP32开发笔记] 音频开发框架ADF环境搭建——基于ESP-IDF

ESP32开发笔记ADF环境搭建打补丁常见错误与配置 1 ADF环境搭建安装成功后,会缺少几个库文件未安装,分别是内嵌的、(adf音频库)、(adf语音识别库),因为这些库在esp-idf-master仓库下都是以分支branch链接形式存储的。方法一:分别将这些文件复制到、、文件夹中。方法二:用git命令克隆仓库:在目录下执行:在目录下执行:以上仓库下载完成后,修改的内容如下:当两个仓库下载完成后,在目录下cmd执行,这一步将两个子模块切换到当前ADF要求的版本。方法

2022-06-03 23:47:15 3689

原创 [019] [STM32] 利用定时器输出比较模式的翻转功能实现不同占空比和频率的PWM输出

第一次进入输出比较回调函数时,由于定时器翻转前的电平为**低**电平,因此会翻转为高电平,因此先将`CCR1` 寄存器值设为脉宽值,即高电平持续时间第二次进入输出比较回调函数时,将先前的高电平翻转为低电平,因此将`CCR1`值设为`period_val - duty_val`,即低电平持续时间

2022-04-04 20:59:16 3964 3

原创 [018] [STM32] 定时器 基本定时/输出比较/输入捕获功能详解与HAL库编程

**计数模块**- 核心计数器:对计数时钟CK_CNT进行二次计数- 计数器寄存器`TIMx_CNT`:存放核心计数器运行时的当前计数值**自动重载模块**由自动重载寄存器`TIMx_ARR`组成,根据定时器不同的**计数模式**:- **递增**计数模式:`TIMx_ARR`值为核心计数器的计数**终值**- **递减**计数模式:`TIMx_ARR`值为核心计数器的计数**初值**

2022-04-04 18:12:04 10169 1

原创 [005] [蓝桥杯物联网] LoRa模块通信原理概述与API使用方法

LoRa (`Long Range`, 远距离)模块收发器型号为`SX1278`,可以完成**点对点**的数据通信功能,属于**半双工**通信,其原理图与引脚描述如下图所示:

2022-04-03 15:00:31 7795 10

原创 [017] [STM32] SPI协议详解及CubeMX+HAL函数配置分析

SPI(Serial Peripheral interface)串行外围设备接口是**同步全双工**的通信总线,在芯片的管脚上只占用**四**根线。- `SS/NSS/CS`:从设备选择信号线(**片选信号线**)。由主设备控制,选择指定的从设备。 > 当主机要**选择从设备时**,把该从设备的**SS信号线设置为低电平**,该从设备即被选中,即**片选有效**,接着主机开始与被选中的从设备进行SPI通讯。所以SPI通讯以**SS线置低电平为开始信号**,以**SS线被拉高作为结束信号**。- `

2022-04-02 22:44:31 12600 3

原创 [004] [蓝桥杯物联网] STS3x-DIS温度传感器IIC读取

温度传感器模块采用Sensirion STS3-DIS-B 温度传感器,I2C 接口,温度测量精度±0.2℃。- STS3x-DIS支持I2C快速模式(频率最高可达`1000khz`)- 在向传感器发送命令后,传感器需要最小的`1ms`等待时间才能接收到另一个命令。- 在**写**方向上,**必须发送校验和**,因为STS3x-DIS只接受后面跟着正确校验和的数据。在读取方向上,校验和的读取和处理由主机完成。

2022-04-02 14:59:45 4693 1

原创 [003] [蓝桥杯物联网] ADC硬件框架与HAL库轮询/中断/DMA方式编程

- ADC一般为12bit分辨率,数据可左对齐和右对齐(一般右对齐),同时具有单次、连续、扫描、间隔模式,其中扫描模式一般用于多通道的采集(多通道默认使能)。- 对于F1/4通道分为规则通道组与注入通道组,注入通道类似中断,可打断正在转换的规则通道组,优先转换注入通道;L0中没有注入通道,均为规则通道。- F1/4的ADC时钟来自APB2经过ADC分配器分频后的时钟,L0的ADC时钟来自HSI(16M)。- ADC的触发源除了内部通道外,还有外部事件触发源,比如定时器捕获,EXTI事件触发。- AD

2022-04-02 00:55:04 4672 2

原创 [002] [蓝桥杯物联网] RTC时钟硬件框架与配置流程

- LSI 37 kHz- LSE 32.768 kHz- HSE预分频后的时钟 `f_ck_apre`时钟用于对二进制`RTC_SSR`亚秒下行计数器进行计时。当其值为0时,`RTC_SSR`重新加载`PREDIV_S`的内容,`f_ck_apre`时钟计算:`f_ck_spre`时钟既可以用于**更新日历**,也可以作为16位唤醒自动重新加载计时器的时间基础。为了获得较短的超时时间,16位唤醒自动重新加载定时器也可以使用`RTCCLK`除以可编程的4位异步预分频器运行。`f_ck_spre`

2022-04-01 00:54:35 1790

原创 [001] [蓝桥杯物联网] 矩阵按键详解

`PA8`引脚为 OLED 显示屏 I2C SCL信号,在同时使用 OLED 屏幕和 2x3 矩阵键盘模块时,在每次矩阵键盘扫描任务前、后,需要**重置 `PA8` 到相应的工作模式和状态**;或**放弃使用** **`PA8` 对应列(B3/B6按键)**,使用 2x2 矩阵键盘功能 。

2022-03-31 17:03:07 1865

原创 [016] [STM32] 串口HAL库轮询、中断、DMA方式传输数据

串口收发单元主要利用:数据寄存器`DR`、发送引脚TX、接收引脚RX,以及状态寄存器`SR`的数据寄存器为空`TXE`标志、数据传输完成`TC`标志、接收寄存器非空`RXNE`标志。

2022-03-31 16:47:01 5271 1

原创 [015] [STM32] IIC协议详解与HAL库相关函数分析

IIC(Inter Integrated Circuit)总线在物理层由SDA(Serial data, 串行数据线)、SCL(Serial clock line,串行时钟线)和上拉电阻组成。- 每个连接到总线的设备都**有一个独立的地址**,主机可以利用此地址进行不同设备之间的访问- 连接到相同总线的 IC 数量受到总线的最大电容 400pF 限制 - 为了避免总线信号的混乱,要求各设备连接到总线的输出端时必须是**漏极开路(OD)**输出或**集电极开路(OC)**输出(IIC的空闲状态只能有

2022-03-29 22:48:51 5591 1

原创 [021] [RT-Thread学习笔记] CPU利用率计算

> 全速运行:不响应中断,也不去执行其他任务,就单纯让它在一个地方持续运行一段时间,这个值可以体现CPU的算力有多大。- `total_count`:单位时间内全速运行下的变量值,表现了单片机全速运行下,所能达到的最大值。- `count`:单位时间内**空闲**任务自加的变量值- `cpu_usage` :CPU利用率,`cpu_usage = (total_count – count)/ total_count × 100 %`- `CPU_USAGE_CALC_TICK`:cpu利用率计算周

2022-03-27 18:47:32 3094

原创 [020] [RT-Thread学习笔记] 消息队列

- 消息队列可以发送任意字节的数据(最大65535),但是每条消息的大小在初始化就已确定,之后不可以更改- 消息队列采用链式存储的队列结构,将队列缓冲区切割成`mq->max_msgs`个大小为`mq->msg_size + sizeof(struct rt_mq_message)`字节的节点,其中`struct rt_mq_message`为指向自身的结构,即链队的next指针,最后一个节点(最高地址)作为队头,从后往前链接消息节点- 每条消息前4个字节存储指针自身结构的指针(指针域),后面才开始存

2022-03-27 02:32:19 1101

原创 [019] [RT-Thread学习笔记] 线程位图调度算法

每个线程控制块都带有一个链表成员,根据优先级将`thread->slist`插入对相应优先级链表中,对于相同优先级采取时间片轮转调度方式,若线程当前时间片已用完,且其所在的优先级队列为当前系统最高优先级,则调用`rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),&(thread->tlist))`将此线程插入到末尾,切换到表头线程运行。

2022-03-26 03:26:48 1248

原创 [018] [RT-Thread学习笔记] 上下文切换分析

- 进入ESR前,硬件将psr, pc, lr, r12, r3, r2, r1, r0 压入 [from] 线程栈中- 进入ESR中,若rt_thread_switch_interrupt_flag为0则退出,反之将其清零- 进入ESR中,软件将r4 - r11 压入 [from] 线程栈中- 进入ESR中,更新当前psp为to线程的栈指针- 进入ESR中,软件将 [to] 线程栈中的保存的r4 - r11 弹出给寄存器- 进入ESR中,将lr = `EXC_RETURN`的 第二位置1表示返回

2022-03-25 20:26:12 2224 1

原创 [019] [ARM-Cortex-M3/4] 中断等待和异常处理优化

中断等待(延时):从检测到某中断请求,到执行了其服务例程的第一条指令时,已流逝的时间。可能造成中断等待的情况:- CPU正在处理另外一个相同或更高优先级的异常- CPU正在执行非对齐传输- 调试器访问存储器系统有些指令需要较多的周期才能完成:- 除法指令- 双字传送指令LDRD/STRD- 多重数据传送指令LDM/STM/PUSH/POP对于LDRD/STRD:为了保证中断及时响应而取消它们的执行,待返回后重新开始。对于多重数据传送指令:支持LDM/STM/PUSH/POP指

2022-03-24 03:12:42 1453

原创 [018] [ARM-Cortex-M3/4] 利用pendsv和systick异常编写一个简单的RTOS

对于一个函数:- 有自己的栈,只有不破坏栈即可(如数组越界访问),无需手动保存- 指令、全局/静态变量、常量都保存在flash上(启动时会将变量重定位到RAM中),无需手动保存- r0~r3、r12、lr、返回地址pc、xpsr发生中断/异常时,由硬件自动保存,并且在退出异常服务例程后,会自动恢复。- 进入函数前,保存r4\~r11到自己的栈中,退出函数后,恢复r4\~r1。(由ATPCS规定,C函数只要使用到这些寄存器,生成的汇编指令都会在进入函数时,将寄存器Push到栈中,退出时从栈中Pop)

2022-03-23 22:26:08 911 1

原创 [017] [ARM-Cortex-M3/4] 中断的硬件框架

中断源 - 引脚映射的外设,如GPIO/UART/DMA/TIMER等 - 触发方式,如GPIO可以配置上升沿、下降沿等方式触发 - 触发控制:使能中断、中断状态、中断类型等- 中断控制器 - 各中断源发出的中断信号,汇聚到中断控制器 - 可设置各中断优先级、使能/失能中断等操作 - 中断控制器向CPU发送中断信号,CPU通过读取中断控制器的寄存器,判断当前处理的是哪个中断 - 中断控制器有多种实现,比如: - STM32F103中被称为NVIC:Nested vec

2022-03-22 02:01:29 1224

原创 [016] [ARM-Cortex-M3/4] Systick异常实战

systick为24位向下计数的定时器- 时钟源可以选外部时钟源(AHB/8)或内核时钟AHB- `systick->ctrl`的tickint位使能systick异常、enable位使能定时器。(**定时器不使能就不会开始计数,也就无法触发异常**)- 当向下计数器`systick->val`减到0时: - systick->ctrl的tickint位使能systick异常、enable位使能态后由硬件置位,但若由于所需的处理任务花费时间太长而导致悬起状态再次置位,则需要清除systick的悬

2022-03-22 01:58:11 1330

原创 [015] [ARM-Cortex-M3/4] SVC和PendSV异常实战

PendSV和SVC一般用于OS,SVC用于产生系统函数的调用请求,从而导致内核的异常处理函数被调用,进而去使用内核的服务。- 使用`SVC #VAL`指令即可触发SVC异常,进入Handler模式——特权级,其中`#VAL`立即数一般作为系统调用代号。- 在SVC服务例程执行后,上次执行的SVC指令地址在异常栈帧中保存,==从SVC指令的机器码提取出立即数,即获得请求执行的功能代号==。

2022-03-22 01:54:46 2914

原创 [014] [ARM-Cortex-M3/4] Usage Fault 使用错误异常实战

测试使用**未定义指令**引发的使用错误异常(软件断点就是使用`未定义指令`来实现的)

2022-03-22 01:51:55 3966

原创 [013] [ARM-Cortex-M3/4] 异常与中断的具体内容

编号1~15为CM3/4内核**异常(**没有编号为0的异常,一般该地址设置MSP的初始值),还有240个请求信号来自CM3内核外的片上外设或外扩的外设的**中断**:

2022-03-22 01:49:10 1780

原创 [012] [ARM-Cortex-M3/4] 异常与中断处理流程

1. 正常程序是顺序执行的,在CM3中每执行一条指令,PC += 4;2. 通过跳转指令,程序可以跳转到特定的地址标号/特定的子程序处执行;3. 当异常/中断发生时,系统**执行完当前指令后**,将跳转到相应的ESR/ISR处执行。当执行完后程序**返回发生中断的指令的下一条指令**处执行。(进入ESR/ISR前先保护被中断程序的执行现场,从异常程序退出时,要恢复现场)

2022-03-22 01:44:18 6029

原创 [011] [ARM-Cortex-M3/4] CM3指令集与CMSIS函数汇总

#mermaid-svg-TiwIdPk7d0RxIFz3 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-TiwIdPk7d0RxIFz3 .error-icon{fill:#552222;}#mermaid-svg-TiwIdPk7d0RxIFz3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TiwIdPk

2022-03-19 00:27:15 882

原创 [014] [STM32] 启动模式&在SRAM中调试代码

因为Cortex-M3/4复位时会从`0x00000000`和`0x00000004`的相对位置取出MSP初值以及将复位向量地址赋给PC,在SRAM中的绝对位置就是`0x20000000`和`0x20000004`。STM32F1系列貌似从SRAM启动复位时,不会自动取出这两个值,因此无法正常运行。因此,需要点击debug引导`.ini`中的文件来初始化pc和sp指针,同时调试时不能点RST,必须退出重新进入debug以复位,同时也不能硬件复位。此外,如果还有问题可以试试`keilkill.bat`

2022-03-19 00:03:19 1590

原创 [013] [STM32] armclang对结构体位域的过渡优化——导致未按字对齐访问寄存器引发的异常

GPIO外设寄存器必须按字对齐方式访问,否则会引发异常(不同外设对齐方式不一样,需查看手册)结构体位域方式操作寄存器时,即便用volatile关键字告知编译器必须按字访问,但是armclang依然会优化成按字节访问(可能是版本问题)armcc编译器不加volatile也会按字访问,但代码量与编译器速度都不如armclang

2022-03-18 02:37:14 1045

原创 [012] [STM32] 代码重定位与清除BSS段深入分析

- 当加载地址与链接地址不同时则需要重定位- 散列文件中描述了程序的加载域和执行域的起始地址和长度- 重定位只能使用位置无关指令,即都是相对于当前PC偏移进行跳转的- 重定位即复制数据,需了解源(加载地址)、目的(链接地址)、长度(复制数据的长度),这些可以通过armlink提供的symbol中获取- keil中,变量>8字节才会放入到bss段,否则存放在rw_data中,使用bss段变量前需要将其清零- 在重定位代码段时,需要将flash第二条指令存放的`Reset_Handler`地址修改

2022-03-16 00:51:48 3556 6

原创 [001][Linux] gcc基本命令

GCC(GNU Compiler Collection,GNU编译器套件)是由GNU开发的编程语言译器,GNU工具链也包含了编译器、汇编器和连接器。一个C/C++文件要经过预处理(Preprocessing)、编译(Compilation)、汇编 (Assembly)和连接(Linking)才能变成可执行文件

2022-03-14 21:49:25 6129

原创 [011] [STM32] MDK使用命令行进行编译与链接

Keil MDK是常用的嵌入式集成开发环境(Integrated Development Environment),使用IDE,很容易操作,点点鼠标就可完成:* 添加文件* 指定文件路径(头文件路径、库文件路径)* 指定链接库* 编译、链接* 下载、调试那么每次点击MDK后会执行什么命令?

2022-03-14 16:30:12 3404

原创 [010] [ARM-Cortex-M3/4] 复位序列与类型

- **上电复位**:复位微控制器中的所有部分,其中包括处理器、调试支持部件和外设等。- **系统复位**:只会复位处理器和外设,不包括处理器的调试支持部件。- **处理器复位**:只复位处理器。系统复位与处理器复位不会复位调试部件,因此可以保持MCU与调试器间的连接,调试器也可以通过系统控制块(SCB)的寄存器产生系统复位或处理器复位。

2022-03-14 11:16:36 2609

原创 [010] [STM32] 串口通信基础知识与编程

- 波特率:每秒传输的码元个数。串口通信中采用一个二进制位表示一个码元,因此波特率=比特率(bit/s)- 起始位:先发出一个逻辑”0”的信号,表示传输数据的开始。- 数据位:可以是5~8位逻辑”0”或”1”,如ASCII码(7位),扩展BCD码(8位),一般为**小端**传输。- 校验位:一帧数据(数据位+校验位)中“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性。- 停止位:一个字符数据的结束标志,一帧数据传输完成后进入逻辑"1"状态,状态持续时间可编程控制(0.5、1

2022-03-14 02:03:25 3162

原创 [009] [ARM-Cortex-M3/4] 进位/借位与溢出

- 无符号数在相加时才会发生进位,相减发生借位;- 有符号数只有在两正数或负数相加时(减正数可视作加负数,减负数视作加正数)才会发生溢出,其他情况不会溢出;- 由于汇编不能真正区别有符号与无符号数,一般由程序员主观决定,对于无符号数关心`C`位,有符号数则关心`V`位。- 数字在计算机中是以其补码进行存储的,正数的补码为其本身,负数的补码为原码按位取反+1。

2022-03-13 23:12:54 5634

原创 [008] [ARM-Cortex-M3/4] 局部变量一定是保存在栈区的吗

- 局部变量不加`volatile`时,如果当前有**空闲**的寄存器(`sp`和`pc`除外),编译器会对其进行优化,即直接将值加载到这些寄存器中,在cpu内部完成运算,不需要访问内存和开辟栈空间;- 局部变量加`volatile`时,编译器不会对其进行优化,且永远都是先在栈中保存局部变量的值,再从栈中读出这些数据进行相应运算,最后弹栈释放开辟的栈内存。

2022-03-11 20:51:57 1109

Typora各种主题风格CSS样式

Typora markdown文本编译器主题CSS样式,风格有:二次元、极客、文墨、简约等。

2022-01-26

批量安装与卸载python的pip包

批量安装与卸载python的pip包

2021-12-25

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除