当前位置: 首页 > news >正文

VESC 电机定时器TIMER PWM初始化

static void timer_reinit(int f_zv) {

    utils_sys_lock_cnt();

    /* 定时器恢复初始化 */

    TIM_DeInit(TIM1);

    TIM_DeInit(TIM8);

    TIM_DeInit(TIM2);

    /* 定时器基础 比较输出 高级定时器 结构体

    stmf4 高级定时器结构体只适用定时器18

    this structure is used only with TIM1 and TIM8.

    */

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    TIM_OCInitTypeDef TIM_OCInitStructure;

    TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

    /* 清空计数器 */

    TIM1->CNT = 0;

    TIM2->CNT = 0;

    TIM8->CNT = 0;

    /* 初始化时钟 */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

    /*

        分频 0

        计数模式 中央对齐模式1

        重载值 系统时钟/频率

        时钟分频 这个分频主要用于死区和过滤时钟

        重载值

    */

    TIM_TimeBaseStructure.TIM_Prescaler = 0;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;

    TIM_TimeBaseStructure.TIM_Period = (SYSTEM_CORE_CLOCK / f_zv);

    TIM_TimeBaseStructure.TIM_ClockDivision = 0;

    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    /* 初始化定时器结构体 */

    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

    /* 输出模式pwm1 */

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

    /* 开始oc输出到对应引脚 */

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

    /* 互补输出使能,互补通道完全反方向 */

    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;

    /* 自动重载值 */

    TIM_OCInitStructure.TIM_Pulse = TIM1->ARR / 2;

    /* 输出极性,比较匹配之后输出口输出的极性 */

#ifndef INVERTED_TOP_DRIVER_INPUT

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // gpio high = top fets on

#else

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;

#endif

    /* 空闲状态 */

    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;

    /* 互补通道,输出极性,比较匹配之后输出口输出的极性 */

#ifndef INVERTED_BOTTOM_DRIVER_INPUT

    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;  // gpio high = bottom fets on

#else

    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;

#endif

    /* 互补通道空闲状态 */

    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;

    /* 初始化定时器通道 */

    TIM_OC1Init(TIM1, &TIM_OCInitStructure);

    TIM_OC2Init(TIM1, &TIM_OCInitStructure);

    TIM_OC3Init(TIM1, &TIM_OCInitStructure);

    TIM_OC4Init(TIM1, &TIM_OCInitStructure);

    /* 使能预装载寄存器 */

    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);

    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);

    TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);

    /* 初始化定时器通道 */

    TIM_OC1Init(TIM8, &TIM_OCInitStructure);

    TIM_OC2Init(TIM8, &TIM_OCInitStructure);

    TIM_OC3Init(TIM8, &TIM_OCInitStructure);

    TIM_OC4Init(TIM8, &TIM_OCInitStructure);

    /* 使能预装载寄存器 */

    TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);

    TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);

    TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable);

    TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable);

    // Automatic Output enable, Break, dead time and lock configuration

    /* 运行模式下的关闭状态选择 */

    TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;

    /* 空闲模式下的关闭状态选择 */

    TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;

    /* 作用: 止意外的修改.桥上的意外信号可能因起全桥短路要烧芯片的.

    锁定级别配置,锁定关闭,寄存器无保护 */

    TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;

    /* 死区作用: 避免关闭前一个设备和打开后一个设备时因为开关速度的问题出现同时开启状态而增加负荷的情况,避免mos同时打开造成短路损坏

    配置死区发生器,定义死区持续时间,可选设置范围为0x00xFF */

    TIM_BDTRInitStructure.TIM_DeadTime =  conf_general_calculate_deadtime(HW_DEAD_TIME_NSEC, SYSTEM_CORE_CLOCK);

    /* 自动输出使能 */

    TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;

#ifdef HW_USE_BRK

    /* 用于快速硬件保护 软件将捕获BRK标志来报告故障代码*/

    // Enable BRK function. Hardware will asynchronously stop any PWM activity upon an

    // external fault signal. PWM outputs remain disabled until MCU is reset.

    // software will catch the BRK flag to report the fault code

    TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;

    TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;

#else

    /* 断路使能 */

    TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;

    /* 断路极性 */

    TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;

#endif

    /* 使能配置 */

    TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

    /* 开启互补通道输出 */

    TIM_CCPreloadControl(TIM1, ENABLE);

    /* 允许或禁止在定时器工作时向ARR的缓冲器中写入新值,以便在更新事件发生时载入覆盖以前的值 */

    TIM_ARRPreloadConfig(TIM1, ENABLE);

    /* 初始化结构体,使能定时器配置 */

    TIM_BDTRConfig(TIM8, &TIM_BDTRInitStructure);

    TIM_CCPreloadControl(TIM8, ENABLE);

    TIM_ARRPreloadConfig(TIM8, ENABLE);

    /* 初始化定时器2时钟 */

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    /* 分频 */

    TIM_TimeBaseStructure.TIM_Prescaler = 0;

    /* 计数模式 */

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    /* 定时器周期 */

    TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

    /* 用于死区或者滤波分频 */

    TIM_TimeBaseStructure.TIM_ClockDivision = 0;

    /* 重载值 */

    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    /* 定时器模式 */

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

    /* 互补通道 */

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

    /* 占空比 */

    TIM_OCInitStructure.TIM_Pulse = 250;

    /* 设置极性 */

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    /* 反向设置极性 */

    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;

    /* 设置空闲极性 */

    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;

    /* 设置反向空闲极性 */

    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;

    /* 设置初始化三个通道 */

    TIM_OC1Init(TIM2, &TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);

    TIM_OC2Init(TIM2, &TIM_OCInitStructure);

    TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);

    TIM_OC3Init(TIM2, &TIM_OCInitStructure);

    TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM2, ENABLE);

    TIM_CCPreloadControl(TIM2, ENABLE);

    // PWM outputs have to be enabled in order to trigger ADC on CCx

    TIM_CtrlPWMOutputs(TIM2, ENABLE);

#if defined HW_HAS_DUAL_MOTORS || defined HW_HAS_DUAL_PARALLEL

    // See: STM32F4 Timer Internal Trigger Connection - IAmAProgrammer - 博客园

    TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Enable);

    /* 主从模式 */

    TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);

    /* 选择输入触发源定时器1 */

    TIM_SelectInputTrigger(TIM8, TIM_TS_ITR0);

    /* 触发 */

    TIM_SelectSlaveMode(TIM8, TIM_SlaveMode_Trigger);

    TIM_SelectOutputTrigger(TIM8, TIM_TRGOSource_Enable);

    /* 更新输出触发 */

    TIM_SelectOutputTrigger(TIM8, TIM_TRGOSource_Update);

    /* 选择定时器8触发 */

    TIM_SelectInputTrigger(TIM2, TIM_TS_ITR1);

    /* 复位 */

    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

#else

   

    /*  选择定时器1成为更新信号

        每次计时器一更新那么TRGO这个信号就会变为有效信号、就能被其他需要这个信号的外设所识别,如果不指定触发源的话就是一个无效信号气的外设无法识别 */

    TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);

    TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);

    /* 定时器1触发定时器2 */

    TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);

    /* 只要遇到上升沿,定时器2就会计数清零 */

    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

#endif

#ifdef HW_HAS_DUAL_MOTORS

    TIM8->CNT = TIM1->ARR;

#else

    TIM8->CNT = 0;

#endif

    TIM1->CNT = 0;

    /* 使能定时器 */

    TIM_Cmd(TIM1, ENABLE);

    TIM_Cmd(TIM2, ENABLE);

    // Prevent all low side FETs from switching on

    stop_pwm_hw((motor_all_state_t*)&m_motor_1);

#ifdef HW_HAS_DUAL_MOTORS

    stop_pwm_hw((motor_all_state_t*)&m_motor_2);

#endif

    /* 输出pwm  */

    TIM_CtrlPWMOutputs(TIM1, ENABLE);

    TIM_CtrlPWMOutputs(TIM8, ENABLE);

    TIMER_UPDATE_SAMP(MCPWM_FOC_CURRENT_SAMP_OFFSET);

    // Enable CC2 interrupt, which will be fired in V0 and V7

    TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);

    utils_sys_unlock_cnt();

    /* 开启定时器2中断 */

    nvicEnableVector(TIM2_IRQn, 6);

}

相关文章:

  • 网新中英企业网站管理系统/购物网站页面设计
  • 如何将公司网站做的更好看/聊城疫情最新消息
  • 那些做软件的网站/今日国内新闻头条大事
  • 制作照片视频的软件/seo工具查询
  • 松滋市住房和城乡建设局网站/腾讯企点官网下载
  • 做房产应看的网站/如何搭建一个自己的网站
  • Hibernate-Validator(数据校验框架)
  • Android自定义ViewGroup的布局,往往都是从流式布局开始
  • Python中转义字符是个啥
  • USB TO SPI(上海同旺电子)调试器调试MCP6S92
  • 基于Spring cloud + vue 的前后端分离的社团管理系统,数据库采用MYSQL,前端使用 VUE + element
  • CMake-官方教程(2)-添加库-Adding a Library
  • 圣诞 HTML 代码汇总
  • jQuery 查找方法
  • [Java实战]Squaretest单元测试生成利器...一天生成所有简单单元测试...[新手开箱可用]
  • SAP UI5 Smart Table 和 Smart Filter Bar 的联合使用方法介绍试读版
  • tensorflow 基本概念和基本操作
  • 基于Python+Echarts+Pandas 搭建一套图书分析大屏展示系统(附源码)