自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(50)
  • 收藏
  • 关注

转载 嵌入式学习笔记 - 奈奎斯特采样定理

当采样频率是5Hz时,还原出来的信号是一个频率为0的直流信号,显然,这里当采样频率小于信号频率的两倍时是无法准确还原原信号的;当然我们继续增加采样频率,当采样频率是40Hz和100Hz时,还原出的信号更加接近真实信号了。在我们周围有着各种各样的模拟信号,比如,电流,电磁波,温度,声音等等。要理解这个问题,我们需要理解在数字信号处理领域中一个非常重要的定理——采样定理,它是模拟信号数字信号之间的一个基本桥梁,本文将和大家一起学习奈奎斯特-香农采样定理。采样频率低于两倍奈奎斯特频率,这种采样被称为欠采样。

2025-05-12 22:56:14 2

原创 嵌入式学习笔记 - MSB, LSB

LSB: the least significant bit, 最低有效位,也就是 一个n位。MSB:the most significant bit, 最高有效位,指的是一个n位。数字中最右边的位,2^0,具有最低的权值。数字中的n-1位,具有最高的。

2025-05-12 20:24:56 24

原创 嵌入式学习笔记 - STM32 ADC,多重转换,内部参考电压,过采样

每个型号MCU通常由多个ADC器件,比如STM32F4有三个ADC器件,每个ADC器件有一个最大转换速率,一般为25Mhz,即一个ADC器件每秒最多转换25M次,两次转换之间需要有时间间隔,但是不同ADC器件之间没有转换间隔要求,即一个ADC器件转换完成,可以立即开始下一个ADC转换器件,这也叫做多重转换,这时相当于转换速率提升到25*3=75M。但是在某些情况下,这个供电电压是不稳定的,不如外部干扰,电源波动,有可能随外部一些其他用电器工作使用的大电流而导致电压不稳定,还有可能。获得实际所测量电压值。

2025-05-11 21:55:15 259

原创 嵌入式学习笔记 - 运算放大器,虚短,虚断

虚短指运算放大器的同相输入端(V+)与反相输入端(V-)在特定条件下呈现等电位状态,表现为两者的电压差趋近于零(V+ ≈ V-),但这种等效短路并非物理连接。

2025-05-11 01:05:24 602

原创 嵌入式学习笔记 - 运算放大器的共模抑制比

共模抑制比(Common Mode Rejection Ratio, ‌。

2025-05-10 22:25:47 413

转载 STM32CubeMX -使用LTDC驱动TFT-LCD屏幕(RGB屏)

在资源紧张的嵌入式系统中,在一般屏幕显示需求中过于浪费珍贵的SRAM空间,所以在不影响显示的情况下,建议使用RGB565格式,每个像素点只需要16bit(两个字节)的显存空间就够了。将该文件复制到工程目录中,添加进MDK工程,因为这是适用于STemwin的,所以该文件需要进行少量修改,改成如下即可,其它的都删除(文件的也有一段代码记得删除)。可以看到,图层1的白色区域和背景层混合,变为蓝色,而图层1的绿色区域与背景层混合,变为,我也不知道这是什么色~DMA2D只是为了方便修改SDRAM中的显存用的。

2025-05-10 15:42:47 27

原创 嵌入式学习笔记 - 垂直消隐期

2025-05-09 19:45:30 166

原创 嵌入式学习笔记 - 关于单片机的位数

单片机的位数是指单片机数据总线的宽度,也就是一次能处理的数据的位数(bit),不是地址总线的宽度,也不是存储器的位宽,地址线的位数可以跟数据线不一致,像51单片机的地址总线为16位,但是它是8位单片机,ARM的存储器也有8位的但是它是32位机。16位的单片机,例如MSP430,感觉16位的单片机比较尴尬,高不成低不就,要求低一点,8位MCU就够,高级点不如用32位MCU。一般不跑嵌入式OS。通常我们经常说一个单片机是8位的,16位的,32位的,那么怎么判断一款单片机的位数是多少位呢,判断的依据是什么呢,

2025-05-09 16:46:58 195

原创 嵌入式学习笔记 - 关于结构体成员地址对齐问题

其地址分配如下图,因为c的大小位2字节,所以起始地址可以放在起始为0,2,4,8起始地址的内存地址,又因为结构体总大小为最大成员变量的整数倍,所以此结构体大小为4*2=8byte。其地址分配如下图,因为b的大小位4字节,所以起始地址必须另起一行,放在起始为0,4,8,C起始地址的内存地址,又因为结构体总大小为最大成员变量的整数倍,所以此结构体大小为4*3=12byte。因为加了#pragma pack(1),按照如下图分配地址,结果为5。①每个成员变量的起始地址必须为其数据类型所占空间大小的整数倍。

2025-05-09 16:13:17 175

原创 嵌入式学习笔记 - 一段在LCD屏幕上画线段的代码

那么每次Y方向usY_Current都会自加, 而usX_Current 每2次自加一次,这样就实现了Y方向每增加2次,X方向增加一次。所以1058行到1067行实现的是增量大的方向,比如说1Delta_X=5,1Delta_Y=10,那么增量大的方向就是Y,1Distance 等于1Delta_X,1Delta_Y中比较大的那个值。1Delta_X,1Delta_Y分别代表线段的横向纵向增量,1Error_X,1Error_Y,初始值为0,

2025-05-08 22:28:55 180

原创 嵌入式学习笔记 - LCD

或者8080,通过命令的方式对液晶控制器芯片进行操作,最终液晶控制器芯片将显存里面的显示数据(RGB格式的数据)传送给LCD.带控制器的LCD屏幕跟STM32单片机的交互方式,可以为串口,也可以为SPI,下图中间左边一个为不带MCU的RGB屏,中间右边一个为带MCU的MCU屏。二 MCU屏幕通常接口8080, RGB屏幕通常接口LTDC。三 FSMC 模拟LCD 8080时序。

2025-05-08 16:58:58 173

原创 嵌入式学习笔记 - MB,KB,kb

1MB=1024KB=1024*1024B,是指1024千个字节,单位是字节。1kb是1024个bit, 单位是bit, 1bit是二进制的一个位。1KB=1024B,是1024个字节,单位是字节,1Byte=8bit,1个字节等于8个bit。

2025-05-07 14:40:36 83

原创 嵌入式学习笔记 - FMC SDRAM控制器

一 FMC拓展外部SDRAM方式:二 SDRAM的刷新机制:Auto Refresh:Self Refreesh:

2025-05-06 22:01:58 99

原创 嵌入式学习笔记 - STM32 SRAM控制器FSMC

一 SRAM控制器内部结构图:二 SRAM地址矩阵/寻址方式:SRAM的地址寻址方式通过行地址与列地址交互的方式存储数据三 STM32 地址映射 从STM32的地址映射中可以看出,FSMC控制器支持扩展4块外部存储器区域,每种存储器区域又可以支持4片存储器细分区域。

2025-05-05 22:22:17 324

原创 嵌入式学习笔记 - SPI FLASH写使能命令

其中SPI_FLASH_WaitForWriteEnd();函数就是在查询写入忙busy位的标志等待写入完成,见下图具体函数实现。由以上可见,写使能命令就是在写芯片状态寄存器,也是一个写入的过程。由此可见当程序执行写使能命令后,这个BUSY标志位也是会被置1的,

2025-04-29 10:54:22 226

原创 嵌入式学习笔记 - 关于STM32 SPI控制器读取以及写入时,标志位TXE, RXNE的变化

发送数据寄存器SPI_DR为空时,TXE由硬件自动设置为1, 接收数据寄存器SPI_DR接收到数据时,RXNE由硬件自动设置为1。位标志自动被清除,读SPI数据寄存器会自动清除。二 软件清除,需要软件参与。当写入SPI-DR时。

2025-04-29 10:22:43 267

原创 嵌入式学习笔记 - HAL_xxx_MspInit(xxx);函数

使用cubeMX生成的HAL库函数中,所有外设的初始化函数HAL_xxx_Init(&xxxHandle)中都存在有此调用函数,此调用函数其实是对各外设模块比如UART,I2C等的底层硬件初始化,包括UART时钟,以及UART用到的GPIO的工作模式以及GPIO的相应的时钟,以及串口NVIC的配置,即。三 以下为HAL_UART_MspInit(huart)函数的内部结构,有下图可以看出,是对UART相关的时钟以及GPIO进行配置的过程,以及NVIC配置,也就是。初始化配置各外设的底层硬件。

2025-04-26 20:31:39 380

原创 嵌入式学习笔记 - SPI通讯协议

SCK的初始电平状态有两种,可以为高电平,也可以为低电平,MISO&MOSI电平采样的时刻,可以为奇数边沿采样,也可以为偶数边沿采样。按照以上两中不同进行组合,可以有4种通信方式,如下图所示,主机与从机的通信方式要保持一致。

2025-04-26 12:44:07 150

原创 嵌入式学习笔记 - STM32 I2C 速率以及时钟控制寄存器(I2C_CCR)的设置以及代码实现

I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle) 代码如下。这个MODIFY的功能是,先与非 第二个参数(要设定的寄存器位的掩码),然后或上第3个参数达到设定寄存器相应位的目的。100kb/s =12.5 KB/s,因为1 byte = 8 bits。为 5μs / (1/8) =40, 此处以PCLK1=8M为例说明。Thigh=(1/100k)/2=5us, 因为是半个周期所以除以2。为了达到5μs的高电平或低电平时间。

2025-04-24 22:12:35 259

原创 嵌入式学习笔记 - I2C通信

主机向某从机写数据的具体过程如下,开始时SCL,SDA均为高电平,主机拉高SCL,拉低SDA发送起始信号,然后发送从设备地址以及写bit,发送地址的具体过程是主机通过拉高SCL时发送一位SDA bit值,拉低SCL时改变成下一位SDA bit值,待SCL再拉高时发送此位bit,也就是说一个SCL周期发送一位SDA bit数据,之后主机拉高SCL电平,获取从机发送的SDA状态,然后主机拉低SCL,从机更改SDA状态,然后主机拉高SCL状态,获取从机SDA状态,如此循环往复得到从机数据。

2025-04-22 21:55:31 369

原创 嵌入式学习笔记 - HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 函数解析

其中划红线语句的意思是,将串口句柄huart 结构体变量中的成员hdmatx句柄的成员之回调函数地址,赋值为UART_DMATTransmitCplt;第2993行,划红线的句子,将串口发送完成中断位置1,也就是说将DMA发送完成中断回调函数又转移到了穿哭发送完成中断函数里去了,第2990行禁止DMA发送见下面寄存器,这是因为是Normal mode。UART_DMATransmitCplt()函数如下所示,

2025-04-21 23:09:36 242

原创 嵌入式学习笔记 - volatile 跟 static

那么就说明个变量a是易变的,动荡的,比如操作系统多个线程都会操作它让其发生变化或者被外部事件以及硬件改变,使用volatile后程序在每次访问的时候会直接访问内存的真实地址,而非变量缓存,,上面的代码永远检测不到这样的修改。static修饰局部变量使得变量的存储位置发生了变化,本来局部变量是放在栈区的,被static修饰后,放在内存的静态区,生命周期变得更长了,‌:普通局部变量在函数调用结束后销毁,而静态局部变量存储在静态区,生命周期与程序相同,函数多次调用时保留上一次的值。英文含义:易变的,动荡不定的,

2025-04-21 22:16:00 435

原创 嵌入式学习笔记 - _attribute_的作用

关键字可以指定变量或类型的特殊属性。定义无符号整形变量aDST_Buffer[]数组,放在内存的0x30000000位置。在C或C++编程中,使用。

2025-04-21 18:24:09 91

原创 嵌入式学习笔记 - Printf()函数以及scanf ()/getchar()函数的实现

例如printf("你好");二 getchar()函数的实现。一 Print函数的实现。

2025-04-19 16:29:53 98

原创 嵌入式学习笔记 - 配置一个外设中断的完整步骤

第一步通过函数HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);获取SYSCLK时钟源,AHB,APB1,APB2分频值,第二步通过根据以上数值,通过HAL_RCC_GetPCLK2Freq()获取定时器时钟值,= 8000000;初始化值,复位时的值。

2025-04-19 01:07:30 141

原创 嵌入式学习笔记 - HAL_RCC_GetClockConfig( ),HAL_RCC_ClockConfig()函数解析

如下图,RCC_ClkInitStruct.APB1CLKDivider,RCC_ClkInitStruct.APB2CLKDivider都使用了PPRE1的寄存器位置设定值,而实际PPRE2的寄存器位置要左移三位。函数中,RCC_ClkInitStruct.APB1CLKDivider,RCC_ClkInitStruct.APB2CLKDivider的赋值都使用了PPRE1位置的寄存器分频设定值,二 至于上面提到的为什么PPRE2要右移3位,那是因为。函数中配置PPRE2时要左移三位。

2025-04-19 00:05:04 332

原创 嵌入式学习笔记 - _NVIC_SetPriorityGrouping(uint32_t PriorityGroup)函数讲解

可见要想写入PriorityGroup,需同时将0X5AF写入VECTKEY相应位,以及将PriorityGroup写入相应位。)的方式,清除相应位(相应位赋值0),其他位为1。(VECTKEY与PriorityGroup。一 以下为寄存器SCB_AIRCR 寄存器。相应位的具体数值即可以成功写入寄存器相应位。第1487~1490行,

2025-04-18 23:28:29 133

原创 嵌入式学习笔记 - stm32 的时钟之AHB, APB1, APB2, HCLK,PCLK1, PCLK2

Advanced High Performance Bus,高级性能总线,又叫PCLK2(peripheral clock2, 外设时钟2),链接内核,CPU,DSP以及高速存储模块。, 高级外设时钟2,,给低速外设提供时钟。,给高速外设提供时钟。

2025-04-17 23:23:53 210

原创 嵌入式学习笔记 - RS232标准通信

控制器一般使用TTL电平标准,所以一般会使用MAX3232芯片对TTL电平与RS232电平进行转换,转化成232电平是为了远距离传输以及抗干扰。是否发送起始位,是否含有校验位,停止位的长度,只要双方约定好就可以。一 下图为232信号传输框图,控制器A的串口充当了发射器接收器。三 RS232标准数据传输协议层。

2025-04-17 22:04:13 148

原创 嵌入式学习笔记 - 关于通讯的各种分类

例如9600波特率,1s传输9600位,10位一个字节包含起始位,停止位,那么1s传输960个字节。并行通讯与串行通讯的区别可以从如下图中看出,并行通讯是多个数据位一起传输,串行通讯是单个数据位传输。波特率跟比特率,比特率是指一秒中传输多少位bit,波特率是指一秒钟传输多少码元,串行通讯的数据传输速度比较慢,传输距离比较远,但是抗干扰能力强,成本低。并行通讯的数据传输速度比较快,传输距离比较近,但是抗干扰能力弱,成本高。半双工:同一时刻只能收或者只能发,异步通讯,无时钟信号线,如串口通讯。

2025-04-17 18:13:18 138

原创 嵌入式学习笔记 - FreeRTOS 中SysTick,IRQ,PendSV的关系, 以及systick中断优先级设置高低问题

也就是说每次SYSTICK中断时,挂起PendSV异常并将任务切换放到PendSV异常中,SYSTICK中断结束后,进入ISR中断,ISR中断结束后执行PENDSV中断,进行任务切换。二 为了避免上述情况,可以将SYSTICK的中断优先级设置为最低,也就是IRQ的优先级高于SYSTICK中断,这样就可以在没有任何IRQ的中断处理程序时,进行上下文切换,但是这样会带来新的问题,就是导致任务切换有很大的延迟,特别是IRQ的中断频率跟Systick的中断频率接近时。一 若SYSTICK的中断优先级高于IRQ。

2025-04-17 00:21:15 321

原创 嵌入式学习笔记- NVIC总结

① 使用HAL_NVIC_SetPriority()函数设置中断优先级顺序。② 使用HAL_NVIC_EnableIRQ()使能中断。

2025-04-15 18:33:47 89

原创 嵌入式学习笔记 - 函数 __NVIC_EnableIRQ(IRQn_Type IRQn)

那么CM3支持240个中断,就需要240 bits。ISER0 bit[31:0]对应外设中断31-0,ISER1 bit[27:0]对应外设中断59-32。ISER[0]或者ISER[1] 寄存器是32位的,见上图,每一位代表一个中断,利用上述把数字1U按照左移中断号位数后就正好对应此中断在寄存器的位置,也就真好是所要求的寄存器值,1FU是个掩码,屏蔽32位以外的数值。就是 IRQn右移5位,就是除以32,那么经过这么处理后>=32的中断号会变成ISER[1],小于32的中断会变成ISER[0],

2025-04-15 16:51:06 221

原创 嵌入式学习笔记 - 函数讲解 HAL_RCC_GetSysClockFreq() (2)

函数具体讲解见下图,基本过程就是如何根据选择的时钟源HSI或者HSE的大小(注意HSE的大小时钟树中默认不可选,而且时钟源数值被定义为常量8000000hz,存放在stm32f1xx_hal_conf.h文件中,如果用户使用了其他数值的时钟源大小,要主动去修改这个文件中的时钟源常量),以及各各分频参数求出SYSCLK的值。当寄存器值等于0~7时,数组值为0不右移,当数组值等于8时右移一位2分频,等于9时右移2位4分频,等于10时右移3位8分频,等于11时右移4位16分频,以此类推。

2025-04-15 15:10:02 304

原创 嵌入式学习笔记 - STM32的HAL_RCC_GetSysClockFreq()函数讲解(1)

此函数关于时钟频率的计算是建立在内部时钟源HSI_VALUE(如果选择的是这个时钟源),或者外部时钟源HSE_VALUE(如果选择的是这个时钟源)确定的情况下,通常情况下,这两个时钟源数值被定义为常量8000000hz,存放在stm32f1xx_hal_conf.h文件中,如下图。而且在cubeMX 的时钟树中这两个值也是不可选的,如下图,但是如果用户使用了非8M的外部晶振,那么这个数值就要手动更改,以保证系统获得的SystemCoreClock数值是正确的,系统各运行时基是准确的。

2025-04-15 13:43:18 233

原创 嵌入式学习笔记 - NVIC配置函数

获取方式为先读取CM3系统控制块SCB寄存器AIRCR(控制NVIC分组的位,位于此寄存器中)的值,注意此时获取的是整个AIRCR寄存器的值,然后与掩码SCB_AIRCR_PRIGROUP_msk(这是个宏定义,为0x07左移8位,就是控制NVIC分组的三位移到寄存器中的实际位置)相与,屏蔽其余各不相关的位仅取与控制NVIC相关的三位,然后右移8位,就得到了实际的NVIC分组数据值。先看NVIC_GetPriorityGrouping()函数,获取系统NVIC分组信息,用户编写的按键配置函数。

2025-04-14 23:38:36 215

原创 嵌入式学习笔记 - 异常和中断的区别

中断一般是连接到内核的外部器件(外设)产生,比如外设产生中断提示数据传输完成,也称。异常通常来自内部,内核活动产生,比如执行指令出错,也称。STM32中 异常和中断的处理方式是一样的,都是通过中断的形式进行处理。

2025-04-14 13:59:32 105

原创 嵌入式学习笔记 - STM32启动文件中汇编语句的解释

如果我们在使用某个外设的时候,开启了某个中断,但是又忘记编写配套的中断服务程序或者函数名写错,那当中断来临的时,程序就会跳转到启动文件预先写好的空的中断服务程序中,并且在这个空函数中无线循环,即程序就死在这里。开辟栈的大小为0X00000400(1KB),名字为STACK,NOINIT即不初始化,可读可写,8(2^3)字节对齐。这些函数都是空的,真正的中断复服务程序需要我们在外部的C文件里面重新实现,所以这里都用了。紧挨着SPACE语句放置,表示栈的结束地址,即栈顶地址,栈是由高向低生长的。

2025-04-13 23:20:29 333

原创 嵌入式学习笔记 - 函数调用过程中栈是如何操作的

funcB 的栈帧包含局部变量 b 和返回地址(返回到 main() 中的地址)。当 funcA 被调用时,funcA 的栈帧会被压入栈中,包含参数 a 和局部变量 x。如果栈的空间大小不够大,而程序嵌套太多的函数,栈的空间被耗尽,就会导致栈溢出。当 funcA 执行完毕后,栈顶的栈帧被弹出,控制权返回到 funcB 中。当 funcB 执行完毕后,栈顶的栈帧被弹出,控制权返回到 main 中。main 函数的栈帧被压入栈中,包含局部变量、返回地址等。main 执行完毕,程序结束。

2025-04-13 21:54:58 140

原创 嵌入式学习笔记 - STM32 的时钟配置,HAL库方式以及标准库方式

另外注意此代码是cubeMX自动生成的,当用户在图形化配置界面选择好各时钟来源分频参数,以及想要的最终频率如72M,就会自动生成这个代码,当你选择另一些配置时会生成另一个代码,正如上图所示。实现代码:使用内部时钟源HSI 作为PLL 的时钟源,然后将PLL 作为系统时钟源,并设置系统时钟为72M。可以看出,相比cubeMX HAL库,标注库的时钟配置方式,有点笨拙,不灵活,而且不直观。函数进行配置写入寄存器。SetSysClock函数,根据宏定义选择配置函数,不同的频率值对应不同的配置函数。

2025-04-13 17:17:19 276

空空如也

空空如也

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

TA关注的人

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