更新时间:2024-11-20 02:14:52下载pdf
API 文件
PWM 相关 API 位于 ty_pwm.h
文件中,芯片平台关联的驱动代码位于 ty_pwm_xxxx.c
文件中。
tuya_ble_sdk_demo
└── board
├── include
| └── ty_pwm.h
├── xxxx /* xxxx 为芯片平台,如 TLSR825x */
| └── ty_board_xxxx /* xxxx 为芯片平台,如 ty_board_tlsr825x */
| └── ty_pwm_xxxx.c /* xxxx 为芯片平台,如 ty_pwm_tlsr825x.c */
└── board.h
Demo 文件
tuya_board_api_demo 的 PWM Demo 文件结构如下:
tuya_ble_sdk_demo
├── app /* API 应用示例 */
| ├── include
| | └── ty_board_demo
| | | ├── demo_config.h /* demo 配置文件 */
| | | └── ty_pwm_demo.h /* pwm 模块示例代码 */
| | ├── tuya_ble_board_api_demo.h /* board api 示例程序入口 */
| | └── tuya_ble_sdk_demo.h /* tuya_ble_sdk 应用入口 */
| └── src
| ├── ty_board_demo
| | └── ty_pwm_demo.c /* pwm 模块示例代码 */
| ├── tuya_ble_board_api_demo.c /* board api 示例程序入口 */
| └── tuya_ble_sdk_demo.c /* tuya_ble_sdk 应用入口 */
└── board /* 部分 API 修改示例 */
修改 demo_config.h
文件即可切换到 PWM 模块示例程序:
#define BOARD_API_DEMO BOARD_API_PWM
函数名称 | 功能描述 |
---|---|
ty_pwm_init | 初始化 PWM 模块 |
ty_pwm_start | 启动 PWM 输出 |
ty_pwm_stop | 停止 PWM 输出 |
ty_pwm_control | 控制 PWM 模块 |
ty_pwm_uninit | 关闭 PWM 模块 |
函数名 | ty_pwm_init |
---|---|
函数原型 | uint32_t ty_pwm_init(ty_pwm_t* p_pwm); |
功能概述 | 初始化 PWM 模块 |
参数 | p_pwm [in]:pwm 参数,由 ty_pwm_t 类型定义 |
返回值 | 0 :成功;其他:失败 |
备注 | 可根据芯片平台按需补充或修改函数内容、参数及返回值 |
函数名 | ty_pwm_start |
---|---|
函数原型 | uint32_t ty_pwm_start(ty_pwm_t* p_pwm); |
功能概述 | 启动 PWM 输出 |
参数 | p_pwm [in]:pwm 参数,由 ty_pwm_t 类型定义 |
返回值 | 0 :成功;其他:失败 |
备注 | 可根据芯片平台按需补充或修改函数内容、参数及返回值 |
函数名 | ty_pwm_stop |
---|---|
函数原型 | uint32_t ty_pwm_stop(ty_pwm_t* p_pwm); |
功能概述 | 停止 PWM 输出 |
参数 | p_pwm [in]:pwm 参数,由 ty_pwm_t 类型定义 |
返回值 | 0 :成功;其他:失败 |
备注 | 可根据芯片平台按需补充或修改函数内容、参数及返回值 |
函数名 | ty_pwm_control |
---|---|
函数原型 | uint32_t ty_pwm_control(ty_pwm_t* p_pwm, uint8_t cmd, void* arg); |
功能概述 | 控制 PWM 模块 |
参数 | p_pwm [inout]:pwm 参数,由 ty_pwm_t 类型定义 cmd [in]:控制命令,由 ty_pwm_cmd_t 类型定义 arg [in]:命令参数,取决于控制命令 |
返回值 | 0 :成功;其他:失败 |
备注 | 可根据芯片平台按需补充或修改函数内容、参数及返回值 |
函数名 | ty_pwm_uninit |
---|---|
函数原型 | uint32_t ty_pwm_uninit(ty_pwm_t* p_pwm); |
功能概述 | 关闭 PWM 模块 |
参数 | p_pwm [in]:pwm 参数,由 ty_pwm_t 类型定义 |
返回值 | 0 :成功;其他:失败 |
备注 | 可根据芯片平台按需补充或修改函数内容、参数及返回值 |
typedef struct {
GPIO_PinTypeDef pin; /* 引脚编号 */
pwm_id id; /* PWM ID */
uint8_t polarity; /* 极性 */
uint32_t freq; /* 周期 */
uint8_t duty; /* 占空比 */
} ty_pwm_t;
typedef enum {
TY_PWM_CMD_SET_POLARITY = 0, /* 极性 */
TY_PWM_CMD_SET_FREQ, /* 周期 */
TY_PWM_CMD_SET_DUTY, /* 占空比 */
} ty_pwm_cmd_t;
typedef struct {
uint8_t polarity; /* 极性(0-H, 1-L) */
} ty_pwm_set_polarity_t;
typedef struct {
uint32_t freq; /* 周期(us) */
} ty_pwm_set_freq_t;
typedef struct {
uint8_t duty; /* 占空比(%) */
} ty_pwm_set_duty_t;
以 TLSR825x 平台为例,可参考以下代码补充 PWM 模块的 API 函数,或者直接在应用代码中调用芯片原厂提供的 API 来实现相关功能。
ty_pwm.h
/* 根据TLSR825x的pwm通道和引脚对应关系,修改参数id为func */
typedef struct {
GPIO_PinTypeDef pin; /* 引脚编号 */
GPIO_FuncTypeDef func; /* 引脚功能 */
uint8_t polarity; /* 极性 */
uint32_t freq; /* 周期 */
uint8_t duty; /* 占空比 */
} ty_pwm_t;
ty_pwm_tlsr825x.c
/****************************************************
PWM0 : PA2. PC1. PC2. PD5.
PWM1 : PA3. PC3.
PWM2 : PA4. PC4.
PWM3 : PB0. PD2.
PWM4 : PB1. PB4.
PWM5 : PB2. PB5.
PWM0_N : PA0. PB3. PC4. PD5.
PWM1_N : PC1. PD3.
PWM2_N : PD4.
PWM3_N : PC5.
PWM4_N : PC0. PC6.
PWM5_N : PC7.
****************************************************/
uint32_t ty_pwm_init(ty_pwm_t* p_pwm)
{
if (p_pwm == NULL) {
return 1;
}
if (p_pwm->duty < 0 || p_pwm->duty > 100) {
return 2;
}
if (p_pwm->func < AS_PWM0 || p_pwm->func > AS_PWM5_N) {
return 3;
}
pwm_set_clk(CLOCK_SYS_CLOCK_HZ, CLOCK_SYS_CLOCK_HZ);
gpio_set_func(p_pwm->pin, p_pwm->func);
pwm_id id = (p_pwm->func < AS_PWM0_N) ? (p_pwm->func - AS_PWM0) : (p_pwm->func - AS_PWM0_N);
pwm_set_mode(id, PWM_NORMAL_MODE);
pwm_polo_enable(id, p_pwm->polarity);
pwm_set_cycle_and_duty(id, (uint16_t)(p_pwm->freq * CLOCK_SYS_CLOCK_1US),
(uint16_t)(p_pwm->freq * CLOCK_SYS_CLOCK_1US * p_pwm->duty / 100));
return 0;
}
uint32_t ty_pwm_start(ty_pwm_t* p_pwm)
{
if (p_pwm == NULL) {
return 1;
}
if (p_pwm->duty < 0 || p_pwm->duty > 100) {
return 2;
}
if (p_pwm->func < AS_PWM0 || p_pwm->func > AS_PWM5_N) {
return 3;
}
pwm_id id = (p_pwm->func < AS_PWM0_N) ? (p_pwm->func - AS_PWM0) : (p_pwm->func - AS_PWM0_N);
pwm_start(id);
return 0;
}
uint32_t ty_pwm_stop(ty_pwm_t* p_pwm)
{
if (p_pwm == NULL) {
return 1;
}
if (p_pwm->func < AS_PWM0 || p_pwm->func > AS_PWM5_N) {
return 3;
}
pwm_id id = (p_pwm->func < AS_PWM0_N) ? (p_pwm->func - AS_PWM0) : (p_pwm->func - AS_PWM0_N);
pwm_stop(id);
return 0;
}
uint32_t ty_pwm_control(ty_pwm_t* p_pwm, uint8_t cmd, void* arg)
{
if ((p_pwm == NULL) || (arg == NULL)) {
return 1;
}
if (p_pwm->func < AS_PWM0 || p_pwm->func > AS_PWM5_N) {
return 3;
}
pwm_id id = (p_pwm->func < AS_PWM0_N) ? (p_pwm->func - AS_PWM0) : (p_pwm->func - AS_PWM0_N);
switch(cmd) {
case TY_PWM_CMD_SET_POLARITY: {
ty_pwm_set_polarity_t* param = arg;
p_pwm->polarity = param->polarity;
pwm_polo_enable(id, p_pwm->polarity);
}
break;
case TY_PWM_CMD_SET_FREQ: {
ty_pwm_set_freq_t* param = arg;
p_pwm->freq = param->freq;
pwm_set_cycle_and_duty(id, (uint16_t)(p_pwm->freq * CLOCK_SYS_CLOCK_1US),
(uint16_t)(p_pwm->freq * CLOCK_SYS_CLOCK_1US * p_pwm->duty / 100));
}
break;
case TY_PWM_CMD_SET_DUTY: {
ty_pwm_set_duty_t* param = arg;
if (p_pwm->duty < 0 || p_pwm->duty > 100) {
return 2;
}
p_pwm->duty = param->duty;
pwm_set_cmp(id, (uint16_t)(p_pwm->freq * CLOCK_SYS_CLOCK_1US * p_pwm->duty / 100));
}
break;
default:
break;
}
return 0;
}
uint32_t ty_pwm_uninit(ty_pwm_t* p_pwm)
{
uint32_t res = ty_pwm_stop(p_pwm);
if (res) {
return res;
}
gpio_set_func(p_pwm->pin, AS_GPIO);
return 0;
}
功能概述
初期输出周期 500us,占空比 50%,极性高电平的 PWM 波形;2s 后,更新占空比为 80%;再 2s 后,更新周期为 800us;再 2s 后,更新极性为低电平;再 2s 后,停止 PWM 输出并关闭 PWM 模块。
代码示例
以 TLSR825x 平台为例:
#include "ty_pwm_demo.h"
#include "ty_pwm.h"
#include "tuya_ble_log.h"
#include "tuya_ble_port.h"
/***********************************************************
************************micro define************************
***********************************************************/
#define PWM_PIN GPIO_PB5
#define PWM_FUNC AS_PWM5
#define PWM_POL 0
#define PWM_POL_UPDATE 1
#define PWM_FREQ 500
#define PWM_FREQ_UPDATE 800
#define PWM_DUTY 50
#define PWM_DUTY_UPDATE 80
#define PWM_UPDATE_TIME_MS 2000
/***********************************************************
***********************variable define**********************
***********************************************************/
static ty_pwm_t sg_pwm = {
.pin = PWM_PIN,
.func = PWM_FUNC,
.polarity = PWM_POL,
.freq = PWM_FREQ,
.duty = PWM_DUTY
};
static tuya_ble_timer_t sg_pwm_timer;
/***********************************************************
***********************function define**********************
***********************************************************/
/**
* @brief pwm timer callback
* @param[in] none
* @return none
*/
void __pwm_timer_cb(void)
{
static uint8_t s_step = 0;
switch (s_step) {
case 0: {
ty_pwm_set_duty_t new_duty = {
.duty = PWM_DUTY_UPDATE
};
ty_pwm_control(&sg_pwm, TY_PWM_CMD_SET_DUTY, &new_duty);
}
break;
case 1: {
ty_pwm_set_freq_t new_freq = {
.freq = PWM_FREQ_UPDATE
};
ty_pwm_control(&sg_pwm, TY_PWM_CMD_SET_FREQ, &new_freq);
}
break;
case 2: {
ty_pwm_set_polarity_t new_pol = {
.polarity = PWM_POL_UPDATE
};
ty_pwm_control(&sg_pwm, TY_PWM_CMD_SET_POLARITY, &new_pol);
}
break;
case 3: {
ty_pwm_stop(&sg_pwm);
ty_pwm_uninit(&sg_pwm);
}
break;
default:
break;
}
if (s_step <= 3) {
s_step++;
}
}
/**
* @brief ty_pwm api demo init
* @param none
* @return none
*/
void ty_pwm_demo_init(void)
{
uint32_t res;
res = ty_pwm_init(&sg_pwm);
if (res) {
TUYA_APP_LOG_ERROR("ty_pwm_init failed, error code: %d", res);
return;
}
res = ty_pwm_start(&sg_pwm);
if (res) {
TUYA_APP_LOG_ERROR("ty_pwm_start failed, error code: %d", res);
return;
}
tuya_ble_timer_create(&sg_pwm_timer, PWM_UPDATE_TIME_MS, TUYA_BLE_TIMER_REPEATED, (tuya_ble_timer_handler_t)__pwm_timer_cb);
tuya_ble_timer_start(sg_pwm_timer);
}
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈