【发布时间】:2018-06-25 11:26:32
【问题描述】:
我是嵌入式新手,遇到了一点小问题。 我认为问题出在我的代码上。但是我已经检查了几十次了,我找不到故障。
我有一个 Timer0,我可以用 16 位编程(最多可以数 65536)。有一个寄存器位 TMR0L 和 TMR0H 在每个时钟沿或时钟信号的倍数处递增。我希望它每 0.00001 秒递增一次。
根据我的数据表,我设置了以下设置:
OSCFRQ = 0x02; //--- HFFRQ 4_MHz
T0CON0 = 10010000; //--- Module Enabled; Timer is 16bits; 1:1 postscaler
T0CON1 = 01010101; //--- Fosc/4; 1:32 prescaler
我的数学并不出众,但我当然可以做基本的算术。 我的时钟是 4Mhz。我使用时钟/4 作为 Timer0 的输入。所以这给出了1MHz的频率。 1000000/32 = 31250Hz,每次计数为 0.000032 秒。一毫秒(0.001/0.000032 = 31.25counts),所以为了得到一毫秒,我必须用这些参数计算大约 31 次。对吧?
//Delay function that can delay from 1 milisecond to 2000 miliseconds.
//Uses timer0.
void countDelay(int ms_delay)
{
//unsigned int oscFreq = ((1<<(00001111&OSCFRQ))*1000000)/4;
//unsigned int Prescaler = (1<<(00001111&T0CON1));
unsigned int oscFreq = 4000000;
unsigned int Prescaler = 32;
float countTime = (Prescaler/(oscFreq/4));
int countsNum = (int)(((ms_delay/1000)/countTime));
char endCountDelay = 0;
TMR0L = 0x00;
TMR0H = 0x00;
unsigned int Time16 = 0x0000;
while(endCountDelay == 0)//PORBLEM
{
Time16 = 0;
Time16 |= TMR0L;
Time16 |= (TMR0H<<8);
if (Time16 >= countsNum)
{
endCountDelay = 1;
}
}
}
我的主要代码就是下面的代码。它使 LED 闪烁。我想让它每秒都变黑。所以 31250 很重要。这不是问题,因为我检查了另一个函数,计时器真的是 16 位。它的计数高达 65k。
void main(void)
{
// Initialize the device
SYSTEM_Initialize();
while (1)
{
countDelay(1000);
LATA0 = 0;
countDelay(1000);
LATA0 = 1;
}
}
使用该代码,我可以看到一个 LED 始终亮着。 用示波器,我检查信号:141.76Hz 我们应该看到 0.5Hz,周期为 2 秒,即 0.5Hz。
所以,简而言之,我们的 283 倍太高了。接近 2^8 的 256。所以我相信这是我的代码中的一个错误。也许我的延迟功能中有什么东西?有人有想法吗?
EDIT#1:我进行了其他测试。我改变了我的变量的值。不改变结果。信号保持 141Hz,+/- 10Hz。即使x16的时钟速度。
更改预标量值几乎相同。这次信号保持在 141.76Hz。
EDIT#2:我在我的pickit 中使用了调试器。看起来像我这样做的时候。
int countsNum = (((ms_delay/1000)/(Prescaler/(oscFreq/4))));
结果为 0。知道为什么吗?它不应该。
EDIT#3:当我使用 long 类型时,它给了我相当多的 2.51 亿。
Edit#4:验证时钟速度。没关系。 但是,这种计算,即使所有的整数都不起作用。 countsNum 的答案是 74,但应该是 15。
unsigned int ms_delay = 500;
unsigned long oscFreq = 4000000;
unsigned long Prescaler = 32768;
unsigned int countsNum = ((ms_delay)/((Prescaler)/(oscFreq/4000)));
【问题讨论】:
标签: timer embedded cpu-registers