您现在的位置是:首页 >技术杂谈 >【致敬未来的攻城狮计划】— 连续打卡第十八天:FSP固件库开发GPT — PWM输出波形 — LED呼吸灯网站首页技术杂谈

【致敬未来的攻城狮计划】— 连续打卡第十八天:FSP固件库开发GPT — PWM输出波形 — LED呼吸灯

嵌入式up 2023-07-02 00:00:03
简介【致敬未来的攻城狮计划】— 连续打卡第十八天:FSP固件库开发GPT — PWM输出波形 — LED呼吸灯

系列文章目录

1.连续打卡第一天:提前对CPK_RA2E1是瑞萨RA系列开发板的初体验,了解一下

2.开发环境的选择和调试(从零开始,加油)

3.欲速则不达,今天是对RA2E1 基础知识的补充学习。

4.e2 studio 使用教程

5.Keil配置使用(使用 RASC 生成 Keil 工程)

6.Keil配置使用(使用 RASC 生成 Keil 工程)

7.(电脑重装系统)学习RA产品家族选型手册

8.问题解决、学习RA寄存器、用寄存器的方式点亮第一个LED灯。

9.继续学习RA寄存器

10.FSP固件库开发及FSP配置详解。

11.FSP固件库开发点亮第一个灯。

12.FSP固件库开发按键输入检测控制LED灯闪烁

13.FSP固件库开发启动文件详解

14.FSP固件库开发延时函数(时钟详解)

15.FSP固件库外部中断处理编程(外部中断检测按键控制LED闪烁)

16.FSP固件库系统定时器(滴答定时器SysTick)每2秒LED闪烁一次

17.FSP固件库开发GPT — PWM通用定时器 定时2s LED 闪烁


文章目录

系列文章目录

前言

一、PWM是什么?

二、FSP固件库开发(PWM输出波形 — LED呼吸灯)

1.新建工程

2.FSP配置

3.代码

总结

不摔的惨烈,如何享受涅磐重生的快乐。


前言

        继前一篇文章 17.FSP固件库开发GPT — PWM通用定时器 定时2s LED 闪烁 我们具体讲解了定时如何使用,如何定时定多长时间,什么计算,FSP库如何开发,不过只是做了一个开发的讲解,并没有探讨到更深沉的地方,写文章的效果一个是想让大家扫盲,对RA2E1进行一个整体的理解扫盲,更深沉的理解将会在后续具体的项目运营中讲述,

        上次的文章讲的是   PWM作为定时器使用,这次我们讲一下PWM作为输出使用,输出波形,但是由于身边没有示波器,所以这次没有视频效果。

        具体的大家也可以关注  我的公众号:嵌入式up(提供我自己写的例程  和  技术支持探讨)


一、PWM是什么?

        下面这么文章也讲解到了PWM是什么。大家可以移步前往。

                   17. FSP固件库开发GPT — PWM通用定时器 定时2s LED 闪烁

 学过单片机的大家伙,对pwm这个肯定不陌生,所以这里不再赘述,大家也可以翻阅上篇文章,上篇文章详细介绍到了。

二、FSP固件库开发(PWM输出波形 — LED呼吸灯

1.新建工程

硬件图:


2.FSP配置

如果常 P501 报红色   是因为  引脚之前被配置好了    需要取消之前的配置

这样就可以了。

按顺序依次选择,生成PWM模块。双击属性,最大化配置框。依次配置General,Output,Pins。实现1秒一个周期,占空比50%,在P501输出。 


 点击此按钮可查询新建的端口可以使用的所有函数: 

  • Pin Output Support:这一项配置允许输出 PWM 信号到引脚,我们改为使能引脚输出。

  • Name 和 Channel:这两项分别设置 GPT 模块名字为 “g_timer_gpt5” 和选择第 5 个 GPT 定时器(第6个通道)。

  • Mode:配置 GPT 的工作模式为 PWM 输出模式。

  • Period 和 Period Unit:我们将PWM频率设为 20 KHz, 因此“Period”设置为 20,单位“Period Unit”设置为 Kilohertz,即千赫兹(KHz)。

  • GTIOCB Output Enabled:使能 GTIOCB 输出。

  • GTIOCB Stop Level:设置定时器停止时 GTIOCB 输出的电平为低电平。

  • GTIOC6B:选择连接到 P600 引脚,这个软件会自动设置的,我们只要确认了就好。


3.代码

#include "hal_data.h"
#include "r_gpt.h"


FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER


typedef enum
{
    SYS_DELAY_UNITS_SECONDS      = 200000000, ///< Requested delay amount is in seconds
    SYS_DELAY_UNITS_MILLISECONDS = 200000,    ///< Requested delay amount is in milliseconds
    SYS_DELAY_UNITS_MICROSECONDS = 200        ///< Requested delay amount is in microseconds
} sys_delay_units_t;


/* 定义变量 */
uint32_t IT_Period;
uint32_t IT_nums;

/**
* @brief  延时程序
* @param  delay: 延时的单位时间
* @param  unit: 延时的单位
* @retval 无
*/

void SysTick_Delay(uint32_t delay, sys_delay_units_t unit)
{
    uint32_t SumTime = delay * unit; //计算总延时时间(单位为时钟节拍数)
    IT_nums = SumTime/IT_Period;
    while (IT_nums != 0);
}


/**
* @brief  SysTick的中断服务函数
* @param  无
* @retval 无
*/
extern void SysTick_Handler(void); //需要先extern声明一下避免编译器警告
void SysTick_Handler(void)
{
	IT_nums++;
    if (IT_nums == 2000)
    {
		 IT_nums = 0;
	     R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_01, BSP_IO_LEVEL_HIGH); //LED1亮
    }
	else
	{
		 R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_01, BSP_IO_LEVEL_LOW); //LED1亮
		
	}
}

 /**
  * @brief  启动系统滴答计时器 SysTick
  * @param  IT_frequency: 滴答计时器每秒的中断次数
  * @retval 无
  */
 void SysTick_Init(uint32_t IT_frequency)
 {
     /* SystemCoreClock在这里默认为200M
      * SystemCoreClock / 1000    1ms中断一次
      * SystemCoreClock / 100000  10us中断一次
      * SystemCoreClock / 1000000 1us中断一次
      */
     IT_Period = SystemCoreClock / IT_frequency;
     uint32_t err = SysTick_Config (IT_Period);
     assert(err==0); //capture error
 }

 

/** 自定义函数:设置PWM占空比
    @param duty 占空比范围:0~100 %
*/
void GPT_PWM_SetDuty(uint8_t duty)
{
    timer_info_t info;
    uint32_t current_period_counts;
    uint32_t duty_cycle_counts;

    if (duty > 100)
        duty = 100; //限制占空比范围:0~100

    /* 获得GPT的信息 */
    R_GPT_InfoGet(&g_timer_gpt5_ctrl, &info);

    /* 获得计时器一个周期需要的计数次数 */
    current_period_counts = info.period_counts;

    /* 根据占空比和一个周期的计数次数计算GTCCR寄存器的值 */
    duty_cycle_counts = (uint32_t)(((uint64_t) current_period_counts * duty) / 100);

    /* 最后调用FSP库函数设置占空比 */
    R_GPT_DutyCycleSet(&g_timer_gpt5_ctrl, duty_cycle_counts, GPT_IO_PIN_GTIOCB);
}

void GPT_PWM_Init(void)
{
    /* 初始化 GPT 模块 */
    R_GPT_Open(&g_timer_gpt5_ctrl, &g_timer_gpt5_cfg);

    /* 启动 GPT 定时器 */
    R_GPT_Start(&g_timer_gpt5_ctrl);


}

void breathing_LED(void)
{
    uint8_t duty = 0;
    uint8_t step = 5;
	
	GPT_PWM_Init();
    while(1)
    {
        if(duty == 100)
            step = 0;
        else if(duty == 0)
            step = 10;
        duty += step;
        GPT_PWM_SetDuty(duty);
        R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MICROSECONDS);
    }
}

/*******************************************************************************************************************//**
 * 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)   //相当于主函数  函数最终执行的地方
{
	R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_02, BSP_IO_LEVEL_LOW); //LED1亮
	R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_01, BSP_IO_LEVEL_LOW); //LED1亮
	
    R_BSP_PinAccessEnable ();  //启用对PFS寄存器的访问,因为后面写IO口都用BSP内联函数
	
	fsp_err_t err = FSP_SUCCESS;
	uint8_t ndt = 30;
	uint8_t step = 10;
	
	/* PWM On*/
    /* 初始化 GPT 模块 */
    err = R_GPT_Open(&g_timer_gpt5_ctrl, &g_timer_gpt5_cfg); 
	assert(err == FSP_SUCCESS);
	R_GPT_Start(&g_timer_gpt5_ctrl);

	R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
	
	err = R_GPT_PeriodSet(&g_timer_gpt5_ctrl,2000);
	assert(err == FSP_SUCCESS);
	R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
	
    /* 最后调用FSP库函数设置占空比 */
    R_GPT_DutyCycleSet(&g_timer_gpt5_ctrl, 20*(100-ndt), GPT_IO_PIN_GTIOCB);
	
	assert(err == FSP_SUCCESS);
	R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);

	err = R_GPT_Reset(&g_timer_gpt5_ctrl);
	assert(err == FSP_SUCCESS);
	R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);	
	while(1){

		R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);	
		
		R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_01, BSP_IO_LEVEL_HIGH);
		
		R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);	
		
		R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_01, BSP_IO_LEVEL_LOW);
		
		err = R_GPT_DutyCycleSet(&g_timer_gpt5_ctrl, 20*(100-ndt), GPT_IO_PIN_GTIOCB);
		assert(err == FSP_SUCCESS);
		R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);	
		
		ndt += step;
		if(ndt >= 100 || ndt <= 0)
			step = -step;
//	    R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_02, BSP_IO_LEVEL_HIGH); 
//        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
//        R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_02, BSP_IO_LEVEL_LOW); 
//        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);

	}
	

视频效果:

RA2E1开发板 呼吸灯成就


总结

        pwm呼吸灯成就达成,继续努力!


不摔的惨烈,如何享受涅磐重生的快乐。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。