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

  1. 上升沿捕获:
    ○ 在上升沿捕获时,更新第一次和第二次上升沿的捕获时间。
    ○ 计算 脉冲周期:即第二次上升沿与第一次上升沿之间的时间差。
    ○ 计算 频率:通过时钟频率除以脉冲周期。
    ○ 计算 占空比:通过计算从上升沿到下降沿的脉冲宽度,然后用脉冲宽度除以脉冲周期来计算占空比。
  2. 下降沿捕获:
    ○ 在下降沿捕获时,更新下降沿的捕获时间。

需要注意的是,代码中计算占空比时,用 (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。

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/14609.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM虚拟机以及跨平台原理

相信大家已经了解到Java具有跨平台的特性&#xff0c;即“一次编译&#xff0c;到处运行”&#xff0c;例如在Windows下编写的程序&#xff0c;无需任何修改就可以在Linux下运行&#xff0c;这是C和C很难做到的。 那么&#xff0c;跨平台是怎样实现的呢&#xff1f;这就要谈及…

激活函数篇 02 —— 双曲正切函数tanh

本篇文章收录于专栏【机器学习】 以下是激活函数系列的相关的所有内容: 一文搞懂激活函数在神经网络中的关键作用 逻辑回归&#xff1a;Sigmoid函数在分类问题中的应用 tanh ⁡ ( x ) e x − e − x e x e − x \tanh(x)\frac{e^x - e^{-x}}{e^x e^{-x}} tanh(x)exe−xex…

redis高级数据结构布隆过滤器

文章目录 背景什么是布隆过滤器Redis 中的布隆过滤器布隆过滤器使用注意事项实现原理空间占用估计 背景 我们在使用新闻客户端看新闻时&#xff0c;它会给我们不停地推荐新的内容&#xff0c;它每次推荐时要去重&#xff0c;去掉那些已经看过的内容。问题来了&#xff0c;新闻…

存储异常导致的Oracle重大生产故障

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验 Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯…

在 Navicat 17 中扩展 PostgreSQL 数据类型 | 创建自定义域

定义域 以适当的格式存储数据可以确保数据完整性&#xff0c;防止错误&#xff0c;优化性能&#xff0c;并通过实施验证规则和支持高效数据管理来维护系统间的一致性。基于这些原因&#xff0c;顶级关系数据库&#xff08;如PostgreSQL&#xff09;提供了多种数据类型。此外&a…

计算机视觉-拟合

一、拟合 拟合的作用主要是给物体有一个更好的描述 根据任务选择对应的方法&#xff08;最小二乘&#xff0c;全最小二乘&#xff0c;鲁棒最小二乘&#xff0c;RANSAC&#xff09; 边缘提取只能告诉边&#xff0c;但是给不出来数学描述&#xff08;应该告诉这个点线是谁的&a…

oracle基础语法

oracle基础语法 1、增删改查1.1查询语句1.2 修改语句1.3 删除表1.4 删除数据1.5 增加数据1.6 创建视图1.7 添加视图字段注释 1、增删改查 oracle与sql server语法上大致相同&#xff0c;但有些细微的不同&#xff0c;以下是我个人记录工作中常用到的一些语法句。 1.1查询语句…

CodeGPT + IDEA + DeepSeek,在IDEA中引入DeepSeek实现AI智能开发

CodeGPT IDEA DeepSeek&#xff0c;在IDEA中引入DeepSeek 版本说明 建议和我使用相同版本&#xff0c;实测2022版IDEA无法获取到CodeGPT最新版插件。&#xff08;在IDEA自带插件市场中搜不到&#xff0c;可以去官网搜索最新版本&#xff09; ToolsVersionIntelliJ IDEA202…

星网锐捷 视频话机设备pwdsetting管理密码信息泄漏

星网锐捷 视频话机设备pwdsetting管理密码信息泄漏 漏洞描述 星网锐捷视频话机设备 泄露管理员密码&#xff0c;攻击者可利用密码直接进入后台配置页面&#xff0c;执行恶意操作&#xff0c;进行一步攻击。 威胁等级: 高危 漏洞分类: 信息泄露 涉及厂商及产品&#xff1a;…

网络安全 | 保护智能家居和企业IoT设备的安全策略

网络安全 | 保护智能家居和企业IoT设备的安全策略 一、前言二、智能家居和企业 IoT 设备面临的安全威胁2.1 设备自身安全缺陷2.2 网络通信安全隐患2.3 数据隐私风险2.4 恶意软件和攻击手段 三、保护智能家居和企业 IoT 设备的安全策略3.1 设备安全设计与制造环节的考量3.2 网络…

38、【OS】【Nuttx】OSTest分析(3):参数传递

背景 接之前 blog 36、【OS】【Nuttx】OSTest分析&#xff08;2&#xff09;&#xff1a;环境变量测试 37、【OS】【Nuttx】OSTest分析&#xff08;2&#xff09;&#xff1a;任务创建 分析完环境变量测试&#xff0c;和任务创建的一些关键要素&#xff0c;OSTest 进入下一阶段…

储能系统-系统架构

已更新系列文章包括104、61850、modbus 、单片机等&#xff0c;欢迎关注 IEC61850实现方案和测试-1-CSDN博客 快速了解104协议-CSDN博客 104调试工具2_104协议调试工具-CSDN博客 1 电池储能系统&#xff08;BESS&#xff09; 架构 电池储能系统主要包括、电池、pcs、本地控制…

Listener监听器和Filter过滤器

一.监听器 1.是javaweb的三大组件之一,分别是Servlet程序,Listener监听器,Filter过滤器 2.Listener是JvaEE的规范,就是接口,监听器的作用就是监听某种变化(一般是对象创建/销毁,属性变化),触发对应方法完成相应的任务 3.ServletContextListener:/*当一个类实现了ServletContex…

Go 中的 7 个常见接口错误

Go 仍然是一门新语言,如果你正在使用它,它很可能不是你的第一门编程语言。 不同的语言,既为你带来了经验,也带来了偏见。你用以前的任何语言做的事情,在 Go 中用相同的方法可能不是一个好主意。 学习 Go 不仅仅是学习一种新的语法。这也是学习一种新的思维方式来思考你的…

【AI实践】Cursor上手-跑通Hello World和时间管理功能

背景 学习目的&#xff1a;熟悉Cursor使用环境&#xff0c;跑通基本开发链路。 本人背景&#xff1a;安卓开发不熟悉&#xff0c;了解科技软硬件常识 实践 基础操作 1&#xff0c;下载安装安卓Android Studio 创建一个empty project 工程&#xff0c;名称为helloworld 2&am…

存储系统、网盘系统的访问留痕

一、适用场景 1、需要了解是否存在非法访问存储系统或网盘系统&#xff1a;各企业或单位为方便远程办公或远程管理&#xff0c;若自建&#xff08;保护隐私数据或敏感资料&#xff09;了存储系统或网盘系统&#xff0c;那么到底有哪些ip地址或用户从远程公网访问存储系统或网盘…

求助DeepSeek帮我开发一个直线审批流程设计页面Vue2.0

之前使用文心一言协助开发过类似的页面&#xff0c;需求方认为某些业务表单需要添加审批流程&#xff0c;可以人为设置审批步骤&#xff0c;由于需求很模糊而且人/天有限&#xff0c;当时的提问很混乱&#xff0c;内容如下&#xff1a; 我的vue2.0系统中需要审批流程设计页面&a…

初级数据结构:栈和队列

目录 一、栈 (一)、栈的定义 (二)、栈的功能 (三)、栈的实现 1.栈的初始化 2.动态扩容 3.压栈操作 4.出栈操作 5.获取栈顶元素 6.获取栈顶元素的有效个数 7.检查栈是否为空 8.栈的销毁 9.完整代码 二、队列 (一)、队列的定义 (二)、队列的功能 (三&#xff09…

LLM:DeepSeek 系列(二)

原文链接 3、DeepSeek-V2 DeepSeek-V2 发布于 2024 年 5 月&#xff0c;为多领域专家&#xff08;MoE&#xff09;语言模型&#xff0c;包含总共 2360 亿个参数&#xff0c;其中每个词元激活 210 亿个参数&#xff0c;并支持 12.8 万个词元的上下文长度。DeepSeek-V2 采用包括…

【学术投稿】第五届计算机网络安全与软件工程(CNSSE 2025)

重要信息 官网&#xff1a;www.cnsse.org 时间&#xff1a;2025年2月21-23日 地点&#xff1a;中国-青岛 简介 第五届计算机网络安全与软件工程&#xff08;CNSSE 2025&#xff09;将于2025年2月21-23日在中国-青岛举行。CNSSE 2025专注于计算机网络安全、软件工程、信号处…