KDocs 研发资料库
  • 手表穿戴技术应用文档入口汇总
  • JL707N穿戴客述问题FAQ
  • 彩屏仓 硬件开发指南 与 量产作业流程规范
  • 彩屏仓 AC98N和JL701烧录升级注意事项
  • JL707 硬件开发资料
  • JL707 手表硬件设计注意事项 总结
  • 穿戴生产烧录OTA和key文件添加使用说明
  • JL707N-入门到进阶开发指导文档
  • 彩屏仓982相关
  • 彩屏仓耳机介绍
  • 杰理701_707双屏demo介绍
  • 707电子吧唧开发资料
  • GPIO相关
  • UART串口相关
  • SPI相关
  • nandflash相关
  • norflash相关
  • IIC相关
  • PWM相关
  • SD卡相关
  • 定时器TIMER
  • 文件系统接口设计说明文档
  • 音视频录像开发流程
  • rdec编码器
  • 穿戴功耗数据标准
  • 手表蓝牙开发文档
  • 701蓝牙PAN联网demo
  • BLE开发使用说明
  • 701手表2.0.0版本SDK EQ在线调试和离线调试方法 V1.1
  • JL707 手表喇叭输出声音大小评估方法 V1.0
  • JL707 手表音频EQ调试方法 V1.0
  • AC707N 手表通话写卡 软件配置方法
  • 录音功能
  • 701手表2.X.X系列SDK调试EQ配置方法及音频调试技巧V1.1
  • 701手表104版本SDK EQ在线调试和离线调试方法 V1.1
  • mic2dac示例
  • P11 SensorHub相关
  • 手表升级操作文档
  • AC707NGPU
  • DBI模块介绍
  • GPU模块介绍
  • 701N屏幕驱动配置说明
  • 701N_UI编辑工具用户手册
  • 支付宝资料
  • 支付宝硬件接入资料
  • 支付宝乘车码接入资料
  • CAT1 接入文档
  • 701N_WATCH_CAT1开发说明
  • Findmy功能
  • music模式相关
  • 707电池曲线
  • 707N内置FLASH挂载FAT文件系统251112_v1.2
  • AC707N_本地视频播放demo(AVI-MJPEG-PCM)
  • 光波导屏幕调试
  • 耳机研发和生产流程 指南
  • 707-NandFlash 代码和UI资源独立烧录方案
  • 彩屏仓时间同步补丁
  • 彩屏仓抖音点赞移植
  • 707LVGLv8双屏开发
  • 707N蓝牙互传图传demo
  • AVIPCM数据流接入AIVOICE
  • Flash分区操作demo
  • 手表发射问题
  • 701_707 双备份升级DEMO
  • 707_乘车码刷码失败问题_共性

PWM相关

📎 原始文档:https://www.kdocs.cn/l/ctHQHrReabi8 PWM相关

一、MCPWM定义

所有系列的芯片包含了MCPWM ,表示为电机控制pwm,mcpwm 一共有六组(不同芯片会有所差异,具体看代码和芯片手册),对应六组不同的硬件io。

二、MCPWM 应用

1、mcpwm的硬件io

有硬件io 则优先使用硬件io,否则需要通过映射功能映射,所以建议优先使用硬件io,可以查看对应的用户手册查找对应的硬件io,具体硬件io如下:

/*mcpwm硬件引脚,上下为一对:---CH0---     ---CH1---    ---CH2---    ---CH3---    ---CH4---    ---CH5--- */
static u8 pwm_hw_h_pin[6] = {IO_PORTA_00, IO_PORTB_00, IO_PORTB_04, IO_PORTB_09, IO_PORTA_09, IO_PORTC_04};
static u8 pwm_hw_l_pin[6] = {IO_PORTA_01, IO_PORTB_02, IO_PORTB_06, IO_PORTB_10, IO_PORTA_10, IO_PORTC_05};

映射通道映射到每一组io的配置选择,但是仅仅只能有三组映射,这里不是说mcpwm有三组映射,是芯片只有三组映射,比如串口使用了一组后,则芯片映射只剩下两组可以使用。

//output_channle
static u8 CHx_CHx_PWM_H[3][3] = {CH0_CH0_PWM_H, CH0_CH1_PWM_H, CH0_CH2_PWM_H,  CH1_CH0_PWM_H, CH1_CH1_PWM_H, CH1_CH2_PWM_H,  CH2_CH0_PWM_H, CH2_CH1_PWM_H, CH2_CH2_PWM_H};
static u8 CHx_CHx_PWM_L[3][3] = {CH0_CH0_PWM_L, CH0_CH1_PWM_L, CH0_CH2_PWM_L,  CH1_CH0_PWM_L, CH1_CH1_PWM_L, CH1_CH2_PWM_L,  CH2_CH0_PWM_L, CH2_CH1_PWM_L, CH2_CH2_PWM_L};

2、mcpwm函数接口:

int mcpwm_init(struct mcpwm_config *mcpwm_cfg)//mcpwm 初始化
void mcpwm_deinit(int mcpwm_cfg_id)//mcpwm 关闭
void mcpwm_start(int mcpwm_cfg_id)// mcpwm 启动开始
void mcpwm_pause(int mcpwm_cfg_id)// 暂停pwm 输出
void mcpwm_set_frequency(int mcpwm_cfg_id, mcpwm_aligned_mode_type align, u32 frequency)// 设置pwm 的频率
void mcpwm_set_duty(int mcpwm_cfg_id, u16 duty)//设置pwm的占空比

3、mcpwm 模块使用注意事项

mcpwm 模块在低功耗模式下不可使用,因为mcpwm 模块属于外设模块,系统进入低功耗后外设模块会掉电处理,所以在低功耗下无法使用mcpwm。

三、MCPWM 测试代码

查看sdk中的mcpwm.c里面的void mcpwm_test(void)函数。
1. JL701N mcpwm 配置示例(具体看mcpwm.c文件) image 2. AC707N mcpwm 配置示例(具体看mcpwm.c文件) image


/* 简易示例 */
struct mcpwm_config  usr_mcpwm_cfg;

usr_mcpwm_cfg.ch = MCPWM_CH0;                       //通道号
usr_mcpwm_cfg.aligned_mode = MCPWM_EDGE_ALIGNED;    //边沿对齐
usr_mcpwm_cfg.frequency = 1000;                     //1KHz
usr_mcpwm_cfg.duty = 5000;                          //占空比50%
usr_mcpwm_cfg.h_pin = IO_PORTC_00;                  //任意引脚输出,不需要就填-1
usr_mcpwm_cfg.l_pin = IO_PORTC_01;                  //任意引脚输出,不需要就填-1
usr_mcpwm_cfg.complementary_en = 0;                 //两个引脚的波形, 0: 同步, 1: 互补,互补波形的占空比体现在H引脚上
usr_mcpwm_cfg.detect_port = IO_PORTC_02;            //任意引脚保护检测,不需要就填-1
usr_mcpwm_cfg.edge = MCPWM_EDGE_FAILL;              //检测方式,下升沿触发
usr_mcpwm_cfg.irq_cb = usr_mcpwm_detect_test_func;  //故障保护回调函数
usr_mcpwm_cfg.irq_priority = 1;                     //优先级默认为1
int ch0_id = mcpwm_init(&usr_mcpwm_cfg);
mcpwm_start(ch0_id);

四、TIMER PWM 使用demo

如果mcpwm 不够,可以使用timer 定时器来实现pwm功能,使用time来实现pwm ,必须保证对应的timer 定时器不被占用或者使用,否则无法使用timer pwm功能,并且timer pwm 也不能再低功耗模式下使用。

1、701n系列timer pwm示例:

在mcpwm.c文件中可以找到对应的代码,如下:
JL701一共有timer0/1/2/3/4/5路timer,其中timer 0 被系统使用了,无法被使用,其余的timer 视具体情况配置。

/*******************************  用timer做pwm的参考代码  ***************************/
//使用timer pwm 必须保证对应的timer 空闲。
/**
 * @param JL_TIMERx : JL_TIMER0/1/2/3
 * @param pwm_io : JL_PORTA_01, JL_PORTB_02,,,等等,支持任意普通IO
 * @param fre : 频率,单位Hz
 * @param duty : 初始占空比,0~10000对应0~100%
 */
void timer_pwm_init(JL_TIMER_TypeDef *JL_TIMERx, u32 pwm_io, u32 fre, u32 duty)
{
    switch ((u32)JL_TIMERx) {
    case (u32)JL_TIMER0 :
        gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER0_PWM);
        break;
    case (u32)JL_TIMER1 :
        gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER1_PWM);
        break;
    case (u32)JL_TIMER2 :
        gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER2_PWM);
        break;
    case (u32)JL_TIMER3 :
        bit_clr_ie(IRQ_TIME3_IDX);
        gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER3_PWM);
        break;
    case (u32)JL_TIMER4 :
        gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER4_PWM);
        break;
    case (u32)JL_TIMER5 :
        gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER5_PWM);
        break;
    default:
        return;
    }
    u32 u_clk = 24000000;
    //初始化timer
    JL_TIMERx->CON = 0;
    JL_TIMERx->CON |= (0b110 << 10);                    //时钟源选择STD_24M时钟源
    JL_TIMERx->CON |= (0b0001 << 4);                    //时钟源再4分频
    JL_TIMERx->CNT = 0;                                    //清计数值
    JL_TIMERx->PRD = u_clk / (4 * fre);                    //设置周期
    JL_TIMERx->PWM = (JL_TIMERx->PRD * duty) / 10000;    //设置初始占空比,0~10000对应0~100%
    JL_TIMERx->CON |= (0b01 << 0);                        //计数模式
    JL_TIMERx->CON |= BIT(8);                            //PWM使能
    //设置引脚状态
    gpio_set_die(pwm_io, 1);
    gpio_set_pull_up(pwm_io, 0);
    gpio_set_pull_down(pwm_io, 0);
    gpio_set_direction(pwm_io, 0);

    printf("JL_TIMERx->PRD = 0x%x\n", JL_TIMERx->PRD);
    printf("JL_TIMERx->CON = 0x%x\n", JL_TIMERx->CON);
}

void set_timer_pwm_duty(JL_TIMER_TypeDef *JL_TIMERx, u32 duty)
{
    JL_TIMERx->PWM = (JL_TIMERx->PRD * duty) / 10000;    //0~10000对应0~100%
}

void timer_pwm_test(void)
{
    printf("timer_pwm_test\n");
    timer_pwm_init(JL_TIMER2, IO_PORTB_03, 10000, 7000);
    // timer_pwm_init(JL_TIMER3, IO_PORTG_04, 1000, 2000);
    extern void wdt_clear();
    while (1) {
        wdt_clear();
    }
}

2、AC707N系列timer pwm

一共有timer0/1/2/3路timer,其中timer3 被系统使用了,无法被使用,其余的timer 视具体情况配置。

/*******************************  用timer做pwm的参考代码  ***************************/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//需要确定对应的定时器是否已经被使用,该功能使用定时器来模拟的pwm,所以对应的定时器必须空闲不被占用
/**
 * @param JL_TIMERx : JL_TIMER0/1/2/
 * @param pwm_io : JL_PORTA_01, JL_PORTB_02,,,等等,支持任意普通IO
 * @param fre : 频率,单位Hz
 * @param duty : 初始占空比,0~10000对应0~100%
 */
void timer_pwm_init(JL_TIMER_TypeDef *JL_TIMERx, u32 pwm_io, u32 fre, u32 duty)
{

    switch ((u32)JL_TIMERx) {
    case (u32)JL_TIMER0 :
        gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER0_PWM);
        break;
    case (u32)JL_TIMER1 :
        gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER1_PWM);
        break;
    case (u32)JL_TIMER2 :
        gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER2_PWM);
        break;

    default:
        ASSERT(0, "JL_TIMERx is err\n");
        return;
    }
    u32 u_clk = 24000000;
    //初始化timer
    JL_TIMERx->CON = 0;
    JL_TIMERx->CON |= (0b110 << 10);                    //时钟源选择STD_24M时钟源
    JL_TIMERx->CON |= (0b0001 << 4);                    //时钟源再4分频
    JL_TIMERx->CNT = 0;                                    //清计数值
    JL_TIMERx->PRD = u_clk / (4 * fre);                    //设置周期
    JL_TIMERx->PWM = (JL_TIMERx->PRD * duty) / 10000;    //设置初始占空比,0~10000对应0~100%
    JL_TIMERx->CON |= (0b01 << 0);                        //计数模式
    JL_TIMERx->CON |= BIT(8);                            //PWM使能
    
    
    //设置引脚状态
    gpio_hw_set_die(IO_PORT_SPILT(pwm_io), 1);
    gpio_hw_set_pull_up(IO_PORT_SPILT(pwm_io),0);
    gpio_hw_set_pull_down(IO_PORT_SPILT(pwm_io), 0);
    gpio_hw_set_direction(IO_PORT_SPILT(pwm_io), 0);

    printf("JL_TIMERx->PRD = 0x%x\n", JL_TIMERx->PRD);
    printf("JL_TIMERx->CON = 0x%x\n", JL_TIMERx->CON);
}
/**
 * @param JL_TIMERx : JL_TIMER0/1/2/
 * @param duty : 初始占空比,0~10000对应0~100%
 */
void set_timer_pwm_duty(JL_TIMER_TypeDef *JL_TIMERx, u32 duty)
{
    JL_TIMERx->PWM = (JL_TIMERx->PRD * duty) / 10000;    //0~10000对应0~100%
}

/**
 * @param JL_TIMERx : JL_TIMER0/1/2/
 * @param pwm_io : JL_PORTA_01, JL_PORTB_02,,,等等,支持任意普通IO
 */
void close_timer_pwm(JL_TIMER_TypeDef *JL_TIMERx,u32 pwm_io)
{
    printf("%s>>>>>>>>>>>>\n",__func__);
    //clear the timer param.......
    JL_TIMERx->CON &= ~BIT(8); //PWM使能
    JL_TIMERx->CON = 0;//清除寄存器
    JL_TIMERx->CNT = 0;//清计数值
    JL_TIMERx->PRD = 0;//清零周期
    JL_TIMERx->PWM = 0;//释放pwm
    // free io ctrl 释放映射功能
    // todo....
    switch ((u32)JL_TIMERx) {
        case (u32)JL_TIMER0 :
            gpio_och_disable_output_signal(pwm_io,OUTPUT_CH_SIGNAL_TIMER0_PWM);
            break;
        case (u32)JL_TIMER1 :
            gpio_och_disable_output_signal(pwm_io,OUTPUT_CH_SIGNAL_TIMER1_PWM);
            break;
        case (u32)JL_TIMER2 :
            gpio_och_disable_output_signal(pwm_io,OUTPUT_CH_SIGNAL_TIMER2_PWM);
            break;
        
        default:
            ASSERT(0, "JL_TIMERx is err,please check timer channel\n");
            break;
    }
    // set io hight z 恢复IO高阻态
    gpio_set_mode(IO_PORT_SPILT(pwm_io), PORT_HIGHZ);
}
//to test use
void mcpwm_use_timer_test(void)
{
    r_printf("%s>>>>>>>>>>>>>>>\n", __func__);
    timer_pwm_init(JL_TIMER1, IO_PORTB_06, 10000, 1000);
    // timer_pwm_init(JL_TIMER3, IO_PORTG_04, 1000, 2000);
    extern void wdt_clear();
    static u32 cnt = 0;
    while (1) {
        wdt_clear();
        //to test
        cnt++;
        if(cnt % 400000 == 0){
            cnt = 0;
            set_time_duty();
        }
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

This electronic documentation and any attachments are confidential and may be legally privileged or otherwise protected from disclosure. If you are not the intended recipient, please do not disclose the contents to anyone。
Thank you for your cooperation!
解析权归杰理所有!
The analysis right belongs to JieLi Technology Co., Ltd.

Prev
IIC相关
Next
SD卡相关