自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(337)
  • 资源 (8)
  • 收藏
  • 关注

原创 细说MCU用自带的波形发生器实现DAC输出的方法

在TIM3模式和配置界面中,先将模式(Mode)的时钟源(Clock Source)选择为内部时钟(Internal Clock);在定时器设置(Counter Settings)区,将预分频因子(Prescaler)设置为0,计数器周期(Counter Period)设置为169。开启定时器的初始化语句是HAL_TIM_Base_Start(),初始化三角波发生器的语句是HAL_DACEx_TriangleWaveGenerate()和启动DAC的语句HAL_ DAC_Start()。

2024-07-26 15:20:59 362

原创 细说MCU用DMA改变DAC输出信号频率和改善输出波形质量的方法

如果VREF为3.3 V,在开启缓冲后,虽然数据输出寄存器数据在0~4095范内变化,但DAC的真实输出会在0.2~3.1 V之间。前面例子所给的数据中,送给数据输寄存器的最大值为4090,最小值为5,所以在峰值处会有饱和现象。虽然定时器的更新频率保持为1 MHz,即DMA会1us传递一个数据到DAC的数据输出寄存器;但由于数据点数由50增加到200,所以传递一个完整周期的数据所需的时间,也就由原来的50us增加至200us。此时,再用示波器查看PA4引脚上的波形,得到的该正弦波的频率为20 kHz。

2024-07-25 17:07:23 850

原创 细说MCU用DMA实现DAC输出的方法

这里给出的SineWaveData,长度为DAC_BUFFER_SIZE(在前面已将其定义为50)。这个数组中的数据,实际是一个周期的正弦信号数据;也就是说,将一个周期的正弦波形,用50个数据点来表示。

2024-07-25 16:20:57 614

原创 细说MCU用定时器控制单路DAC模块设计和输出锯齿波的实现方法

硬件配置完成后,在代码中实要做的只有两步:一是用库函数HAL_DAC_Start()启动DAC,二是用函数HAL_DACValue()给DAC的数据寄存器赋值。系统时钟为170MHz时,计数器的计数周期为(169+1)(9+1)/(170*10^6)=10us,对应的频率为0.1MHz。本例依然是在初始化阶段启动DAC,即函数HAL_DAC_Start()放置的位置不变,而将给DAC的数据寄存器赋值的语句放置到定时器的中断中,从而实现用定时器中断控制DAC的输出频率。使能TIM3的中断,优先级设置为0;

2024-07-22 16:38:02 678

原创 细说MCU用单路DAC模块设计和输出锯齿波的实现方法

不过,如果开启了DAC的缓冲(Buffer),输出的电压最小值不会为0,最大值也不会是VREF,而是会在0.2 V~VREF-0.2 V之间。DAC模块从MCU引脚上最终输出的电压(VDAC),与输入到它的数据输出寄存器中的数值有关。由于STM32G474RE中的DAC为12位,也就是说,当数据寄存器中的值为4095时,DAC会输出最大电压值,但这个最大值具体是几伏,还与MCU的参考电压(VREF)有关。DAC启动之后,可以在while(1)中给其数据寄存器赋值,这样就可以通过它输出所需要的模拟电压信号。

2024-07-20 17:00:56 778

原创 细说MCU用DMA控制ADC采样和串口传送的实现方法

首先定义存储ADC采样结果的数组,本例中用数组变量ADC1ConvertedData。//信号源。

2024-07-19 17:10:16 1212

原创 细说MCU用定时器控制ADC采样频率的实现方法并通过Simulink查看串口输出波形

本文作者的文章 细说MCU用定时器控制ADC采样频率的实现方法-CSDN博客中说到了一种用定时器控制ADC采样频率的实现方法,并通过串口调试助手把串口接收到的数据输出到计算机显示器。在这篇文章中,利用同样的硬件设置,作者通过MATLAB中的Simulink建立一个串口接收模型,然后和.ioc工程的串口握手通讯。接收并在Time scope控件上显示串口数据波形在display控件上显示数据。

2024-07-18 15:44:29 787

原创 细说MCU用定时器控制ADC采样频率的实现方法

/信号源//串口打印return ch;

2024-07-12 17:13:48 1006

原创 细说MCU的ADC模块单通道连续采样的实现方法

TIM3中断定义一个数组,用于存储A/D转换结果。每执行一次回调函数,就将此次A/D转结果存入数组,直到存满。随后,在主程序中,通过串口送出数组中存储的数据。其中,数组长度ADC_CONVERTED_DATA_BUFFER_SIZE定义到main.h中。

2024-07-05 10:55:16 829

原创 细说MCU的ADC模块单通道单次采样的实现方法

由于希望在产生按键中断时,启动ADC采样,所以,需要重定义外部中断EXTI的回调函数。这个回调函数可以写在main.c文件后面的一个注释对中。

2024-06-22 17:12:52 1350

原创 细说MCU定时器模块的输入捕捉功能的实现方法

由于要记录两次发生捕捉中断时刻计数器的值,所以需要定义四个变量:存放两次计数值及它们之间的差值的变量,以及一个计数标志用的变量。将这些变量定义为全局变量,放置到main.c中的一个注释对中。//存放第一个计数�??//存放第二个计数�??//存放两个计数值之�?//计数标志这个函数在stm32g4xx_hal_tim.c中是以弱函数的形式被定义的,实际是一个空函数,所以要在main.c中重新定义它。/*记录第一个计数值 *//*记录第二个计数值 *//*计算两次计数值之值 */

2024-06-22 10:52:29 985

原创 细说MCU输出互补型PWM波形时设置死区时间的作用

因为实际开关的动作(导通和关断)是需要时间的,虽然互补型PWM在理论上能保证两路信号完全互补,但从信号发出到开关实际动作,还是需要一定时间的。死区时间的设置,就可以避免两个开关同时导通的可能性。由于没有设置计数器的预分频因子,所以两次计数的时间间隔为(1/170)μs,这个100所代表的时间就是100个定时器的时钟周期,约为0.588 ns。在截图中,可以清楚地看到,在PA8(通道1)由低电平变为高电平之前,PA7(通道2就已经由高电平变为了低电平,这两个跳变沿之间的时间就是死区时间。

2024-06-19 13:01:04 733

原创 细说MCU输出互补型PWM波形的实现方法

随后,还需要在主程序中的初始化代码部分调用库函数,开启定时器中断、使能PWM。启动定时器中断还需要用库函数HAL_TIM_Base_Start_IT()。调用该函数的语句如下:其中,htim1为TIM1的句柄。

2024-06-19 08:30:00 1508

原创 细说MCU输出两路PWM波形及改变占空比的实现方法

目录一、硬件及工程 二、建立工程三、代码修改四、下载运行五、改变PWM波形占空比1、定义两个全局变量2、启动定时器3、重写TIM3中断回调函数六、下载并运行 文章依赖的硬件及工程配置参考本文作者的其他文章:细说ARM MCU的串口接收数据的实现过程-CSDN博客 https://wenchm.blog.csdn.net/article/details/139541112 通过PB4输出配置一个通道TIM3_CH1、通过PB5输出配置一个通道TIM3_CH2。用示波器进行观察PB4

2024-06-18 10:31:38 1181

原创 细说MCU通过定时器输出PWM波形的实现方法

* 定时器中断回调函数操纵GPIO PC3输出波形 */

2024-06-18 08:30:00 889

原创 细说MCU定时器中断的实现方法

在main.c中重新定义回调函数HAL_TIM_PeriodElapsedCallback()。在其中让PA5的输出状态翻转。本例中,定时器的预分频因子(Prescaler)和计数器周期(Counter Period)分别置为999和16999,定时器的时钟频率为170 MHz,最终TIM3中断的周期为(999+1)/(170×10⁶)×(16999+1)=0.1(s),即频率为10 Hz。

2024-06-13 08:30:00 1113

原创 细说MCU串口函数及使用printf函数实现串口发送数据的方法

如果想查看具体收到的是什么数据,可以按一下NUCLEO-G474RE板上的B1键,在串口助手上就会显示所接收到的数据。连续发送4次数据53 10 45 ,会收到4次数据正确的消息“Everything is OK” ,并不是程序写错了,而是程序没写判断数据的对错,程序只是判断数据是否准备妥当了。在上面putchar函数的定义中,串口发送函数使用的是库函数HAL_UART_Transmit(),每次发送1字节的数据。按下B1键,看看MCU接收到了什么数据并显示到串口助手上,按一下B1显示一次。

2024-06-12 11:28:26 1160

原创 细说MCU修改回调函数调用模式的方法

在本文作者的文章中:细说ARM MCU的串口发送数据的实现过程-CSDN博客串口每接收到1字节的数据,就调用一次回调函数。实际上,可以通过修改参数,在接收了一定长度的数据之后再调用回调函数。下面尝试当串口接收到3字节数据后再调用一次回调函数。

2024-06-12 09:21:06 727

原创 细说ARM MCU的串口发送数据的实现过程

前面的文章介绍了用串口的接收中断来接收数据,本文介绍通过串口从MCU向外发送数据。

2024-06-11 15:27:57 582

原创 细说ARM MCU的串口接收数据的实现过程

重定义串口中断接收的回调函数HAL_UART_RxCpltCallback()。这个函数已经在stm32g4xx_ hal_uart.c中有定义,只不过被定义为弱函数,实际就是一个空函数。需要重写它。与写EXTI的回调函数类似,也将该函数写在main.c中。串口有数据送来,会执行中断服务函数USART2_IRQHandler(),然后该函数又会调用函数HAL_UART_IRQHandler()。

2024-06-11 14:22:17 1429

原创 几种在ARM MCU上控制流水灯的方法

对于初学者,在ARM单片机上控制流水灯的亮灭是必经之路。控制流水灯的亮灭有很多方法,比如8个LED,可以控制8灯同时亮、灭;可以控制8灯依次亮、灭;可以控制8灯依次亮、灭,然后反方向再依次亮、灭;可以控制8灯依次亮、灭;可以控制8灯依次点亮全部、然后依次熄灭全部;

2024-06-02 08:00:00 661

原创 细说ARM MCU中的HAL_GPIO_Init()函数的实现过程

继续上一篇文章,分析HAL_GPIO_Init函数是如何实现的,该函数的定义在stm32g4xx_hal _gpio.c文件中。

2024-06-02 08:00:00 669

原创 优化C/C++代码:处理大量case表达式时的优化策略

当 C 语言项目中的 switch 语句包含多达 300 多个 case,就可能导致性能问题,特别是如果每个 case 的逻辑相对简单且执行时间较短。在这种情况下,大部分时间可能被花在了通过跳转表(jump table)来找到相应的 case 执行代码上。

2024-06-01 08:00:00 411

原创 优化C/C++代码:内联函数与宏展开在处理大量case表达式时的应用

使用内联函数或者宏展开是可以优化C/C++代码执行效率的。减少函数调用的开销。

2024-06-01 08:00:00 279

原创 细说ARM MCU中的MX_GPIO_Init()函数的实现过程

本文中使用ST的开发板NUCLEO-G474RE,板上MCU型号为STM32G474RET6。配套的扩展板:实例中当开发板上的按键B1被按下时,PC13引脚被上拉至高电平VDD,不按下时,PC13下拉至低电平GND。用按键B1控制板上的LD2灯的亮灭,当PA5输出高电平时LD2亮,否则灯灭。

2024-05-30 11:25:02 772

原创 细说常见的原子操作 (CAS)和(LL/SC)及常与其一起使用的仲裁(Arbitration)

例如,它可能导致“ABA”问题,即一个值从 A 改为 B,然后又改回 A,尽管这个值变化了,但由于 CAS 只比较是否与期望值相等,因此可能会错过这种变化。例如,在基于锁的仲裁中,原子的锁获取和释放操作可以确保只有一个线程能够持有锁,从而保证资源的独占使用。在某些情况下,这些指令可能会被编译器或运行时环境转换为其他形式的原子操作,以便在不支持LL/SC的硬件上执行。所以,虽然仲裁不是一个直接的原子操作,但在设计高并发和分布式系统时,它是确保线程安全和正确性的关键机制之一,而原子操作则是其实现的基础工具。

2024-04-29 15:59:19 905 2

原创 STM32H745BIT6上的ARM Cortex-M7和Cortex-M4核心共享SRAM4中的数据的方法

这只是一个简化的例子,只是提供了一种解决问题的思路。在实际应用中需要考虑更多的细节,比如错误处理、同步机制的选择(信号量、邮箱、共享变量等)、中断处理以及性能优化等。此外,更需要确保两个核心的时钟和外设访问控制正确配置,以便能够正确地访问共享SRAM。在具体实现时,还需要参考STM32H7xx的参考手册和HAL库提供的API来完成相应的配置和操作。

2024-04-29 09:54:55 1458

原创 细说HAL_GPIO_WritePin()函数写操作BSRR和BRR端口寄存器的原理

第一句define宏定义中的(void)0U,是空语句的表达式。将assert_param(expr)定义为:如果表达式expr真,就是空语句(void)0U;如果表达式expr假,则为assert_failed()函数。define宏定义后,就是对assert_failed()的声明。如果USE_FULL_ASSERT未定义过,则会编译#else中的内容,就是用define宏定义直接将assert_param(expr)定义为空语句(void)0U。

2024-04-28 16:15:54 2675

原创 细说HAL_GPIO_TogglePin()函数写操作BSSR寄存器的原理

第一个参数GPIOx的类型为GPIO_TypeDef,也就是说,GPIOx只能是结构体GPIO_TypeDef的或员,即GPIO端口的寄存器。注意,在函数HAL_GPIO_TogglePin()的参数义中,参数GPIOx的前面有个“*”,表示GPIOx这个变量是一个指针型变量。因此,在访问结构体成员时,就要采用指针的形式。

2024-04-27 15:47:42 1844

原创 C语言中细说用typedef和用struct定义结构体的区别及其在单片机C语言开发中的应用

上面的声明的结构体并没有定义结构体变量,只是建立了一个名为b_type的结构体类型。如果仅仅如此,编译的时候,是不会给这个结构体分配存储单元的。// b为结构体变量名/*!/*!此外,在声明结构体时还可以不指定结构体类型名// 直接定义结构体变量GPIO_InitTypeDefstruct。

2024-04-26 10:32:35 755

原创 C#鼠标拖拽无边框浮动窗体的方法:窗体控制

一般情况下,在标题栏中按住鼠标左键不放即可实现拖动操作。当做浮动窗体时,如果包含窗体边框,那么界面给使用者的感觉将很不友好,因此浮动窗体没有边框,但对于这种没有边框的窗体,该如何进行拖放操作呢?

2024-04-25 17:20:23 781

原创 C# 通过子窗体刷新父窗体:窗体控制

在一些软件,比如,进销存管理系统中添加销售单信息时,每个销售单都可能对应多种商品,而且在向销售单中添加商品时,一般都是在新弹出的窗体中选择商品,这时就涉及通过子窗体刷新父窗体的问题。

2024-04-25 16:34:32 1158

原创 缓解程序员工作压力的十大策略

不断学习新技术,不仅可以提高工作效率,也可以增强自信心,减轻因技术发展快速而产生的焦虑感。最后,每个人遭遇的压力的来源都不同、应对压力的方式也不同,找到适合自己的方法是非常重要的。均衡饮食,多吃水果和蔬菜,减少高糖和高脂肪食品的摄入,有助于维持能量水平和提高情绪。定期进行体育锻炼,如跑步、游泳、健身等,以促进血液循环,减少压力激素的产生。创造一个舒适的工作环境,包括合适的桌椅、良好的照明和减少噪音的措施。与同事、朋友或家人交流你的压力感受,寻求他们的支持和理解。

2024-04-25 09:32:11 203

原创 探索AIGC:人工智能生成内容的现状与未来趋势

AIGC的应用非常广泛,从简单的文本摘要到复杂的虚拟现实场景,都有其身影。AIGC也涉及到虚拟助手的领域,这些虚拟助手能够回答用户的问题、提供个性化建议以及执行各种任务,如苹果的Siri、亚马逊的Alexa和谷歌助手等。AIGC的发展可能导致某些职业的消失,同时也会催生新的职业和工作方式,如与AI协作的新型创意职业。随着算法和算力的进步,AIGC将能够生成更加丰富、更具创造性的内容,甚至可能达到以假乱真的程度。随着AIGC的广泛应用,将需要更多的伦理考量和法规制定,以防止滥用、保护隐私和维护内容的真实性。

2024-04-25 09:31:04 657

原创 C#窗体中动态按钮的设计方法:创建特殊窗体

在窗体界面中,通常以按钮来代替菜单栏的功能,这种形式虽然给用户一种直观、界面风格各异的感觉,但通常按钮都是以静止的形式显示,当光标移到按钮上时,可以使按钮上的图片和文字说明动态化,使用户快捷地找到所选按钮,这时就需要一个动态按钮的窗体界面。

2024-04-24 14:12:57 526

原创 C#设计树形程序界面的方法:创建特殊窗体

以树形来显示程序的菜单,可以更直观、更快捷地对窗体进行操作,而且树型菜单比菜单栏更加美观实用。

2024-04-24 09:12:05 874

原创 C#仿QQ抽屉式窗体的设计方法:创建特殊窗体

QQ软件对于绝大多数的人来说再熟悉不过了,它以使用方便、界面美观及功能完善而著称。

2024-04-23 15:12:44 675

原创 C#带引导窗体的窗体设计方法:创建特殊窗体

很多时候。我们的窗体设计需要一个引导窗体。当打开一个项目的窗体时,默认的是先打开一个欢迎或介绍项目信息的引导窗体,几秒钟后再打开项目的主窗体。这几秒时间最重要的意义是等待主窗体加载程序完毕。

2024-04-23 10:58:59 526

原创 高性能、灵活的DPRAM解决方案

DPRAM是一种特殊的RAM,它有两个独立的接口,可以同时从两个不同的地址空间进行读写操作。这使得DPRAM非常适合于需要高速数据传输和处理的应用场景。在两个微控制单元(MCU)之间共享数据存储器(DPRAM),可以使用一个简单的例子,其中两个MCU将通过串行通信进行连接,并使用DPRAM来交换数据。首先,需要了解DPRAM是一种可以被多个设备访问的RAM类型,通常具有并行接口。由于DPRAM不常见于现代微控制器中,常规设计先假设它是一个外部设备,可以通过总线接口(如SPI、I2C或并行接口)访问。

2024-04-22 21:49:54 827 4

原创 双核MCU中的数据共享与DPRAM的工作机制对比分析

然而,DPRAM通常是在硬件层面设计来支持这种并发读写的,而双核MCU的缓存则依赖于更复杂的缓存一致性协议和操作系统级别的同步机制。为了确保数据的一致性,一个核心在修改了共享数据后,可能需要使用缓存同步操作来确保另一个核心可以看到最新的数据。为了保证缓存的一致性,每当一个核心修改了缓存中的数据,另一个核心在接下来访问同一缓存行时会得到最新的数据。此外,L2缓存的使用通常还会涉及更复杂的数据共享和同步机制,比如锁和信号量,这些都是在操作系统层面上实现的。

2024-04-22 11:16:04 871

C# 开发实例大全(基础卷)例题前4章VS2022版本

C# 开发实例大全(基础卷)例题前4章VS2022版本

2024-02-10

《C++从入门到精通》第5版VS2022的例题

《C++从入门到精通》第5版VS2022的例题,明日科技,清华大学出版社。 明日科技太懒了,配套例题仍然是VC++6.0的,例题的错误,几十年了,出版到第5版了,也没安排人修改。 本资料,书中例题全部在VS2022上运行过,修改了原题的错误、过气的函数。并增加了一些自己学习的见解。

2023-05-12

《C语言从入门到精通》VS2022的例题

《C语言从入门到精通》发行到第五版了,可是明日科技很懒惰,书中的例题仍然还在用VC++6.0.如果工程师照着书学习操作VC++6.0即使学会了书,还能找到工作吗和学以致用吗?所以,我就辛苦一下,把书中的例子在VS2022环境下都运行了一遍。修改了很多被VS2022抛弃的函数还有原书例题中的错误。

2023-04-12

profinet ASIC ERTEC200_Boot_Manual_V110

名称:ERTEC200_Boot_Manual_V110 用途:profinet ASIC ERTEC200 评价:这个资源十分稀少,分享给大家;

2022-05-17

Profinet ASIC ERTEC200芯片“ERTEC200_Datasheet_V112”

名称:ERTEC200_Datasheet_V112 用途:Profinet ASIC ERTEC200芯片; 评价:这个资源很稀少,几乎下不到了,今天上传到网上,分享给大伙。

2022-05-17

西门子PLC S7-226固件程序,V2.01S7-226_CN_2.01_dump_24c512

西门子PLC S7-226固件程序,V2.01; "S7-226_CN_2.01_dump_24c512"

2022-05-12

实测好用的两个Profilic PL2303HXA USB-to-Serial Comm Port for WIN10的驱动

经win10旗舰版21H2实测好用的两个profilic PL2303HXA USB-to-Serial Comm Port 驱动.

2022-04-16

SystemVerilog.std.1800-2012

SystemVerilog.std.1800-2012

2014-02-15

SystemC std 1666-2011

IEEE SystemC.std.1666-2011.pdf

2014-02-15

基于VB的分布式监控系统通信设计

基于VB的分布式监控系统通信设计摘 要:本文介绍了利用VB的多种通信手段实现分布式监控系统的多种通信功能,对每一种通信手段给出其原理和应用实例。

2010-04-28

在VB下PC机与MCS-51单片机的串行通信

在VB下PC机与MCS-51单片机的串行通信

2010-04-28

空空如也

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

TA关注的人

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