e2studio开发RA2E1(9)----定时器GPT配置输入捕获
e2studio开发RA2E1.9--定时器GPT配置输入捕获
- 概述
- 视频教学
- 样品申请
- 硬件准备
- 参考程序
- 源码下载
- 选择计时器
- 时钟源
- UART配置
- UART属性配置
- 设置e2studio堆栈
- e2studio的重定向printf设置
- R_SCI_UART_Open()函数原型
- 回调函数user_uart_callback ()
- printf输出重定向到串口
- 定时器输入捕获配置
- 占空比与频率计算
- 回调函数gpt5_callback
- 主程序
- 演示
概述
本文将探讨如何在 Renesas RA 系列微控制器上使用 GPT(通用定时器)模块来配置输入捕获功能。输入捕获是定时器的一项重要功能,它允许我们捕获外部信号(如脉冲或波形)的时间戳,广泛应用于频率计数、脉冲宽度测量以及其他需要精确时间记录的应用。
最近在瑞萨RA的课程,需要样片的可以加qun申请:925643491。
视频教学
https://www.bilibili.com/video/BV1QrP1ejEAZ/
e2studio开发RA2E1(9)----定时器GPT配置输入捕获
样品申请
https://www.wjx.top/vm/rCrkUrz.aspx
硬件准备
首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。
主控为R7FA2E1A72DFL#AA0
参考程序
https://github.com/CoreMaker-lab/RA2E1
https://gitee.com/CoreMaker/RA2E1
源码下载
选择计时器
RA MCU 有两个定时器外设:通用 PWM 定时器 (GPT) 和异步通用定时器 (AGT)。
时钟源
GPT 使用 PCLKD(外设时钟D) 作为主时钟源。该时钟可以通过 可配置的分频器 进行调整,最大分频因子为 1024。
选择 XTAL 12MHz 作为时钟源(Clock Src: XTAL)。PCLKD 时钟的分频器设置为 Div /1,意味着 PCLKD 直接运行在 12MHz。
UART配置
点击Stacks->New Stack->Connectivity -> UART(r_sci_uart)。
UART属性配置
设置e2studio堆栈
printf函数通常需要设置堆栈大小。这是因为printf函数在运行时需要使用栈空间来存储临时变量和函数调用信息。如果堆栈大小不足,可能会导致程序崩溃或不可预期的行为。
printf函数使用了可变参数列表,它会在调用时使用栈来存储参数,在函数调用结束时再清除参数,这需要足够的栈空间。另外printf也会使用一些临时变量,如果栈空间不足,会导致程序崩溃。
因此,为了避免这类问题,应该根据程序的需求来合理设置堆栈大小。
e2studio的重定向printf设置
在嵌入式系统的开发中,尤其是在使用GNU编译器集合(GCC)时,–specs 参数用于指定链接时使用的系统规格(specs)文件。这些规格文件控制了编译器和链接器的行为,尤其是关于系统库和启动代码的链接。–specs=rdimon.specs 和 --specs=nosys.specs 是两种常见的规格文件,它们用于不同的场景。
–specs=rdimon.specs
用途: 这个选项用于链接“Redlib”库,这是为裸机(bare-metal)和半主机(semihosting)环境设计的C库的一个变体。半主机环境是一种特殊的运行模式,允许嵌入式程序通过宿主机(如开发PC)的调试器进行输入输出操作。
应用场景: 当你需要在没有完整操作系统的环境中运行程序,但同时需要使用调试器来处理输入输出(例如打印到宿主机的终端),这个选项非常有用。
特点: 它提供了一些基本的系统调用,通过调试接口与宿主机通信。
–specs=nosys.specs
用途: 这个选项链接了一个非常基本的系统库,这个库不提供任何系统服务的实现。
应用场景: 适用于完全的裸机程序,其中程序不执行任何操作系统调用,比如不进行文件操作或者系统级输入输出。
特点: 这是一个更“裸”的环境,没有任何操作系统支持。使用这个规格文件,程序不期望有操作系统层面的任何支持。
如果你的程序需要与宿主机进行交互(如在开发期间的调试),并且通过调试器进行基本的输入输出操作,则使用 --specs=rdimon.specs。
如果你的程序是完全独立的,不需要任何形式的操作系统服务,包括不进行任何系统级的输入输出,则使用 --specs=nosys.specs。
R_SCI_UART_Open()函数原型
故可以用 R_SCI_UART_Open()函数进行配置,开启和初始化UART。
/* Open the transfer instance with initial configuration. */err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);assert(FSP_SUCCESS == err);
回调函数user_uart_callback ()
当数据发送的时候,可以查看UART_EVENT_TX_COMPLETE来判断是否发送完毕。
可以检查检查 “p_args” 结构体中的 “event” 字段的值是否等于 “UART_EVENT_TX_COMPLETE”。如果条件为真,那么 if 语句后面的代码块将会执行。
fsp_err_t err = FSP_SUCCESS;
volatile bool uart_send_complete_flag = false;
void user_uart_callback (uart_callback_args_t * p_args)
{if(p_args->event == UART_EVENT_TX_COMPLETE){uart_send_complete_flag = true;}
}
printf输出重定向到串口
打印最常用的方法是printf,所以要解决的问题是将printf的输出重定向到串口,然后通过串口将数据发送出去。
注意一定要加上头文件#include <stdio.h>
#ifdef __GNUC__ //串口重定向#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endifPUTCHAR_PROTOTYPE
{err = R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);if(FSP_SUCCESS != err) __BKPT();while(uart_send_complete_flag == false){}uart_send_complete_flag = false;return ch;
}int _write(int fd,char *pBuffer,int size)
{for(int i=0;i<size;i++){__io_putchar(*pBuffer++);}return size;
}
定时器输入捕获配置
操作 “New Stack > Timers >Timer, General PWM (r_gpt)” 在项目中添加GPT定时器。
这里设置P102进行捕获PWM。
● Pin Output Support:设为 Enabled,允许 PWM 信号输出到外部引脚。
● Name:设置为 g_timer5,这是模块的唯一标识符,用于代码中引用此定时器实例。
● Channel:设定为 5,表示该定时器使用通道 5 进行计数和控制。
● Mode:设为 Periodic,表示该定时器工作在周期模式,将在设定周期内重复运行。
● Period:周期值设置为 0x10000,表示定时器的周期为 65536 个时钟周期。根据时钟源频率的不同,实际的周期时间可以转换为相应的实际时间。
● Period Unit:单位选择为 Raw Counts,表示周期单位为原始计数,即计数器溢出的周期。
● Capture B Source:设为 GPT5 CAPTURE COMPARE B,表示捕获源为 GPT5 定时器的比较匹配B事件,用于捕获输入信号的时间戳。
● GTIOCB Rising Edge While GTIOCA Low:表示当 GTIOCA 为低电平时,捕获 GTIOCB 引脚的上升沿事件。
● GTIOCB Rising Edge While GTIOCA High:表示当 GTIOCA 为高电平时,捕获 GTIOCB 引脚的上升沿事件。
● GTIOCB Falling Edge While GTIOCA Low:表示当 GTIOCA 为低电平时,捕获 GTIOCB 引脚的下降沿事件。
● GTIOCB Falling Edge While GTIOCA High:表示当 GTIOCA 为高电平时,捕获 GTIOCB 引脚的下降沿事件。
● Callback:设置为 gpt5_callback,指定了当定时器触发中断时,调用的回调函数。在此情况下,回调函数 gpt5_callback 将在捕获事件发生时执行。
● Capture/Compare match B Interrupt Priority:设置为 Priority 2,表示启用比较匹配 B 中断,且其优先级为 2。
● GTIOC5B:指定 GTIOC5B 引脚为另一个定时器输入/输出引脚,连接到外部引脚 P102。
占空比与频率计算
在波形中:
● up1_capture_time 是第一次上升沿的捕获时间。
● down_capture_time 是下降沿的捕获时间。
● up2_capture_time 是第二次上升沿的捕获时间。
脉冲周期(pulse_period)完整周期为上升沿(up1_capture_time)到第二次上升沿(up2_capture_time)之间的时间差,也就是脉冲的完整周期。
● 频率计算:我在频率计算中使用了 pulse_period,确保了计算是在第一次和第二次上升沿之间。
● 占空比计算:计算占空比时,使用了从 down_capture_time 到第二次上升沿 up2_capture_time 之间的时间差来计算脉冲宽度。
回调函数gpt5_callback
- 上升沿捕获:
○ 在上升沿捕获时,更新第一次和第二次上升沿的捕获时间。
○ 计算 脉冲周期:即第二次上升沿与第一次上升沿之间的时间差。
○ 计算 频率:通过时钟频率除以脉冲周期。
○ 计算 占空比:通过计算从上升沿到下降沿的脉冲宽度,然后用脉冲宽度除以脉冲周期来计算占空比。 - 下降沿捕获:
○ 在下降沿捕获时,更新下降沿的捕获时间。
需要注意的是,代码中计算占空比时,用 (100.0f - (pulse_width*100 / (double)pulse_period)) 来计算正占空比。
volatile uint32_t up1_capture_time = 0; // 用于存储第一次上升沿捕获的时间
volatile uint32_t down_capture_time = 0; // 用于存储第一次上升沿捕获的时间
volatile uint32_t up2_capture_time = 0; // 用于存储第二次上升沿捕获的时间
volatile uint32_t pulse_width = 0; // 用于存储脉冲宽度
volatile uint32_t pulse_period = 0; // 用于存储脉冲周期
volatile double duty_cycle = 0; // 用于存储正占空比
volatile double frequency = 0; // 用于存储频率void gpt5_callback(timer_callback_args_t *p_args)
{/* TODO: add your own code here */if ((TIMER_EVENT_CAPTURE_B == p_args->event)) // 捕获事件{bsp_io_level_t p_port_value_port_102;// 读取端口电平状态,如果是低电平则发生的是下降沿,高电平则是上升沿R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_02, &p_port_value_port_102);// 获取当前定时器的时钟频率和周期timer_info_t info;(void) R_GPT_InfoGet(&g_timer5_ctrl, &info);uint64_t clock_frequency = info.clock_frequency; // 定时器时钟频率uint32_t current_period_counts = info.period_counts; // 定时器周期uint32_t current_time = p_args->capture; // 获取当前捕获时间(计数值)if (p_port_value_port_102 == BSP_IO_LEVEL_HIGH) // 上升沿{// 记录第一次和第二次上升沿的时间戳up1_capture_time=up2_capture_time;up2_capture_time=current_time;// 计算脉冲周期:从第一次到第二次上升沿的时间差if(up2_capture_time>=up1_capture_time)pulse_period = (up2_capture_time-up1_capture_time);elsepulse_period = (current_period_counts -up1_capture_time) + up2_capture_time;// 计算频率:频率 = 时钟频率 / 脉冲周期frequency =(double) (clock_frequency/pulse_period);// 计算脉冲宽度:从下降沿到第二次上升沿的时间差if(up2_capture_time>=down_capture_time)pulse_width=up2_capture_time-down_capture_time;elsepulse_width=(current_period_counts -down_capture_time) + up2_capture_time;// 计算占空比:占空比 = 脉冲宽度 / 脉冲周期duty_cycle = 100.0f-(pulse_width*100 / (double)pulse_period);}else // 下降沿{// 更新下降沿的捕获时间down_capture_time=current_time;}}
}
主程序
void hal_entry(void)
{/* TODO: add your own code here */fsp_err_t err = FSP_SUCCESS;/* Initializes the module. */err = R_GPT_Open(&g_timer8_ctrl, &g_timer8_cfg);/* Handle any errors. This function should be defined by the user. */assert(FSP_SUCCESS == err);/* Start the timer. */(void) R_GPT_Start(&g_timer8_ctrl);R_BSP_SoftwareDelay (20, BSP_DELAY_UNITS_MILLISECONDS);err = R_GPT_PeriodSet(&g_timer8_ctrl, 12000);//频率assert(FSP_SUCCESS == err);R_BSP_SoftwareDelay (20, BSP_DELAY_UNITS_MILLISECONDS);//不加延时可能会设置不成功err = R_GPT_DutyCycleSet(&g_timer8_ctrl, 3000, GPT_IO_PIN_GTIOCA);// 设置占空比assert(FSP_SUCCESS == err);err = R_GPT_DutyCycleSet(&g_timer8_ctrl, 9000, GPT_IO_PIN_GTIOCB);// 设置占空比assert(FSP_SUCCESS == err);R_BSP_SoftwareDelay (20, BSP_DELAY_UNITS_MILLISECONDS);// err = R_GPT_Close(&g_timer8_ctrl);
// assert(FSP_SUCCESS == err);
// R_BSP_SoftwareDelay (20, BSP_DELAY_UNITS_MILLISECONDS);/* Open the transfer instance with initial configuration. */err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);assert(FSP_SUCCESS == err);printf("hello\n");/* Initializes the module. */err = R_GPT_Open(&g_timer5_ctrl, &g_timer5_cfg);/* Handle any errors. This function should be defined by the user. */assert(FSP_SUCCESS == err);/* Start the timer. */(void) R_GPT_Start(&g_timer5_ctrl);(void) R_GPT_Enable(&g_timer5_ctrl);R_BSP_SoftwareDelay (20, BSP_DELAY_UNITS_MILLISECONDS);while(1){printf("frequency=%.2f,duty cycle=%.2f\n",frequency,duty_cycle);duty_cycle = 0; // 重置占空比frequency = 0; // 重置频率R_BSP_SoftwareDelay (200, BSP_DELAY_UNITS_MILLISECONDS);}#if BSP_TZ_SECURE_BUILD/* Enter non-secure code */R_BSP_NonSecureEnter();
#endif
}
演示
分别接入P101和P100。
相关文章:

e2studio开发RA2E1(9)----定时器GPT配置输入捕获
e2studio开发RA2E1.9--定时器GPT配置输入捕获 概述视频教学样品申请硬件准备参考程序源码下载选择计时器时钟源UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user_uart_callback ()printf输出重定向到串口定时器输入捕获配…...

25/2/7 <机器人基础>雅可比矩阵计算 雅可比伪逆
雅可比矩阵计算 雅可比矩阵的定义 假设我们有一个简单的两个关节的平面机器人臂,其末端执行器的位置可以表示为: 其中: L1 和 L2 是机器人臂的长度。θ1 和 θ2是关节的角度。 计算雅可比矩阵 雅可比矩阵 JJ 的定义是将关节速度与末…...

网络爬虫js逆向之异步栈跟栈案例
【注意!!!】 前言: 1. 本章主要讲解js逆向之异步栈跟栈的知识(通过单步执行调试) 2. 使用关键字搜定位加密入口 3. 本专栏通过多篇文章【文字案例】的形式系统化进行描述 4. 本文章全文进行了脱敏处理 5. 详…...

使用Ollama本地部署deepseek
1、下载安装Ollama 前往下载页面 https://ollama.com/download下载好安装包,如同安装软件一样,直接安装即可 win中默认为C盘,如果需要修改到其他盘,查找具体教程 运行list命令,检查是否安装成功 2、修改模型下载的…...
Rust错误处理:从灭火器到核按钮的生存指南
开篇:错误处理的生存哲学 在Rust的平行宇宙里,错误分为两种人格: panic! → 核按钮💣(不可恢复,全系统警报)Result → 灭火器🧯(可控制,局部处理࿰…...

Golang:Go 1.23 版本新特性介绍
流行的编程语言Go已经发布了1.23版本,带来了许多改进、优化和新特性。在Go 1.22发布六个月后,这次更新增强了工具链、运行时和库,同时保持了向后兼容性。 Go 1.23 的新增特性主要包括语言特性、工具链改进、标准库更新等方面,以下…...

电脑运行黑屏是什么原因?原因及解决方法
电脑运行黑屏是指电脑在正常开机或使用过程中,突然出现屏幕变黑,无法显示任何内容的现象。这种现象可能会给用户带来很多不便,甚至造成数据丢失或硬件损坏。那么,电脑运行黑屏是什么原因呢?下面我们将分析几种可能的原…...

redis之AOF持久化过程
流程图 在redis.conf文件中配置appendonly为yes则开启aof持久化机制 #开启aof持久化,默认关闭为no appendonly no也可以在命令行开启 aof刷盘策略 #每个写操作都会同步刷盘。 appendfsync always #执行命令后先放入aof缓冲区,每秒钟将缓冲区数据刷盘…...

Elasticsearch:向量搜索的快速介绍
作者:来自 Elastic Valentin Crettaz 本文是三篇系列文章中的第一篇,将深入探讨向量搜索(也称为语义搜索)的复杂性,以及它在 Elasticsearch 中的实现方式。 本文是三篇系列文章中的第一篇,将深入探讨向量搜…...
Docker在安装时遇到的问题(第一部分)
一、在用docker-config-manager安装yum源时出现错误 [rootlocalhost ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 已加载插件:fastestmirror, langpacks adding repo from: https://download.docker.com/linux/ce…...
使用 OpenGL ES 在 iOS 上渲染一个四边形:从基础到实现
使用 OpenGL ES 在 iOS 上渲染一个四边形:从基础到实现 在 iOS 开发中,OpenGL ES 是一个强大的工具,用于实现高性能的 2D 和 3D 图形渲染。本文将详细分析一段完整的代码,展示如何使用 OpenGL ES 在 iOS 上渲染一个简单的四边形。我们将从代码的结构、关键模块、着色器的实…...
Spring Boot 2 快速教程:WebFlux处理流程(五)
WebFlux请求处理流程 下面是spring mvc的请求处理流程 具体步骤: 第一步:发起请求到前端控制器(DispatcherServlet) 第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找) 匹配条件包括…...
Vue 鼠标事件合集,关于鼠标右键的处理方法(改写鼠标右键方法、自定义鼠标右键)
鼠标事件使用 mousedown"canvasDown($event)"按下事件合集 click 点击某个对象时触发 mousedown 鼠标按钮被按下时触发 mouseup 鼠标按钮被松开时触发 mouseleave 当鼠标指针移出元素时触发 dblclick 双击时触发 mousemove 鼠标移动时触发,…...
两种交换排序算法--冒泡,快速
目录 1.冒泡排序原理 2.快速排序原理 3.冒泡代码实现 4.快速排序代码实现 1.冒泡排序原理 冒泡排序(Bubble Sort)是一种简单的排序算法,基本思想是通过反复交换相邻的元素,直到整个序列有序。它的名字来源于较大的元素像气泡…...

语音交友app系统源码功能及技术研发流程剖析
语音交友App的核心功能包括语音聊天、语音房间、社交互动等,开发流程涵盖需求分析、技术选型、前后端开发、实时通信集成、测试优化、部署上线及运营维护。 一、语音交友App的大概功能 1. 语音聊天 一对一聊天:用户可与好友进行私密语音通话。 群组语音…...
零基础Vue入门7——状态管理Pinia
本节重点: pinia是什么pinia怎么用 pinia是什么 vue中组件间的数据传递: app.config.globalProperties:能够被应用内所有组件实例访问到的全局属性的对象props:父传子用provide:父传后代用 想象下有咩有哪些数据存储…...

Bash (Bourne-Again Shell)、Zsh (Z Shell)
文章目录 1. 历史背景2. 主要区别3. 功能对比自动补全插件和主题路径扩展提示符定制 4. 性能5. 使用场景6. 如何切换 Shell7. 总结 以下是 Bash 和 Zsh 之间的主要区别,列成表格方便对比: 特性BashZsh默认Shell大多数Linux发行版默认ShellmacOS默认She…...

Android studio 创建aar包给Unity使用
1、aar 是什么? 和 Jar有什么区别 aar 和 jar包 都是压缩包,可以使用压缩软件打开 jar包 用于封装 Java 类及其相关资源 aar 文件是专门为 Android 平台设计的 ,可以包含Android的专有内容,比如AndroidManifest.xml 文件 &#…...

DeepSeek R1 简单指南:架构、训练、本地部署和硬件要求
DeepSeek 的 LLM 推理新方法 DeepSeek 推出了一种创新方法,通过强化学习 (RL) 来提高大型语言模型 (LLM) 的推理能力,其最新论文 DeepSeek-R1 对此进行了详细介绍。这项研究代表了我们如何通过纯强化学习来增强 LLM 解决复杂问题的能力,而无…...

图论常见算法
图论常见算法 算法prim算法Dijkstra算法 用途最小生成树(MST):最短路径:拓扑排序:关键路径: 算法用途适用条件时间复杂度Kruskal最小生成树无向图(稀疏图)O(E log E)Prim最小生成树无…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...