在上一篇输入捕获中断的使用-按键捕获的基础上
最近项目上有个传感器的是输出pwm信号的,考虑了两种方法,1:两个输入捕获中断,一个捕捉下降沿一个捕捉上升沿,然后计时,2;一个输入捕获中断,里面判断上升沿还是下降沿,但由于芯片外部资源问题,使用第二种方法,所以在开发板上实现一下
添加一个定时器(这个无所谓,只是用来计时的随便一个都行)
定时器配置(直接默认就行,如果需要计算高电平时间等,就配置一下)
将上一试验的外部中断源重新配下双边沿检测
代码实现
#include "hal_data.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "common_data.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
int cmd_get_char(char *ch);
void LedBlink(uint16_t call_period);
void myprintf(const void *format, ...);
char cmd;
volatile bool switch1 = false;
#define DELAY_TIME (100)
volatile uint32_t high_counts = 0;
volatile uint32_t low_counts = 0;
timer_status_t mytime;
/*******************************************************************************************************************/
/**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
/* TODO: add your own code here */
fsp_err_t err = FSP_SUCCESS;
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
/* Open the transfer instance with initial configuration. */
err = R_IOPORT_Open(&g_ioport_ctrl, &g_bsp_pin_cfg);
err = R_SCI_UART_Open(&g_uart0_ctrl, &g_uart0_cfg);
err = R_ICU_ExternalIrqOpen(&g_external_irq0_ctrl, &g_external_irq0_cfg);
err = R_ICU_ExternalIrqEnable(&g_external_irq0_ctrl);
err = R_GPT_Open(&g_timer0_ctrl, &g_timer0_cfg);
err = R_GPT_Start(&g_timer0_ctrl);
//err = R_ICU_ExternalIrqClose(&g_external_irq0_ctrl);
assert(FSP_SUCCESS == err);
uint32_t duty = 0;
for (;;)
{
duty = high_counts*100/(high_counts + low_counts);
myprintf("high:%d,low:%d,duty:%d\r\n",high_counts,low_counts,duty);
R_BSP_SoftwareDelay(DELAY_TIME, BSP_DELAY_UNITS_MILLISECONDS);
}
}
/**
* @brief 灯闪烁
*
* @param call_period 调用周期
*/
void LedBlink(uint16_t call_period)
{
#define LEN_OPEN_TIME (1000)
#define LEN_CLOSE_TIME (2000)
static uint16_t sys_time = 0;
sys_time += call_period;
if (sys_time >= LEN_CLOSE_TIME)
{
sys_time = 0;
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_07, BSP_IO_LEVEL_HIGH);
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_08, BSP_IO_LEVEL_LOW);
}
else if (sys_time >= LEN_OPEN_TIME)
{
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_07, BSP_IO_LEVEL_LOW);
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_08, BSP_IO_LEVEL_HIGH);
}
}
/*******************************************************************************************************************/
/**
* This function is called at various points during the startup process. This implementation uses the event that is
* called right before main() to set up the pins.
*
* @param[in] event Where at in the start up process the code is currently at
**********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
if (BSP_WARM_START_RESET == event)
{
#if BSP_FEATURE_FLASH_LP_VERSION != 0
/* Enable reading from data flash. */
R_FACI_LP->DFLCTL = 1U;
/* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
* C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
}
if (BSP_WARM_START_POST_C == event)
{
/* C runtime environment and system clocks are setup. */
/* Configure pins. */
R_IOPORT_Open(&g_ioport_ctrl, g_ioport.p_cfg);
}
}
#if BSP_TZ_SECURE_BUILD
FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable();
/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable()
{
}
FSP_CPP_FOOTER
#endif
#define RING_LEN (255)
char rx_buff[RING_LEN] = {0};
volatile int twrite = 0;
int tread = 0;
/**
* @brief 串口数据回调函数
*
* @param p_args
*/
void xcmd_callback(uart_callback_args_t *p_args)
{
/* TODO: add your own code here */
if (p_args->event == UART_EVENT_RX_CHAR)
{
rx_buff[twrite] = (char)(p_args->data);
twrite++;
if (twrite >= RING_LEN)
twrite = 0;
}
}
/**
* @brief 从循环buf中获取一个字节
*
* @param ch 输出的字节
* @return int 0:未读到数据,1:读到数据
*/
int cmd_get_char(char *ch)
{
if (tread != twrite)
{
*ch = rx_buff[tread];
tread++;
if(tread >= RING_LEN)
tread = 0;
return 1;
}
return 0;
}
#define CMD_LEN_MAX (1024)
char buff[CMD_LEN_MAX];
/**
* @brief 打印数据
*
* @param format 格式
* @param ...
*/
void myprintf(const void *format, ...)
{
int len = 0;
va_list list;
va_start(list, format);
len = vsnprintf(buff, CMD_LEN_MAX, format, list);
va_end(list);
if (len > 0)
{
R_SCI_UART_Write(&g_uart0_ctrl, (const uint8_t* const) buff, (uint32_t)len);
}
}
bsp_io_level_t a;
/**
* @brief 回调函数
*
* @param p_args
*/
void switchCallBack(external_irq_callback_args_t *p_args)
{
if(1 == p_args->channel) // 中断通道为1
{
R_IOPORT_PinEventInputRead(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_05,&a);
R_GPT_StatusGet(&g_timer0_ctrl, &mytime);
R_GPT_Reset(&g_timer0_ctrl);
if(a)
{
low_counts = mytime.counter;
}
else
{
high_counts = mytime.counter;
}
}
}