智能车制作

标题: 载波调制控制舵机(含源代码) [打印本页]

作者: 1325536866    时间: 2016-10-27 09:35
标题: 载波调制控制舵机(含源代码)
本帖最后由 1325536866 于 2016-10-27 09:39 编辑

做比赛也基本没有发过帖子,今天来发一个载波调制控制舵机的代码,以前北科经常说使用载波调制来控制舵机,在实验室的时候也听小伙伴们说过,不过那个时候也懒得研究,今天给大家贡献一个关于载波调制控制舵机的代码。如果有啥问题就加群去问里面的人,就别问我喽。




/*********************************************************************************************************************
* COPYRIGHT NOTICE
* Copyright (c) 2016,逐飞科技
* All rights reserved.
* 技术讨论QQ群:179029047
*
* 以下所有内容版权均属逐飞科技所有,未经允许不得用于商业用途,
* 欢迎各位使用并传播本程序,修改内容时必须保留逐飞科技的版权声明。
*
* @file                       MK60DN10_cmt.c
* @BRIEF                      CMT_PWM函数库
* @company                           成都逐飞科技有限公司
* @version                    v1.0
* @software                 IAR 7.2 or MDK 5.17
* @target core                MK60DN512VLL10
* @Taobao                   https://seekfree.taobao.com/
* @date                       2016-02-25
********************************************************************************************************************/




#include "MK60DN10_cmt.h"


//-------------------------------------------------------------------------------------------------------------------
//  @brief      CMT_PWM初始化
//  @param      freq         设置PWM的频率
//  @param      duty         设置PWM的占空比
//  @return     void
//  @since      v1.0
//  Sample usage:               cmt_pwm_init(50,50);    // 频率50HZ,占空比为百分之(50/CMT_PRECISON *100);
//-------------------------------------------------------------------------------------------------------------------
void cmt_pwm_init(uint16 freq, uint16 duty)
{
    uint32 temp_clk;
    uint32 temp_num, temp_high_num, temp_low_num;
    uint32 temp_div;

    //使能时钟
    SIM->SCGC4 |= SIM_SCGC4_CMT_MASK;
    //设置复用功能为CMT功能
    port_init (D7, ALT2 | PULLUP );
    //使能输出
    CMT->OC |= CMT_OC_IROPEN_MASK;

    //由于CMT模块会固定八分频,因此这里计算,便于后面使用
    temp_clk = bus_clk_mhz*1000*1000/8;

    //计算最佳分频
    temp_div = temp_clk/freq;
    temp_div = temp_div>>16;
    if(temp_div>0x0f)   temp_div = 0x0f;

    //设置分频
    CMT->PPS = CMT_PPS_PPSDIV(temp_div);

    //计算一个周期需要计数的次数
    temp_num = temp_clk/(temp_div+1)/freq;

    //计算高低电平的计数次数
    temp_low_num = (temp_num*(CMT_PRECISON-duty)/CMT_PRECISON - 1);
    temp_high_num = (temp_num*(duty)/CMT_PRECISON);

    //设置低电平时间
    CMT->CMD1 = temp_low_num >> 8;
    CMT->CMD2 = (uint8)temp_low_num;

    //设置高电平时间
    CMT->CMD3 = temp_high_num >> 8;
    CMT->CMD4 = (uint8)temp_high_num;

    //设置模式且使能CMT模块   
    CMT->MSC = CMT_MSC_BASE_MASK | CMT_MSC_MCGEN_MASK;
}


//-------------------------------------------------------------------------------------------------------------------
//  @brief      CMT_PWM占空比设置
//  @param      duty         设置PWM的占空比
//  @return     void
//  @since      v1.0
//  Sample usage:               cmt_pwm_duty(50);    //占空比为百分之(50/CMT_PRECISON *100);
//-------------------------------------------------------------------------------------------------------------------
void cmt_pwm_duty(uint16 duty)
{
    uint32 temp_num, temp_high_num, temp_low_num;
    uint32 temp_data;

    //获取低电平次数
    temp_data = CMT->CMD1;
    temp_low_num = (temp_data << 8) | CMT->CMD1;
    //固定加一
    temp_low_num++;   

    //获取高电平次数
    temp_data = CMT->CMD3;
    temp_high_num = (temp_data << 8) | CMT->CMD4;


    //计算PWM周期
    temp_num = temp_high_num + temp_low_num;

    //计算高低电平的计数次数
    temp_low_num = (temp_num*(CMT_PRECISON-duty)/CMT_PRECISON - 1);
    temp_high_num = (temp_num*(duty)/CMT_PRECISON);

    //设置低电平时间
    CMT->CMD1 = temp_low_num >> 8;
    CMT->CMD2 = (uint8)temp_low_num;

    //设置高电平时间
    CMT->CMD3 = temp_high_num >> 8;
    CMT->CMD4 = (uint8)temp_high_num;

}


//-------------------------------------------------------------------------------------------------------------------
//  @brief      CMT_PWM频率设置
//  @param      freq         设置PWM的频率
//  @param      duty         设置PWM的占空比
//  @return     void
//  @since      v1.0
//  Sample usage:               cmt_pwm_init(50,50);    // 频率50HZ,占空比为百分之(50/CMT_PRECISON *100);
//-------------------------------------------------------------------------------------------------------------------
void cmt_pwm_freq(uint16 freq, uint16 duty)
{
    uint32 temp_clk;
    uint32 temp_num, temp_high_num, temp_low_num;
    uint32 temp_div;


    //由于CMT模块会固定八分频,因此这里计算,便于后面使用
    temp_clk = bus_clk_mhz*1000*1000/8;

    //计算最佳分频
    temp_div = temp_clk/freq;
    temp_div = temp_div>>16;
    if(temp_div>0x0f)   temp_div = 0x0f;

    //设置分频
    CMT->PPS = CMT_PPS_PPSDIV(temp_div);


    //计算一个周期需要计数的次数
    temp_num = temp_clk/(temp_div+1)/freq;

    //计算高低电平的计数次数
    temp_low_num = (temp_num*(CMT_PRECISON-duty)/CMT_PRECISON - 1);
    temp_high_num = (temp_num*(duty)/CMT_PRECISON);

    //设置低电平时间
    CMT->CMD1 = temp_low_num >> 8;
    CMT->CMD2 = (uint8)temp_low_num;

    //设置高电平时间
    CMT->CMD3 = temp_high_num >> 8;
    CMT->CMD4 = (uint8)temp_high_num;
}

















作者: advance    时间: 2016-10-27 22:45
厉害了我的哥,然而看不懂。
作者: fbhsy    时间: 2016-10-28 13:20
:victory::victory:
作者: sangchaochun    时间: 2016-10-30 15:15
fbhsy 发表于 2016-10-28 13:20

就这样把你们的成果发出来了,唉

作者: fbhsy    时间: 2016-10-31 09:12
sangchaochun 发表于 2016-10-30 15:15
就这样把你们的成果发出来了,唉

我们本来也是开源的哈





欢迎光临 智能车制作 (http://dns.znczz.com/) Powered by Discuz! X3.2