📄 hal_ftm.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 + -