API GUIDE / PWM / Middleware
G32S10 PWM Middleware 接口
Middleware 层接口:PWM 中间件以“通道”表达输出位置,通道两两成组。
1. MID 资源模型与公开类型
1.1 通道与 PWM 组映射
PWM 中间件以“通道”表达输出位置,通道两两成组。同一组内的 P 输出和 N 输出共享时钟分频和周期计数值,各自拥有独立的比较阈值,即独立占空比。
| PWM 组 | HAL 组选择值 | P 输出通道 | N 输出通道 | 组掩码 |
|---|---|---|---|---|
| 0 | HAL_PWM_GROUP_0 |
IM_PWM_CHANNEL_PWM0 |
IM_PWM_CHANNEL_PWM1 |
0x01 |
| 1 | HAL_PWM_GROUP_1 |
IM_PWM_CHANNEL_PWM2 |
IM_PWM_CHANNEL_PWM3 |
0x02 |
| 2 | HAL_PWM_GROUP_2 |
IM_PWM_CHANNEL_PWM4 |
IM_PWM_CHANNEL_PWM5 |
0x04 |
| 3 | HAL_PWM_GROUP_3 |
IM_PWM_CHANNEL_PWM6 |
IM_PWM_CHANNEL_PWM7 |
0x08 |
| 4 | HAL_PWM_GROUP_4 |
IM_PWM_CHANNEL_PWM8 |
IM_PWM_CHANNEL_PWM9 |
0x10 |
| 5 | HAL_PWM_GROUP_5 |
IM_PWM_CHANNEL_PWM10 |
IM_PWM_CHANNEL_PWM11 |
0x20 |
| 6 | HAL_PWM_GROUP_6 |
IM_PWM_CHANNEL_PWM12 |
IM_PWM_CHANNEL_PWM13 |
0x40 |
| 7 | HAL_PWM_GROUP_7 |
IM_PWM_CHANNEL_PWM14 |
IM_PWM_CHANNEL_PWM15 |
0x80 |
说明:
通道到组的映射为
group_index = channel / 2,偶数通道是 P 输出,奇数通道是 N 输出。MID 内部使用组掩码调用 HAL,组掩码不通过公开接口暴露。
组内 P/N 输出由同一组波形计数器驱动,因此频率必须一致,无法为 P/N 配置不同频率。
1.2 MID 公开宏
| 宏 | 使用说明 | 取值/约束 |
|---|---|---|
IM_PWM_PERIOD_COUNT_BITS | PWM 周期计数寄存器位宽。 | 16。 |
IM_PWM_PERIOD_COUNT_MAX | 硬件可接受的最大周期计数值。 | (1 << 16) - 1,即 65535。 |
IM_PWM_DUTY_PERCENT_MAX | duty_percent 的取值范围上限。 | 100。 |
IM_PWM_MODULE_CLOCK_HZ | im_pwm_init() 配置的 PWM 模块输入时钟频率。 | 200000000,单位 Hz。 |
IM_PWM_CHANNEL_COUNT 是 im_pwm_channel_t 的计数成员而不是宏,值为 16。MID 用它判断通道是否合法:取值等于该值的通道一律被拒绝,因此它只用于计数和边界判断,不作为可用通道。
1.3 MID 公开类型
typedef enum {
IM_PWM_CHANNEL_PWM0 = 0U,
IM_PWM_CHANNEL_PWM1,
IM_PWM_CHANNEL_PWM2,
IM_PWM_CHANNEL_PWM3,
IM_PWM_CHANNEL_PWM4,
IM_PWM_CHANNEL_PWM5,
IM_PWM_CHANNEL_PWM6,
IM_PWM_CHANNEL_PWM7,
IM_PWM_CHANNEL_PWM8,
IM_PWM_CHANNEL_PWM9,
IM_PWM_CHANNEL_PWM10,
IM_PWM_CHANNEL_PWM11,
IM_PWM_CHANNEL_PWM12,
IM_PWM_CHANNEL_PWM13,
IM_PWM_CHANNEL_PWM14,
IM_PWM_CHANNEL_PWM15,
IM_PWM_CHANNEL_COUNT,
} im_pwm_channel_t;
typedef enum {
IM_PWM_STATE_RESET = 0U,
IM_PWM_STATE_READY = 1U,
} im_pwm_state_t;
typedef struct {
uint32_t frequency_hz;
uint8_t duty_percent;
} im_pwm_channel_config_t;im_pwm_channel_t 是 MID 的唯一输出位置标识,取值 0 至 15 对应 PWM0 至 PWM15;IM_PWM_CHANNEL_COUNT 只作为通道数量和边界使用,不是合法通道。
im_pwm_state_t 表示中间件生命周期状态,与 HAL handle 的生命周期状态一一对应。IM_PWM_STATE_RESET 表示尚未调用 im_pwm_init(),或已经调用 im_pwm_deinit()。
im_pwm_channel_config_t 是通道配置对象:
| 成员 | 类型 | 说明 |
|---|---|---|
frequency_hz | uint32_t | 请求的 PWM 频率,单位 Hz,必须非零;同组 P/N 共享。 |
duty_percent | uint8_t | 该通道的占空比,范围 0 至 IM_PWM_DUTY_PERCENT_MAX。 |
1.4 请求参数到硬件参数的映射规则
MID 不直接暴露分频、周期计数值和比较阈值,调用方只提供频率和占空比。source_clock_hz 指 im_pwm_init() 配置并回读到的 PWM 模块输入时钟频率,默认目标值为 IM_PWM_MODULE_CLOCK_HZ。
频率解算:
对分频指数 div = 0 到 7(分频系数 2^div)依次尝试: count = ceil(source_clock_hz / (frequency_hz * 2^div)) 取第一个满足 count <= IM_PWM_PERIOD_COUNT_MAX 的组合 clk_div = div period_count = ceil(count / 2)
硬件
period_count计的是半个周期,实际波形周期为2 * period_count个分频后时钟。解算从最小分频开始,因此相同请求频率下会得到尽可能高的周期分辨率。
所有分频都无法满足
count <= IM_PWM_PERIOD_COUNT_MAX时返回IM_ERR_INVALID_PARAM。最高可实现频率为源时钟的一半(
count最小为 1);请求高于该值时接口不返回错误,实际输出为源时钟的一半。最低可实现频率约为
source_clock_hz / (128 * 65536)。以 200 MHz 源时钟计算,约为 23.8 Hz;最高可实现频率为 100 MHz。
占空比映射:
threshold = period_count * duty_percent * 2 / IM_PWM_DUTY_PERCENT_MAX (整除)
100% 对应
period_count * 2个半周期。阈值写入采用向下取整,因此实际占空比不会高于请求占空比。
周期计数值越大,占空比量化误差越小;
period_count * 2不小于 100 时,读回值与请求值偏差不超过 1 个百分点。
固定波形配置项:
| 硬件配置 | MID 固定取值 | 说明 |
|---|---|---|
| P/N 死区 | 0 | 边沿对齐模式下 0 表示无死区。 |
| 时钟分频 | 由请求频率解算 | P/N 共享。 |
| 周期计数值 | 由请求频率解算 | P/N 共享。 |
| P/N 阈值 | 由请求占空比解算 | P/N 各自独立。 |
1.5 运行状态与资源模型
| 状态 | 说明 |
|---|---|
IM_PWM_STATE_RESET | 中间件未初始化,或 im_pwm_deinit() 已成功完成 |
IM_PWM_STATE_READY | HAL handle 已初始化,可以配置通道和启动输出 |
中间件内部状态:
| 状态 | 说明 |
|---|---|
| 源时钟频率 | im_pwm_init() 回读到的 PWM 模块输入时钟,用于频率解算和读回 |
| 组位图 | 记录哪些 PWM 组至少配置过一路通道 |
| 占空比缓存 | 16 路通道各自的请求占空比,用于重算同组另一路阈值 |
说明:
中间件只支持一个实例,所有
im_pwm_*接口共享同一份静态状态,不提供按对象绑定的多实例接口。中间件不使用动态内存,不依赖 RTOS,也不创建线程。
中间件当前不使用中断、DMA 和回调,所有操作同步完成。
2. MID 接口规范
2.1 生命周期与资源流程
分别调用 configure
frequency_update 更新频率
资源与状态规则:
| 阶段 | 中间件行为 | 需要调用方完成 |
|---|---|---|
| 初始化前 | 通道接口返回 IM_ERR_NOT_READY | 完成 PWM 输出引脚复用 |
im_pwm_init() | 打开 CPM gate 和 CGU 模块时钟,配置并回读 PWM 模块频率,初始化 HAL handle,清空组记账和占空比缓存 | 保证 CPM 可用,且板级时钟配置允许 200 MHz 的 PWM 模块时钟 |
| 通道配置 | 解算并写入整组配置,触发比较参数更新 | 选择实际使用的输出通道 |
| 组启动 | 使能整组,P/N 输出同时开始 | 观察波形或接入负载 |
| 运行期更新 | 占空比可在线更新;频率更新要求组已停止 | 需要改频率时先停组 |
| 反初始化 | 停止所有已配置组,触发模块软复位,关闭模块时钟和 gate | 再次使用前重新调用 im_pwm_init() |
2.2 初始化与反初始化
2.2.1 im_pwm_init
error_code_t im_pwm_init(void);
功能说明:
初始化 PWM 中间件:打开 PWM CPM gate 和 CGU 模块时钟,把 PWM 模块输入频率配置为 IM_PWM_MODULE_CLOCK_HZ 并回读实际频率,初始化 HAL handle,并清空组记账和占空比缓存。
参数表:无参数。
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 初始化成功,或中间件已处于已初始化状态 |
IM_ERR_NOT_READY | 回读到的 PWM 模块时钟频率为 0 |
| CPM/HAL 错误码 | 打开时钟、配置频率、回读频率或 HAL 初始化失败时透传对应返回值 |
补充说明:
任一步失败时,接口会关闭已打开的模块时钟和 gate 后再返回错误。
本接口只做时钟和软件状态准备,不配置任何波形参数,也不启动输出。
本接口不触发 PWM 软复位,不复位硬件寄存器。
本接口只允许在任务上下文调用,不得在中断服务程序中调用。中间件不加锁,多任务并发调用需由调用方串行化。
2.2.2 im_pwm_deinit
error_code_t im_pwm_deinit(void);
功能说明: 反初始化 PWM 中间件:停止所有已配置的 PWM 组,触发 PWM 模块软复位,等待硬件释放复位请求并清除复位状态,关闭 PWM 模块时钟和 CPM gate,并清空中间件内部状态。
参数表:无参数。
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 反初始化成功 |
IM_ERR_TIMEOUT | 等待硬件释放软复位请求超时 |
| HAL/CPM 错误码 | 停止组、触发或清除软复位、关闭时钟失败时透传对应返回值 |
补充说明:
已配置组会被整体停止,P/N 同时停止;从未配置过的组不参与停止操作。
软复位作用于整个 PWM 模块,会影响同一模块上的所有使用方;调用前应确认没有其他 PWM 使用者,例如 PWM 音频。
软复位状态轮询为忙等实现,次数上限为 10000 次;硬件始终不释放复位请求时返回
IM_ERR_TIMEOUT。反初始化过程中任一 HAL 或 CPM 调用失败会立即返回,已完成的部分不回滚,中间件记账保持不变;可以再次调用本接口重试。
反初始化成功后中间件回到
IM_PWM_STATE_RESET,组记账和占空比缓存被清空,需要重新调用im_pwm_init()才能再次配置和启动输出。本接口只允许在任务上下文调用,不得在中断服务程序中调用。
2.2.3 im_pwm_state_get
error_code_t im_pwm_state_get(im_pwm_state_t *state_out);
功能说明: 读取 PWM 中间件的生命周期状态。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
state_out | im_pwm_state_t * | 输出 | 输出当前中间件状态,不能为空 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | state_out 为空 |
补充说明:
本接口可以在
im_pwm_init()之前和im_pwm_deinit()之后调用,两种情况都返回IM_PWM_STATE_RESET。中间件状态与 HAL handle 生命周期状态一一对应;本接口不访问 PWM 硬件。
本接口只允许在任务上下文调用。
2.3 通道配置
2.3.1 im_pwm_channel_configure
error_code_t im_pwm_channel_configure(im_pwm_channel_t channel, const im_pwm_channel_config_t *config);
功能说明: 配置一个 PWM 通道:按请求频率解算同组的时钟分频与周期计数值,按请求占空比解算该通道的比较阈值,写入整组基础配置并触发比较参数更新。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
channel | im_pwm_channel_t | 输入 | 目标通道,取值 IM_PWM_CHANNEL_PWM0 至 IM_PWM_CHANNEL_PWM15 |
config | const im_pwm_channel_config_t * | 输入 | 通道配置,不能为空;frequency_hz 必须非零,duty_percent 不能超过 IM_PWM_DUTY_PERCENT_MAX |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 配置成功 |
IM_ERR_INVALID_PARAM | 通道越界、config 为空、频率为 0、占空比超过 100,或请求频率低于可实现下限 |
IM_ERR_NOT_READY | 中间件未初始化 |
IM_ERR_BUSY | 目标通道所属组正在输出,当前配置不可修改 |
补充说明:
参数校验顺序为:通道范围、
config非空、频率非零、占空比范围,然后检查中间件状态,最后解算频率。配置粒度为 PWM 组:写入整组的时钟分频、周期计数值、P/N 阈值、波形模式、初始电平、空闲电平和死区。
本通道阈值使用本次请求的
duty_percent;同组另一路输出的阈值使用中间件缓存的占空比,该缓存初始为 0,因此只配置一路时,另一路按 0% 占空比参与配置。组内 P/N 共享时钟分频和周期计数值,后配置的一路会用自己请求的频率重写整组的频率。
本接口不启动输出,配置成功后需要调用
im_pwm_channel_enable()才会产生波形。目标组正在输出时接口返回
IM_ERR_BUSY,且不修改中间件缓存的占空比和组记账。配置成功后中间件记录该通道的请求占空比,并标记该组已配置。
本接口只允许在任务上下文调用;调用前应确认目标组已停止输出。
2.3.2 im_pwm_channel_get_config
error_code_t im_pwm_channel_get_config(im_pwm_channel_t channel, im_pwm_channel_config_t *config_out);
功能说明: 读取一个 PWM 通道当前的频率和占空比。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
channel | im_pwm_channel_t | 输入 | 目标通道,取值 IM_PWM_CHANNEL_PWM0 至 IM_PWM_CHANNEL_PWM15 |
config_out | im_pwm_channel_config_t * | 输出 | 输出通道配置,不能为空 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 读取成功 |
IM_ERR_INVALID_PARAM | 通道越界或 config_out 为空 |
IM_ERR_NOT_READY | 目标通道所属组尚未配置 |
补充说明:
判定条件是“目标组已配置”,不是中间件初始化状态;中间件未初始化时组必然未配置,同样返回
IM_ERR_NOT_READY。读取的数据来自 HAL 回读的硬件寄存器:组时钟分频、周期计数值和 P/N 阈值,再按
frequency_hz = source_clock_hz / (2^div * period_count * 2)与duty_percent = threshold * 100 / (period_count * 2)反算,除法均为整数向下取整。偶数通道使用 P 阈值,奇数通道使用 N 阈值。
由于换算存在取整,读回频率不会高于请求频率,读回占空比不会高于请求占空比;
period_count * 2不小于 100 时占空比偏差不超过 1 个百分点。本接口只允许在任务上下文调用。
2.4 运行期更新
2.4.1 im_pwm_channel_frequency_update
error_code_t im_pwm_channel_frequency_update(im_pwm_channel_t channel, uint32_t frequency_hz);
功能说明: 更新一个已配置 PWM 通道所属组的频率:重新解算时钟分频和周期计数值,按缓存的占空比重算 P/N 阈值,并触发比较参数更新。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
channel | im_pwm_channel_t | 输入 | 目标通道,取值 IM_PWM_CHANNEL_PWM0 至 IM_PWM_CHANNEL_PWM15 |
frequency_hz | uint32_t | 输入 | 请求的 PWM 频率,单位 Hz,必须非零 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 更新成功 |
IM_ERR_INVALID_PARAM | 通道越界、频率为 0,或请求频率低于可实现下限 |
IM_ERR_NOT_READY | 目标通道所属组尚未配置 |
IM_ERR_BUSY | 目标通道所属组正在输出,时钟分频不可修改 |
补充说明:
接口只接收一个通道,但频率属于整组属性:更新任一路都会同时改变同组 P/N 输出的频率。
更新流程依次写入时钟分频、周期计数值和按缓存占空比重算的 P/N 阈值,最后触发比较参数更新;其中时钟分频写入会检查组工作状态,组正在输出时返回
IM_ERR_BUSY。本接口不修改中间件缓存的占空比;频率变化后阈值按新的周期计数值重算,因此 P/N 的占空比请求值保持不变,实际占空比重新受新的周期分辨率约束。
需要在组运行期间改频率时,应先调用
im_pwm_channel_disable()停止该组,更新后再重新使能。本接口只允许在任务上下文调用。
2.4.2 im_pwm_channel_duty_update
error_code_t im_pwm_channel_duty_update(im_pwm_channel_t channel, uint8_t duty_percent);
功能说明: 更新一个已配置 PWM 通道的占空比:按当前周期计数值把请求占空比换算为比较阈值,改写该组 P/N 阈值并触发比较参数更新。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
channel | im_pwm_channel_t | 输入 | 目标通道,取值 IM_PWM_CHANNEL_PWM0 至 IM_PWM_CHANNEL_PWM15 |
duty_percent | uint8_t | 输入 | 通道占空比,范围 0 至 IM_PWM_DUTY_PERCENT_MAX |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 更新成功 |
IM_ERR_INVALID_PARAM | 通道越界或占空比超过 IM_PWM_DUTY_PERCENT_MAX |
IM_ERR_NOT_READY | 目标通道所属组尚未配置 |
补充说明:
只有目标通道对应的阈值被替换,同组另一路阈值保持当前值。
更新使用 HAL 回读的当前周期计数值,不重新解算频率,因此不改变组频率。
本接口可以在组输出过程中调用,用于运行期调整占空比,不需要停止组。
更新成功后中间件记录该通道的请求占空比,供后续频率更新重算阈值使用。
取整规则与通道配置一致:实际占空比不会高于请求占空比。
本接口只允许在任务上下文调用。
2.5 输出启停
2.5.1 im_pwm_channel_enable
error_code_t im_pwm_channel_enable(im_pwm_channel_t channel);
功能说明: 启动目标通道所属 PWM 组的波形输出。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
channel | im_pwm_channel_t | 输入 | 目标通道,取值 IM_PWM_CHANNEL_PWM0 至 IM_PWM_CHANNEL_PWM15 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 启动请求已下发 |
IM_ERR_INVALID_PARAM | 通道越界 |
IM_ERR_NOT_READY | 目标通道所属组尚未配置,或中间件未初始化 |
补充说明:
启动粒度为 PWM 组:组内任意一路通道都能启动整组,P/N 输出同时开始输出。
组启动后由硬件持续产生波形,直到调用
im_pwm_channel_disable()或im_pwm_deinit()。接口不做幂等判断,对已启动的组重复调用仍返回
IM_OK。启停由 HAL 通过组使能位和时钟更新完成,中间件不等待同步过程,也不查询计数器工作状态。
本接口只允许在任务上下文调用。
2.5.2 im_pwm_channel_disable
error_code_t im_pwm_channel_disable(im_pwm_channel_t channel);
功能说明: 停止目标通道所属 PWM 组的波形输出。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
channel | im_pwm_channel_t | 输入 | 目标通道,取值 IM_PWM_CHANNEL_PWM0 至 IM_PWM_CHANNEL_PWM15 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 停止请求已下发 |
IM_ERR_INVALID_PARAM | 通道越界 |
IM_ERR_NOT_READY | 目标通道所属组尚未配置,或中间件未初始化 |
补充说明:
停止不改变组配置,停止后可以再次调用
im_pwm_channel_enable()恢复输出;组配置和占空比缓存保持有效。停止后可以继续调用
im_pwm_channel_configure()或im_pwm_channel_frequency_update()。接口不做幂等判断,对已停止的组重复调用仍返回
IM_OK。本接口只允许在任务上下文调用。
3. 当前实现约束与行为说明
3.1 频率与占空比换算
频率由分频(
2^0至2^7)和 16 位周期计数值共同实现,只能落在离散频点上,读回频率不会高于请求频率。请求频率高于源时钟的一半时接口返回
IM_OK,实际输出为源时钟的一半;低于可实现下限时返回IM_ERR_INVALID_PARAM。占空比量化为比较阈值,
period_count * 2不小于 100 时读回偏差不超过 1 个百分点;周期计数值较小时偏差会更大。频率更新按缓存的请求占空比重算阈值,因此频率变化后实际占空比会按新的周期分辨率重新量化。
3.2 组资源记账
同组另一路输出的占空比取自中间件缓存,缓存初始为 0。因此只调用一次
im_pwm_channel_configure()时,另一路按 0% 占空比参与配置。判定“是否已配置”以组为单位,因此同组另一路即使未显式配置,也能通过
im_pwm_channel_get_config()、im_pwm_channel_duty_update()和启停接口访问。需要两路都具有明确占空比时,应对同组的 P 和 N 各调用一次
im_pwm_channel_configure()。
3.3 时钟与引脚
im_pwm_init()负责打开 PWM CPM gate 和 CGU 模块时钟,并把 PWM 模块输入频率配置为IM_PWM_MODULE_CLOCK_HZ;im_pwm_deinit()负责关闭它们。芯片上 CGU 的父时钟
SCLK_A为 800 MHz,PWM 模块输入上限为 200 MHz,因此 MID 将模块时钟配置为 200 MHz。PWM 输出引脚复用由 BSP 或调用方负责;MID 不配置 pinmux,也不配置板级使能信号。
当 CPM stub 返回 0 频率时,
im_pwm_init()返回IM_ERR_NOT_READY。
3.4 并发与上下文
中间件使用文件内静态状态保存 HAL handle、源时钟频率、组位图和 16 路占空比缓存,只支持单实例。
中间件不提供内部锁和原子保护;多任务共享同一 PWM 中间件时,调用方必须自行串行化全部
im_pwm_*调用。所有 MID 接口只允许在任务上下文调用,不得在中断服务程序中调用。
中间件不使用动态内存,不依赖 RTOS,也不创建线程。
3.5 复位与释放
im_pwm_deinit()使用 PWM 模块软复位清空硬件状态,会影响同一 PWM 模块上的其他使用方。反初始化期间任一 HAL 或 CPM 调用失败会立即返回,已完成的部分不回滚,可再次调用重试。
软复位等待上限是中间件内部常量,不对调用方暴露超时参数。
3.6 实现约束
MID 只依赖 HAL、CPM 和公共错误码组件,不包含寄存器定义,不展开
pwm_regs_t。公开接口遵循
im_pwm_<对象>_<动词>命名;文件内静态函数遵循<module>_<动词>命名。公开接口的参数校验顺序为:空指针、取值/范围、状态。
MID 不提供回调、不注册 IRQ,也不使用 DMA。
4. 典型用法
以下示例省略返回值检查,实际使用时应逐个判断 error_code_t。
4.1 单组基本输出
#include "im_pwm.h"
im_pwm_channel_config_t config = {
.frequency_hz = 20000U,
.duty_percent = 50U,
};
error_code_t ret;
ret = im_pwm_init(); /* 打开时钟并配置模块频率 */
ret = im_pwm_channel_configure(IM_PWM_CHANNEL_PWM2, &config);
ret = im_pwm_channel_enable(IM_PWM_CHANNEL_PWM2); /* 组 1 的 P/N 同时开始输出 */
/* ... 业务运行 ... */
ret = im_pwm_channel_disable(IM_PWM_CHANNEL_PWM2);
ret = im_pwm_deinit();调用前需要保证 PWM 输出引脚已由 BSP 配置为 PWM 功能。具体板卡的引脚映射参见 code/middleware/pwm/example/README.md。
4.2 组内 P/N 独立占空比
im_pwm_channel_config_t p_config = {
.frequency_hz = 10000U,
.duty_percent = 25U,
};
im_pwm_channel_config_t n_config = {
.frequency_hz = 10000U,
.duty_percent = 75U,
};
/* 同组两路都需要显式配置,否则未配置的一路按 0% 参与配置 */
ret = im_pwm_channel_configure(IM_PWM_CHANNEL_PWM2, &p_config);
ret = im_pwm_channel_configure(IM_PWM_CHANNEL_PWM3, &n_config);
ret = im_pwm_channel_enable(IM_PWM_CHANNEL_PWM2);两路频率必须一致:后配置的一路会用自己请求的频率重写整组频率。
4.3 运行中更新占空比
ret = im_pwm_channel_enable(IM_PWM_CHANNEL_PWM2); /* 组输出过程中直接改占空比,不需要停止 */ ret = im_pwm_channel_duty_update(IM_PWM_CHANNEL_PWM2, 50U);
运行中改频率需要先停组:
ret = im_pwm_channel_disable(IM_PWM_CHANNEL_PWM2); ret = im_pwm_channel_frequency_update(IM_PWM_CHANNEL_PWM2, 20000U); ret = im_pwm_channel_enable(IM_PWM_CHANNEL_PWM2);
4.4 停止与释放
ret = im_pwm_channel_disable(IM_PWM_CHANNEL_PWM2); /* 只停组,配置保留 */ ret = im_pwm_channel_enable(IM_PWM_CHANNEL_PWM2); /* 可以再次启动 */ ret = im_pwm_deinit(); /* 停组、软复位、关闭时钟 */