Holtek单片机HT66F019定时功能与PWM配置详解
前言:
CTM:工作模式:比较匹配输出、定时 / 事件计数器和 PWM 输出模式;简易型 TM 也由一个外部输入脚控制并驱动一个外部输出脚。
STM工作模式:比较匹配输出、定时 / 事件计数器、捕捉输入、 单脉冲输出和 PWM 输出模式。标准型 TM 由两个外部输入脚控制并驱动一个 外部输出脚。
先来看下配置步骤:
一、CTM简易定时器===PWM配置
(1)寄存器:
一对只读寄存器用来存放 16位计数器的值:CTMDH 、CTMDL(无需设置)
一对读 / 写寄存器存放 16 位 CCRA 的值:CTMAH 、CTMAL (设置占空比)
CTMRP 寄存器用于存放 8 位 CCRP 的值:CTMRP(存放周期值)
剩下两个控制寄存器:CTMC0 、CTMC1
(2)配置步骤:
①配置:CTMC0 、CTMC1
CTMC0:配置时钟频率
CTMC1:配置PWM模式,低电平有效,同相,CCRA作为占空比,CCRP:周期
②使能对应CTM输出脚(CTP)
③设置占空比:CTMAH 、CTMAL (设置占空比)
④设置PWM周期计数:CTMRP(存放周期值)
⑤打开CTM开关:CTMC0 : bit3 CTON
(3)源代码
//此处系统时钟频率:16Mhz
_ctmc0 = 0x10; // 0 001 0 xxx 001:fsys
_ctmc1 = 0xa0; // 10 10 0 0 0 0
_t2cp = 1; // 使能 CTP
_ctmal = 0x70; //
_ctmah = 0x0D; // 占空比16*215=3440=0x0D70
_ctmrp = 62; // 周期为16000/(62*256)=1.008khZ
(4)解说:
①CTMC0 时钟配置
_ctmc0 = 0x10;//0100 0000
_ctmc1 = 0xa0; // 10 10 0 0 0 0
② 使能对应CTM输出脚(CTP)==对应寄存器TMPC –>Bit 2 T2CP: CTP 引脚使能位
_t2cp = 1;
该引脚做复用功能:定时器pwm波输出口(_pbc3 = 0; //pwm out)
③设置占空比:CTMAH 、CTMAL (设置占空比)
④设置PWM周期计数:CTMRP(存放周期值)
_ctmal = 0x70;
_ctmah = 0x0D;
_ctmrp = 62;
计算方法如下:CCRA: 0x0D70=3440;CCRP = 62;fsys=16MHz(前面时钟选择CTMC0);
PWM输出频率 = 16M / (62 * 256) = 1.008kHz –>周期=0.996ms≈1ms
duty = 3440 / (62 * 256) =21.6%
⑤打开CTM开关:CTMC0 : bit3 CTON
开始输出PWM波
void pwm_on(void)
{
_cton = 1;//CTM 总开关
}
总结:pwm波形讲解
程序这里并没有打开PWM或者CTM相关的中断;如果有需要的话,可以查询比较器A匹配中断的标志位(CCRA溢出中断标志位)或者CCRP溢出中断标志位。
我们这里可以看一看输出波形相关寄存器位相关变化
过程:①首先CTON=1后,CTPAU=0处在运行状态,计数器开始计数。
②当计数器计数到CCRA值时,比较器A匹配成功,中断标志CTMAF=1(开关中断与标志位无关)
③当计数器计数到CCRP值时,比较器P匹配成功,中断标志CTMPF=1,并且计数器自动清0;
④CTPAU=1;暂停时,计数器的值保持,直到CTPAU=0;运行;继续之前的计数
⑤CTON=0;关闭计数器时;计数器里面的值保持不变;直到CTON=1;计数器的值清0,重新开始计数(即CTON经过一次上升沿变化后,计数器清0)
二、STM标准定时器===定时功能
(1)寄存器:
一对只读寄存器用来存放 16 位计 数器的值:STMDH STMDL
一对读 / 写寄存器存放
16
位 CCRA 的值:STMAH STMAL
STMRP 寄存器存放
8
位 CCRP 的值。
两个控制寄存器:
STMC0 STMC1
(2)代码:
void stm_Init(void) // 25ms
{
//内部低速时钟fsub = 32kHz
_stmc0 = 0x40; // bit6-4 100:fSUB=32khz
//11:定时/计数器模式 1:(选择 STM 计数器清零条件位)STM 比较器 A 匹配
_stmc1 = 0xc1; // 11 00 0 0 0 1
_stmal = 0x20;//计数值
_stmah = 0x03;
_stmaf = 0; // MFI0 清除中断标志
_stmae = 1;//STMAE:STM 比较器 A 匹配中断使能
// INTC0寄存器;
_mf0f = 0; //bit6->MF0F:多功能中断 0 请求标志位
_mf0e = 1; //bit3->MF0E:多功能中断使能
_emi = 1;//打开总中断
_ston = 1; // on
}
void __attribute((interrupt(0x0c))) stm_isr(void)
{
_emi = 0; //关总中断
_stmaf = 0; //清除TM2比较器A中断标志位
led_25ms++; //25ms加一次,供其他函数查询
_emi=1; //开总中断
}
(3)步骤:
①配置控制寄存器STMC0/STMC1:
//这里时钟选择的内部低速时钟 32kHz
_stmc0 = 0x40;//配置定时器时钟(bit 6~4),其余位不用管
_stmc1 = 0xc1;//配置定时器模式(Bit 7~6),1100 0001
//以及选择溢出清零计数器方式(Bit 0 STCCLR=1);其余位不用管
STMC1只需要设置三个位即可;其余位是设置PWM和比较模式的;未使用其复用功能的输出脚
②配置定时器初值CCRA:STMAH/STMAL(定时25ms)
这里配置的计数值=800;时钟频率=32khz
===>计数一个周期的时间=时钟周期=1/32000=31.25us;
===>此时需要定时25ms,则需要计数的次数=CCRA=25000/31.25=800
===>换算成16进制,分别赋值给
STMAH = 800/256 = 3—->0x03 取整运算
STMAL = 800%256 = 32—>0x32 取余运算
_stmal = 0x20; // 0x0320 = 800
_stmah = 0x03; //800 / 32
③配置定时溢出中断,通过MFI0寄存器:bit5 STMAF:STM 比较器 A 匹配中断请求标志位
此时用到了中断计时功能,每25ms中断一次;
打开中断前,需要清除对应标志位STMAF = 0;
中断使能
//bit1 STMAE:STM 比较器 A 匹配中断控制位
_stmaf = 0; // MFI0 清除中断标志
_stmae = 1; // 中断使能

④配置寄存器 INTC0:bit6 MF0F:多功能中断 0 请求标志位
// INTC0寄存器;
_mf0f = 0; //bit6->MF0F:多功能中断 0 请求标志位
_mf0e = 1; //bit3->MF0E:多功能中断使能
_emi = 1;//打开中断总开关
INTC0寄存器中:中断控制寄存器(我理解的是控制那些有关中断的寄存器的开关:如MFI0)
我们可以看一下它整个中断需要置位那些寄存器位,最终才能进入中断服务程序ISR
⑤打开STM定时器: _ston = 1;
⑥中断服务函数:
void __attribute((interrupt(0x0c))) stm_isr(void)
{
_emi = 0; //关总中断
_stmaf = 0; //清除TM2比较器A中断标志位
led_25ms++; //25ms加一次,供其他函数查询
_emi=1; //开总中断
}
三、周期型PTM
寄存器:
一对只读寄存器用来存放
10
位计 数器的值,两对读 /
写寄存器存放
10
位
CCRA
和
CCRP
的值。剩下两个控制寄 存器用来设置不同的操作和控制模式。
总结:
每个定时器的定时功能和pwm功能配置大同小异,按照步骤配置即可
作者:yingqingling