Я новичок во внедрении, и у меня есть небольшая проблема.Я думаю, что проблема в моем коде.Но я прошел через это десятки раз, и я не могу найти сбой.
У меня есть Timer0, который я могу запрограммировать в 16 бит (может сосчитать до 65536).Существует регистровый бит TMR0L и TMR0H, которые увеличиваются на каждом фронте тактового сигнала или кратны тактовому сигналу.Я хочу, чтобы он увеличивался, скажем, каждые 0,00001 с.
В соответствии с моим DATASHEET, я установил следующие настройки:
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.Так что это дает частоту 1 МГц.1000000/32 = 31250 Гц, что дает 0,000032 секунды на счет.Миллисекунда (0,001 / 0,000032 = 31,25 счета), поэтому, чтобы получить миллисекунды, мне пришлось бы посчитать примерно 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;
}
}
}
И мой основной код - это только код ниже.Это заставляет светодиод мигать.Я хочу сделать это блекнутым каждую секунду.Итак, 31250 пунктов.Это не проблема, потому что я проверил с другой функцией, и таймер действительно 16 бит.Считается до 65 тыс.
void main(void)
{
// Initialize the device
SYSTEM_Initialize();
while (1)
{
countDelay(1000);
LATA0 = 0;
countDelay(1000);
LATA0 = 1;
}
}
С этим кодом я вижу постоянно включенный светодиод.С помощью осциллографа я проверяю сигнал: 141,76 Гц. Мы должны были увидеть 0,5 Гц с периодом цикла 2 секунды, то есть 0,5 Гц.
Итак, вкратце, мы в 283 раза выше.Что близко к 256 из 2 ^ 8.Поэтому я считаю, что это ошибка в моем коде.Может быть, что-то в моей функции задержки?У кого-нибудь есть идея?
РЕДАКТИРОВАТЬ # 1: Я сделал другие тесты.Я изменил значение моих переменных.Не меняет результат.Сигнал остается 141 Гц, +/- 10 Гц.Даже если x16 тактовая частота.
Изменение прескалярного значения делает почти то же самое.Сигнал остается на этот раз, ТОЧНО, на частоте 141,76 Гц.
РЕДАКТИРОВАТЬ # 2: я использовал отладчик внутри моего pickit.Похоже, когда я делаю это.
int countsNum = (((ms_delay/1000)/(Prescaler/(oscFreq/4))));
Результат равен 0. Есть идеи почему?Это не должно быть.
РЕДАКТИРОВАТЬ # 3: Это дает мне 251 миллион, когда я использую тип long.
Edit # 4: проверенная тактовая частота.Это нормально.Тем не менее, этот расчет, даже если все целые числа не работают.Ответ на counttsNum - 74, но он должен быть 15.
unsigned int ms_delay = 500;
unsigned long oscFreq = 4000000;
unsigned long Prescaler = 32768;
unsigned int countsNum = ((ms_delay)/((Prescaler)/(oscFreq/4000)));