PWM基础知识
什么是PWM
PWM(Pulse Width Modulation脉宽调制)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号任然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有,要么完全无。比如我们的电压输出是5v的,那么经过改变PWM的占空比,可以达到在一定时间内输出3.3V的效果。
PWM基本参数
PWM是脉冲宽度调制,具有两个非常重要的参数:频率和占空比。
- 频率:PWM的频率是整个周期的倒数。
- 占空比:占空比是指一个周期内高电平所占的比例。
PWM优点
PWM的一个优点是从处理器到被控制系统信号都是数字形式,无需进行数模转换。让信号保持为数字形式可将噪声影响降到最小。噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,才能对数字信号产生影响。对噪声抵抗能力的增强是PWM相对于模拟控制的另一个优点,而且这也是在某些时候将PWM用于通信的主要原因。
PWM 应用
PWM可应用于电机调速、功率调制、PID调节、通信等,配置简单、抗干扰能力强。可以通过PWM来控制LED灯的亮暗变化,可以通过PWM信号来控制无源蜂鸣器发出简单的声音以及实现功率继电器的线圈节能等。PWM用来驱动电机和调节电机转速是非常重要的内容。
PWM 实验
通过驱动PWM实现一个呼吸灯的效果,通过PWM信号占空比的变化,可以实现流过LED电流的不同,实现LED亮暗的渐变。
AGT低功耗定时器介绍
低功耗异步通用定时器(AGT)是一个32位定时器,可用于脉冲输出,外部脉冲宽度或周期测量,以及外部事件计数。这个定时器由一个重新加载寄存器和一个关闭寄存器组成计数器。
AGT 功能说明
注:RA6E2 Group User’s Manual: Hardware 第623页
- 说明:
- 定时器功能说明:支持定时器模式、脉冲输出模式、外部事件计数模式、外部脉冲宽度测量模式与外部脉冲周期测量模式。
- 通道:对于RA6E2 来说:只有两个 32 bits 的AGT定时器。
- 时钟资源:可以选择PCLKB, PCLKB/2, PCLKB/8, AGTLCLK/d, AGTSCLK/d (d = 1, 2, 4, 8, 16, 32, 64,or 128), 或者外部输入事件
- 中断和事件链接功能:下溢事件信号或测量完整事件信号、比较 match A 或者 match B事件信号与比较匹配功能。
AGT I/O pins
引脚名称 | 输入/输出 | 功能 |
---|---|---|
AGTEEn | 输入 | AGT的外部事件输入使能 |
AGTIOn | 输入/输出 | AGT的外部事件输入和脉冲输出 |
AGTOn | 输出 | AGT的脉冲输出 |
AGTOAn | 输出 | AGT的比较匹配A输出 |
AGTOBn | 输出 | AGT的比较匹配B输出 |
注:n=0,1
PWM 呼吸灯
首先打开 e2 studio 软件新建工程后,在 FSP Configuration -> Pins -> Peripherals -> Timers:AGT -> AGT0 接下来我们需要配置PIN Group Select 为模式A only,Operation Mode ,选择 Compare Match 。如下图所示:
接下来,添加AGT定时器的模块, New Stack -> Timers -> Timer,Low-Power(r_agt),如下图所示:
接下来我们选择 g_timer0_Timer 模块,然后点击属性,然后放大,如下图所示:
需要修改的内容如下图所示:
设置完成后,按下 Ctrl + S 进行保存,然后点击 Generate Project Content 进行工程生成。如下图所示:
程序编写
然后再 src 下创建一个 agt 的文件夹,在里面创建 bsp_agt.c 与 bsp_agt.h 两个文件,创建一个 Applay 的文件夹,在里面创建 app.c 与 app.h 两个文件,如下图所示:
#include "Apply\app.h"
#include "agt/bsp_agt.h"
void Run(void)
{
uint8_t i=0;
//初始化AGT
Agt_Init ();
while (1)
{
i++;
if(i>100) i=0;
Agt_Set_Pwm_Cycle(i); //设置占空比
R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef __APP_H
#define __APP_H
#include "hal_data.h"
#include <stdio.h>
void Run(void);
#endif
2
3
4
5
6
7
8
9
#include <agt/bsp_agt.h>
#include "hal_data.h"
void Agt_Init(void)
{
R_AGT_Open(&g_timer0_ctrl, &g_timer0_cfg);
R_AGT_Start(&g_timer0_ctrl);
}
void Agt_Set_Pwm_Cycle(uint8_t number)
{
timer_info_t timer_info;
uint64_t get_cycle_count;
uint32_t counts;
fsp_err_t err;
// 限制占空比范围在0-100%
number = (number > 100) ? 100 : number;
// 获取定时器信息
err = R_AGT_InfoGet(&g_timer0_ctrl, &timer_info);
if (FSP_SUCCESS != err) {
return;// 错误处理逻辑
}
// 获取定时器周期计数
get_cycle_count = timer_info.period_counts;
// 使用32位计算避免溢出
counts = (uint32_t)((get_cycle_count * number) / 100);
// 设置PWM占空比
err = R_AGT_DutyCycleSet(&g_timer0_ctrl, counts, AGT_OUTPUT_PIN_AGTOA);
if (FSP_SUCCESS != err) {
return;// 错误处理逻辑
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#ifndef BSP_AGT_H_
#define BSP_AGT_H_
#include "stdint.h"
void Agt_Init(void);
void Agt_Set_Pwm_Cycle(uint8_t number);
#endif
2
3
4
5
6
7
8
9
void hal_entry(void)
{
/* TODO: add your own code here */
Run(); //应用程序
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
2
3
4
5
6
7
8
9
10
11
实验现象
烧写代码之后,会观察到LED灯由亮变暗的效果。