我正在使用MC9S08LH64微控制器的定时器模块来生成内部定时器以进行同步。 总线时钟为4.3 MHz,模数设置为4309(TPM1MODH和TPM1MODL),我预计脉冲每1.25 ms,但结果大约是每3.75ms。 我在这里缺少任何设置吗?非常感谢你
/*
* TPM1SC: pg 358
bit
7 TOF need to check for this flag
6 not used since no interrupt being used
5 1 not used
4 0 selecting bus clock
3 1
2 0 not dividing clock down
1 0
0 0
*/
TPM1SC = 0x08;
*更新: 我刚刚意识到改变TPM1MOD对结果脉冲宽度没有影响。 TPM1SC是我用来设置模块的唯一寄存器。我需要为此设置其他寄存器吗?
以下是设置计时器的源代码:
//to set up the modulo register:
void set_base_pulse(float time_ms){
int modulo_value;
modulo_value = (int) time_ms*1000/233;
TPM1MODH = modulo_value >>8;
TPM1MODL = modulo_value;
}
为了产生脉冲,我检查了TOF标志,每40次标志熄灭,我切换输出:
for(counter = 0; counter<40; counter++
{
while(!TPM1SC_TOF){}
if(counter ==40) output~=output;
}
答案 0 :(得分:1)
关于代码的一些评论:
void set_base_pulse(float time_ms){
在8位微控制器上使用浮点数通常是一个非常糟糕的主意。生成的代码效率极低。在这种情况下,我非常怀疑你需要它们。
(int)time_ms * 1000/233;
魔数233是多少?首先将它定义为有意义的事物#define BUSCLOCK_ns 233
或类似事物。此外,你的逻辑是有缺陷的:1.25 * 1000/233 = 5.36。将此类型转换为int,然后得到5.这就完全不同了。
for(counter = 0; counter&lt; 40; counter ++
你为什么要在循环中消磨时间?你不能把计数放在ISR里吗? TOF标志可以给你一个中断。或者更好的是,在硬件中使用内置的输出比较/ PWM功能。
if(counter == 40)output~ = output;
这不是有效的C,不会编译。你可能意味着output = ~output
。请发布您编译的真实代码,而不是在航班上输入内容。
答案 1 :(得分:0)
我不能按照你的预期1,25ms,因为1 / 4.3E6MHz = 233ns BUSCLK
如果将TPM1MOD设置为4309,则应获得233ns * 4309 = 1,002ms的周期。
但是如果你将TPM1MOD设置为0x4309(十六进制0x4309 = dez 17161),那么你应该得到一个233ns * 17161 = 3,99ms的周期。
编辑:编辑后,显示代码
是的,它是......不常见的
恕我直言,纯计时器设置会起作用,也许它有点不准确。
但是创建输出信号的代码有点奇怪。
尝试简单的事情。
while (1)
{
output = TPM1SC_TOF;
}
或创建方形信号
while (1)
{
if ( TPM1SC_TOF )
output = !output;
}