⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal_ftm.c

📁 Kinetis_K60开源底层驱动开发包(20120328)
💻 C
字号:
/*
 * 测试硬件平台:LPLD_K60 Card
 * 版权所有:北京拉普兰德电子技术有限公司
 * 网络销售:http://laplenden.taobao.com
 * 公司门户:http://www.lpld.cn
 *
 * 文件名: HAL_FTM.h
 * 用途: FlexTimer底层模块相关函数
 * 最后修改日期: 20120216
 *
 * 开发者使用协议:
 *  本代码面向所有使用者开放源代码,开发者可以随意修改源代码。但本段及以上注释应
 *  予以保留,不得更改或删除原版权所有者姓名。二次开发者可以加注二次版权所有者,
 *  但应在遵守此协议的基础上,开放源代码、不得出售代码本身。
 */
#include "common.h"
#include "HAL_FTM.h"

//引用总线时钟频率,该值在sysinit.c文件中取得
extern int periph_clk_khz;

//全局变量定义
uint32_t LPLD_FTM0_MOD;
uint32_t LPLD_FTM1_MOD;
uint32_t LPLD_FTM2_MOD;

/*
 * LPLD_FTM0_PWM_Init
 * FTM0模块PWM功能初始化函数
 * 
 * 参数:
 *    freq--期望频率,单位Hz
 *
 * 输出:
 *    0--配置错误
 *    1--配置成功
 */
uint8_t LPLD_FTM0_PWM_Init(uint32_t freq)
{
  uint32_t bus_clk_hz;
  uint32_t mod;
  uint8_t ps;

  bus_clk_hz = periph_clk_khz*1000;
  
  if(freq>bus_clk_hz) return 0;
  
  if((mod=bus_clk_hz/(freq*128)) < 0xFFFFu)
  {
    ps = 7;
    LPLD_FTM0_MOD = mod;
    if((mod=bus_clk_hz/(freq*64)) < 0xFFFFu)
    {
      ps = 6;   
      LPLD_FTM0_MOD = mod;  
      if((mod=bus_clk_hz/(freq*32)) < 0xFFFFu)
      {
        ps = 5; 
        LPLD_FTM0_MOD = mod;  
        if((mod=bus_clk_hz/(freq*16)) < 0xFFFFu)
        {
          ps = 4;  
          LPLD_FTM0_MOD = mod;    
          if((mod=bus_clk_hz/(freq*8)) < 0xFFFFu)
          {
            ps = 3;
            LPLD_FTM0_MOD = mod;
            if((mod=bus_clk_hz/(freq*4)) < 0xFFFFu)
            {
              ps = 2;
              LPLD_FTM0_MOD = mod;
              if((mod=bus_clk_hz/(freq*2)) < 0xFFFFu)
              {
                ps = 1;
                LPLD_FTM0_MOD = mod;
                if((mod=bus_clk_hz/(freq*1)) < 0xFFFFu)
                {
                  ps = 0;
                  LPLD_FTM0_MOD = mod;
                }
              }
            }
          }
        }  
      }
    }
  }
  else
  {
    return 0;
  }
  
  // 使能FTM时钟模块
  SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK;
  
  // 配置FTM控制寄存器
  // 禁用中断, 加计数模式, 时钟源:System clock(Bus Clk), 分频系数:8
  // 假设SysClk = 50MHz, SC_PS=3, FTM Clk = 50MHz/2^3 = 6.25MHz
  FTM0_SC = FTM_SC_CLKS(1)|FTM_SC_PS(ps);
  
  // 设置PWM周期及占空比
  //    PWM周期 = (MOD-CNTIN+1)*FTM时钟周期 :
  // 配置FTM计数初始值
  FTM0_CNT = 0;
  FTM0_CNTIN = 0;
  // 配置FTM计数MOD值
  FTM0_MOD = LPLD_FTM0_MOD;
  
  return 1;
}

/*
 * LPLD_FTM0_PWM_Open
 * FTM0模块PWM输出通道及占空比配置
 * 
 * 说明: 其他GPIO也可配置为FTM0输出,本函数只考虑PTC和PTD,如需改变请自行修改 
 * 
 * 参数:
 *    channel - PWM输出通道
 *      |__0--PTC1
 *      |__1--PTC2
 *      |__2--PTC3
 *      |__3--PTC4
 *      |__4--PTD4
 *      |__5--PTD5
 *      |__6--PTD6
 *      |__7--PTD7
 *    duty - PWM输出占空比
 *      |__0~10000--占空比0.00%~100.00%
 *
 * 输出:
 *    0--配置错误
 *    1--配置成功
 */
uint8_t LPLD_FTM0_PWM_Open(uint8_t channel, uint32_t duty)
{
  uint32_t cv;
  volatile uint32_t mod;
  
  if(duty>10000) return 0;
  //占空比 = (CnV-CNTIN)/(MOD-CNTIN+1)
  mod = LPLD_FTM0_MOD;
  cv = (duty*(mod-0+1)+0)/10000;
  
  //选择并开启通道
  switch(channel)
  {
    case 0:
    case 1:
    case 2:
    case 3:
      SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK;
      PORT_PCR_REG(PORTC_BASE_PTR, channel+1) = PORT_PCR_MUX(4);
      break;
    case 4:
    case 5:
    case 6:
    case 7:
      SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;
      PORT_PCR_REG(PORTD_BASE_PTR, channel) = PORT_PCR_MUX(4);
      break;
    default:
       return 0;
  }  
  
  // 配置FTM通道控制寄存器 
  // 通道模式 MSB:MSA-1X, 通道边缘选择 ELSB:ELSA-10
  FTM_CnSC_REG(FTM0_BASE_PTR, channel) = FTM_CnSC_MSB_MASK|FTM_CnSC_ELSB_MASK;
  // 配置FTM通道值
  FTM_CnV_REG(FTM0_BASE_PTR, channel) = cv;
  
  return 1;
}

/*
 * LPLD_FTM0_PWM_ChangeDuty
 * 改变FTM0模块PWM输出通道占空比
 *
 * 参数:
 *    channel - PWM输出通道
 *      |__0--PTC1
 *      |__1--PTC2
 *      |__2--PTC3
 *      |__3--PTC4
 *      |__4--PTD4
 *      |__5--PTD5
 *      |__6--PTD6
 *      |__7--PTD7
 *    duty - PWM输出占空比
 *      |__0~10000--占空比0.00%~100.00%
 *
 * 输出:
 *    0--配置错误
 *    1--配置成功
 */
uint8_t LPLD_FTM0_PWM_ChangeDuty(uint8_t channel, uint32_t duty)
{
  uint32_t cv;
  volatile uint32_t mod;
  
  if(duty>10000) return 0;
  //占空比 = (CnV-CNTIN)/(MOD-CNTIN+1)
  mod = LPLD_FTM0_MOD;
  cv = (duty*(mod-0+1)+0)/10000;
 
  // 配置FTM通道值
  FTM_CnV_REG(FTM0_BASE_PTR, channel) = cv;
  
  return 1;
}

/*
 * LPLD_FTM1_PWM_Init
 * FTM0模块PWM功能初始化函数
 * 
 * 参数:
 *    freq--期望频率,单位Hz
 *
 * 输出:
 *    0--配置错误
 *    1--配置成功
 */
uint8_t LPLD_FTM1_PWM_Init(uint32_t freq)
{
  uint32_t bus_clk_hz;
  uint32_t mod;
  uint8_t ps;

  bus_clk_hz = periph_clk_khz*1000;
  
  if(freq>bus_clk_hz) return 0;
  
  if((mod=bus_clk_hz/(freq*128)) < 0xFFFFu)
  {
    ps = 7;
    LPLD_FTM1_MOD = mod;
    if((mod=bus_clk_hz/(freq*64)) < 0xFFFFu)
    {
      ps = 6;   
      LPLD_FTM1_MOD = mod;  
      if((mod=bus_clk_hz/(freq*32)) < 0xFFFFu)
      {
        ps = 5; 
        LPLD_FTM1_MOD = mod;  
        if((mod=bus_clk_hz/(freq*16)) < 0xFFFFu)
        {
          ps = 4;  
          LPLD_FTM1_MOD = mod;    
          if((mod=bus_clk_hz/(freq*8)) < 0xFFFFu)
          {
            ps = 3;
            LPLD_FTM1_MOD = mod;
            if((mod=bus_clk_hz/(freq*4)) < 0xFFFFu)
            {
              ps = 2;
              LPLD_FTM1_MOD = mod;
              if((mod=bus_clk_hz/(freq*2)) < 0xFFFFu)
              {
                ps = 1;
                LPLD_FTM1_MOD = mod;
                if((mod=bus_clk_hz/(freq*1)) < 0xFFFFu)
                {
                  ps = 0;
                  LPLD_FTM1_MOD = mod;
                }
              }
            }
          }
        }  
      }
    }
  }
  else
  {
    return 0;
  }
  
  // 使能FTM时钟模块
  SIM_SCGC6 |= SIM_SCGC6_FTM1_MASK;
  
  // 配置FTM控制寄存器
  // 禁用中断, 加计数模式, 时钟源:System clock(Bus Clk), 分频系数:8
  // 假设SysClk = 50MHz, SC_PS=3, FTM Clk = 50MHz/2^3 = 6.25MHz
  FTM1_SC = FTM_SC_CLKS(1)|FTM_SC_PS(ps);
  
  // 设置PWM周期及占空比
  //    PWM周期 = (MOD-CNTIN+1)*FTM时钟周期 :
  // 配置FTM计数初始值
  FTM1_CNT = 0;
  FTM1_CNTIN = 0;
  // 配置FTM计数MOD值
  FTM1_MOD = LPLD_FTM1_MOD;
  
  return 1;
}

/*
 * LPLD_FTM1_PWM_Open
 * FTM1模块PWM输出通道及占空比配置
 *  
 * 说明: 其他GPIO也可配置为FTM1输出,本函数只考虑PTA,如需改变请自行修改 
 * 
 * 参数:
 *    channel - PWM输出通道
 *      |__0--PTA8
 *      |__1--PTA9
 *    duty - PWM输出占空比
 *      |__0~10000--占空比0.00%~100.00%
 *
 * 输出:
 *    0--配置错误
 *    1--配置成功
 */
uint8_t LPLD_FTM1_PWM_Open(uint8_t channel, uint32_t duty)
{
  uint32_t cv;
  volatile uint32_t mod;
  
  if(duty>10000) return 0;
  //占空比 = (CnV-CNTIN)/(MOD-CNTIN+1)
  mod = LPLD_FTM1_MOD;
  cv = (duty*(mod-0+1)+0)/10000;
  
  //选择并开启通道
  switch(channel)
  {
    case 0:
    case 1:
      SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;
      PORT_PCR_REG(PORTA_BASE_PTR, channel+8) = PORT_PCR_MUX(3);
      break;
    default:
       return 0;
  }  
  
  // 配置FTM通道控制寄存器 
  // 通道模式 MSB:MSA-1X, 通道边缘选择 ELSB:ELSA-10
  FTM_CnSC_REG(FTM1_BASE_PTR, channel) = FTM_CnSC_MSB_MASK|FTM_CnSC_ELSB_MASK;
  // 配置FTM通道值
  FTM_CnV_REG(FTM1_BASE_PTR, channel) = cv;
  
  return 1;
}

/*
 * LPLD_FTM1_PWM_ChangeDuty
 * 改变FTM1模块PWM输出通道占空比
 *
 * 参数:
 *    channel - PWM输出通道
 *      |__0--PTA8
 *      |__1--PTA9
 *    duty - PWM输出占空比
 *      |__0~10000--占空比0.00%~100.00%
 *
 * 输出:
 *    0--配置错误
 *    1--配置成功
 */
uint8_t LPLD_FTM1_PWM_ChangeDuty(uint8_t channel, uint32_t duty)
{
  uint32_t cv;
  volatile uint32_t mod;
  
  if(duty>10000) return 0;
  //占空比 = (CnV-CNTIN)/(MOD-CNTIN+1)
  mod = LPLD_FTM1_MOD;
  cv = (duty*(mod-0+1)+0)/10000;
 
  // 配置FTM通道值
  FTM_CnV_REG(FTM1_BASE_PTR, channel) = cv;
  
  return 1;
}


/*
 * LPLD_FTM2_PWM_Init
 * FTM0模块PWM功能初始化函数
 * 
 * 参数:
 *    freq--期望频率,单位Hz
 *
 * 输出:
 *    0--配置错误
 *    1--配置成功
 */
uint8_t LPLD_FTM2_PWM_Init(uint32_t freq)
{
  uint32_t bus_clk_hz;
  uint32_t mod;
  uint8_t ps;

  bus_clk_hz = periph_clk_khz*1000;
  
  if(freq>bus_clk_hz) return 0;
  
  if((mod=bus_clk_hz/(freq*128)) < 0xFFFFu)
  {
    ps = 7;
    LPLD_FTM2_MOD = mod;
    if((mod=bus_clk_hz/(freq*64)) < 0xFFFFu)
    {
      ps = 6;   
      LPLD_FTM2_MOD = mod;  
      if((mod=bus_clk_hz/(freq*32)) < 0xFFFFu)
      {
        ps = 5; 
        LPLD_FTM2_MOD = mod;  
        if((mod=bus_clk_hz/(freq*16)) < 0xFFFFu)
        {
          ps = 4;  
          LPLD_FTM2_MOD = mod;    
          if((mod=bus_clk_hz/(freq*8)) < 0xFFFFu)
          {
            ps = 3;
            LPLD_FTM2_MOD = mod;
            if((mod=bus_clk_hz/(freq*4)) < 0xFFFFu)
            {
              ps = 2;
              LPLD_FTM2_MOD = mod;
              if((mod=bus_clk_hz/(freq*2)) < 0xFFFFu)
              {
                ps = 1;
                LPLD_FTM2_MOD = mod;
                if((mod=bus_clk_hz/(freq*1)) < 0xFFFFu)
                {
                  ps = 0;
                  LPLD_FTM2_MOD = mod;
                }
              }
            }
          }
        }  
      }
    }
  }
  else
  {
    return 0;
  }
  
  // 使能FTM时钟模块
  SIM_SCGC3 |= SIM_SCGC3_FTM2_MASK;
  
  // 配置FTM控制寄存器
  // 禁用中断, 加计数模式, 时钟源:System clock(Bus Clk), 分频系数:8
  // 假设SysClk = 50MHz, SC_PS=3, FTM Clk = 50MHz/2^3 = 6.25MHz
  FTM2_SC = FTM_SC_CLKS(1)|FTM_SC_PS(ps);
  
  // 设置PWM周期及占空比
  //    PWM周期 = (MOD-CNTIN+1)*FTM时钟周期 :
  // 配置FTM计数初始值
  FTM2_CNT = 0;
  FTM2_CNTIN = 0;
  // 配置FTM计数MOD值
  FTM2_MOD = LPLD_FTM2_MOD;
  
  return 1;
}

/*
 * LPLD_FTM2_PWM_Open
 * FTM2模块PWM输出通道及占空比配置
 *  
 * 说明: 其他GPIO也可配置为FTM2输出,本函数只考虑PTA,如需改变请自行修改 
 * 
 * 参数:
 *    channel - PWM输出通道
 *      |__0--PTA10
 *      |__1--PTA11
 *    duty - PWM输出占空比
 *      |__0~10000--占空比0.00%~100.00%
 *
 * 输出:
 *    0--配置错误
 *    1--配置成功
 */
uint8_t LPLD_FTM2_PWM_Open(uint8_t channel, uint32_t duty)
{
  uint32_t cv;
  volatile uint32_t mod;
  
  if(duty>10000) return 0;
  //占空比 = (CnV-CNTIN)/(MOD-CNTIN+1)
  mod = LPLD_FTM2_MOD;
  cv = (duty*(mod-0+1)+0)/10000;
  
  //选择并开启通道
  switch(channel)
  {
    case 0:
    case 1:
      SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;
      PORT_PCR_REG(PORTA_BASE_PTR, channel+10) = PORT_PCR_MUX(3);
      break;
    default:
       return 0;
  }  
  
  // 配置FTM通道控制寄存器 
  // 通道模式 MSB:MSA-1X, 通道边缘选择 ELSB:ELSA-10
  FTM_CnSC_REG(FTM2_BASE_PTR, channel) = FTM_CnSC_MSB_MASK|FTM_CnSC_ELSB_MASK;
  // 配置FTM通道值
  FTM_CnV_REG(FTM2_BASE_PTR, channel) = cv;
  
  return 1;
}

/*
 * LPLD_FTM2_PWM_ChangeDuty
 * 改变FTM2模块PWM输出通道占空比
 *
 * 参数:
 *    channel - PWM输出通道
 *      |__0--PTA8
 *      |__1--PTA9
 *    duty - PWM输出占空比
 *      |__0~10000--占空比0.00%~100.00%
 *
 * 输出:
 *    0--配置错误
 *    1--配置成功
 */
uint8_t LPLD_FTM2_PWM_ChangeDuty(uint8_t channel, uint32_t duty)
{
  uint32_t cv;
  volatile uint32_t mod;
  
  if(duty>10000) return 0;
  //占空比 = (CnV-CNTIN)/(MOD-CNTIN+1)
  mod = LPLD_FTM2_MOD;
  cv = (duty*(mod-0+1)+0)/10000;
 
  // 配置FTM通道值
  FTM_CnV_REG(FTM2_BASE_PTR, channel) = cv;
  
  return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -