Auratos

PIC18F25K22. Настройка прерываний таймера

11 posts in this topic

Auratos    0

Добрый день. У меня контроллер PIC18F25K22. Пытался завести таймер TMR0 с частотой прерываний 1мс. Но на деле получаю 1,31мс. И не пойму, почему так. Настройки таймера рассчитал вручную, а затем с помощью программы PIC Timer Calculator. Данные сошлись, но по факту частота не та. У меня внешний тактовый генератор 4,9152МГц с включенной PLL. От этого и отталкивался. Считал, что на CLKOUT имею 4915200Гц. Значит в 16-битном режиме для 1мс мне понадобится 4916 приращений таймера. Сделал предзагрузку 0xECCC. И получил не то, что хотел.

Вот такие у меня настройки источника тактирования:

#pragma config WDTEN = SWON        // сторожевой таймер
#pragma config WDTPS = 512        // скорость работы сторожевого таймера
#pragma config FOSC = HSMP        // частота тактового генератора
#pragma config PLLCFG = ON
#pragma config PRICLKEN = ON
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRTEN = ON
//#pragma config BORV = 285
#pragma config BOREN = OFF
#pragma config PBADEN = OFF
#pragma config XINST = OFF

И вот настройки таймера:

// обработка прерывания таймера TMR0
void tmr0_int(void)
{
    INTCONbits.TMR0IF = 0;	// сброс переполнения таймера

    T0CONbits.TMR0ON = 0;
    TMR0L = 0xСС;
    TMR0H = 0xEC;
    T0CONbits.TMR0ON = 1;
    LED_SW;
}

// инициализация таймера TMR0
void tmr0_init(void)
{
    T0CONbits.T08BIT = 0;   // 16-ти разрядный таймер
    T0CONbits.T0CS = 0;     // тактирование от осцилятора 4*Fosc/4
    T0CONbits.T0SE = 0;     // приращение по переднему фронту импульса
    T0CONbits.PSA = 1;      // предделитель не используется
    T0CONbits.T0PS = 0;     // коэф. предделителя не используется
    TMR0L = 0xСС;	// регистр таймера в ноль
    TMR0H = 0xEC;
    INTCON2bits.TMR0IP = 1; // приоритет прерывания TMR0 - высокий
    INTCONbits.TMR0IE = 1;	// разрешить прерывание по переполнению TMR0
    T0CONbits.TMR0ON = 1;
}

Частоту смотрю на осциллографе по светодиоду, состояние которого меняю каждое прерывание. Схема подключения внешнего тактового генератора на фотографии. Подскажите, пожалуйста, в чем может быть загвоздка? В Fosc выбрал не тот режим? Завел еще таймер TMR1. В регистре T1CONbits в бите TMR1CS  ставил и 00 и 01. После соответствующего пересчета получал все то же значение частоты. 

TMRxCS<1:0>: Timer1/3/5 Clock Source Select bits
 11 =Reserved. Do not use.
 10 =Timer1/3/5 clock source is pin or oscillator:
    If TxSOSCEN = 0:
    External clock from TxCKI pin (on the rising edge)
    If TxSOSCEN = 1:
    Crystal oscillator on SOSCI/SOSCO pins
 01 =Timer1/3/5 clock source is system clock (FOSC)
 00 =Timer1/3/5 clock source is instruction clock (FOSC/4)

Еще подскажите, пожалуйста, как начать тактироваться от внутреннего тактового генератора. Где это настраивается? В регистре OSCCON?

o3HjHrTjL_w.jpg

Share this post


Link to post
Share on other sites
Alex    587
13 часа назад, Auratos сказал:

Сделал предзагрузку 0xECCC. И получил не то, что хотел.

Делать точные периодические вызовы на этих таймерах - мазохизм. Посмотрите в сторону TIMER2/4/6 Они для этого как раз и предназначены.

13 часа назад, Auratos сказал:

как начать тактироваться от внутреннего тактового генератора. Где это настраивается? В регистре OSCCON?

Раздел "OSCILLATOR MODULE" даташита. Всё расписано по полочкам, даже с рисуночками...

Share this post


Link to post
Share on other sites
IMXO    1474
15 часов назад, Auratos сказал:

 


// обработка прерывания таймера TMR0
void tmr0_int(void)
{
    INTCONbits.TMR0IF = 0;	// сброс переполнения таймера

    T0CONbits.TMR0ON = 0;
    TMR0L = 0xСС;
    TMR0H = 0xEC;
    T0CONbits.TMR0ON = 1;
    LED_SW;
}

какое отношение эта функция имеет к прерыванию?

Share this post


Link to post
Share on other sites

DC/DC-преобразователи MORNSUN R3. Повышенная надёжность - сниженная стоимость!

Особенностью преобразователей R3 являются улучшенные технические характеристики, повышенная надёжность и сниженная стоимость. Электрическая прочность изоляции представленных преобразователей не менее 1500 В, а температурный диапазон применения -40…105ºС.

Подробнее...

Auratos    0
5 часов назад, IMXO сказал:

какое отношение эта функция имеет к прерыванию?

Я просто не указал место, где вызывается эта функция )

#pragma code high_vector=0x08
void interrupt_at_high_vector(void)  // с высоким приоритетом
{
_asm GOTO high_isr _endasm
}
#pragma code

#pragma interrupt high_isr
// обработчик векторов прерываний высокого приоритета
void high_isr (void)
{
    if(INTCONbits.TMR0IF & INTCONbits.TMR0IE) tmr0_int();   // прерывание по таймеру
    if(PIR1bits.TMR1IF) tmr1_int();   // прерывание по таймеру
}

 

Share this post


Link to post
Share on other sites
Auratos    0
7 часов назад, Alex сказал:

Раздел "OSCILLATOR MODULE" даташита. Всё расписано по полочкам, даже с рисуночками...

Я читал этот раздел. Увидел, что внутренний генератор настраивается в регистре OSCCON. Я его настроил вот так (хотел запуститься от 4МГц):

OSCCONbits.IRCF = 0b101;
OSCCONbits.OSTS = 0;
OSCCONbits.HFIOFS = 1;
OSCCONbits.SCS = 0x10;

А в итоге не увидел на осциллографе разницы. Я, видимо, упустил какую-то маленькую, но важную деталь )

Share this post


Link to post
Share on other sites

Новые методы уменьшения дрейфа нуля в малошумящих АЦП Texas Instruments

Стабилизация с помощью двойного прерывания с двойным контролем в новых АЦП ADS1235 производства Texas Instruments позволяет снизить до минимума напряжение смещения и достичь высокой точности в измерительных цепях современных прецизионных цифровых приборов.

Подробнее...

skripach    16
6 часов назад, IMXO сказал:

TMR0L = 0xСС;

TMR0H = 0xEC;

чтобы записать в таймер  новое значение, сначала надо записать TMR0H, а потом TMR0L!  

Share this post


Link to post
Share on other sites
IMXO    1474

это:

if(INTCONbits.TMR0IF & INTCONbits.TMR0IE) tmr0_int();

if(INTCONbits.TMR0IF && INTCONbits.TMR0IE) tmr0_int();

разные команды!!!

23 часа назад, Auratos сказал:

Значит в 16-битном режиме для 1мс мне понадобится 4916 приращений таймера.

там ни как не будет эта цифра.

вход в обработчик  2маш.цикла

переход на функцию   2маш.цикла

семафор    6 маш.циклов

установка таймера   6маш.циклов

итого   16маш.циклов

Share this post


Link to post
Share on other sites
Auratos    0
2 часа назад, IMXO сказал:

там ни как не будет эта цифра.

Объясните, пожалуйста, вашу точку зрения. Цифра, задуманная мною, не будет в принципе или не будет при данном синтаксисе?

if(INTCONbits.TMR0IF & INTCONbits.TMR0IE) tmr0_int();

А если напишу if(INTCONbits.TMR0IF && INTCONbits.TMR0IE) tmr0_int();, то будет?

2 часа назад, IMXO сказал:

там ни как не будет эта цифра

Просто когда я поправил порядок инициализации (TMR0H и TMR0L поменял местами), как посоветовали, то результат улучшился. Теперь я на осциллографе увидел, что прерывания срабатывают каждую  1.045мс, вместо предыдущих 1.3мс. Хотя я подбирал предзагрузку для 1.0001мс, но результат уже определенно лучше

Share this post


Link to post
Share on other sites
Alex    587

От переполнения таймера, до его переустановки проходит n-ное кол-во тактов (их описал IMXO). По этому и возникает ошибка.
Ещё раз посоветую - используйте другие таймеры, специально для этого предназначенные. Они сами, аппаратно, переустанавливаются при переполнении.

Share this post


Link to post
Share on other sites
IMXO    1474
2 часа назад, Auratos сказал:

Просто когда я поправил порядок инициализации (TMR0H и TMR0L поменял местами)

все проще, в хедерах уже прописана переменная TMR1  размерностью 16бит

в коде после конфига достаточно прописать что-то типа

#define CONSTANT_TMR1  45 - 4916 //  где первое число поправочный коэф. 
                                 // второе расчетное кол-во тактов  
  
// перезагрузка таймера
      INTCONbits.TMR0IF = 0;	// сброс переполнения таймера
      T0CONbits.TMR0ON = 0;
      TMR1 = CONSTANT_TMR1;  
      T0CONbits.TMR0ON = 1;

 

Share this post


Link to post
Share on other sites
Auratos    0

Спасибо большое. Теперь я со всем разобрался. Убрал лишнее из обработчика прерываний, назначил на все это дело TMR2, и все запело ))

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Сообщения

    • это другой ток, спасибо     значит подходящей цепи по питанию нет  
    • Никто не отписывался по поводу ЦАПа, собранного автором в дополнение к контроллеру. Я решил собирать все от начала до конца, сегодня закончил ЦАП, подключил и был очень приятно удивлен звуком. Разницу между Realtek и PCM2706 на работе услышали все, даж е те, кто к этому относился очень скептически. Других ЦАПов не слушал, но этот очень и очень хорош. Спасибо. Чуть позже отпишусь по работе в связке с РГ на PGA2311, доделываю БП.
    • У меня есть трансформатор с выходом 33.5 вольта переменного напряжения , есть предложить схему БП ? Если после диодного моста и конденсатора будет больше чем 33.5 постоянного , мне нужно что бы от 1.25 вольта регулировалось минимум к 24
    • Мастеровой bashir Я настраивал без осциллографа,хотя их у меня 2.Человек хочет дёшево и надёжно.Я пользуюсь тиристорником и обладатели заводских инверторов мне завидуют.Особенно когда варят чугун или обычные трубы-говорят-сварочный шов как у автогена.А вы покупайте транзисторные ключи пока не надоест и придумывайте всякие приблуды,чтобы облегчить им жизнь.Тиристорный аппарат дешёвый и надёжный.Естественно у того-кто умеет его сделать и настроить.Ваш аппарат хоть и красиво сделан-но имеет огромные отклонения конструктива от совершенства.Не судите тиристорный сварочник по своему недоделанному и несовершенному варианту.  
    • В справочнике по микросхеме всё показано, думаю, разобраться будет не сложно. Ток ограничится до уровня установленного и микросхема не погорит. Транзистор надо установить на радиатор достаточной мощности и уточнить его максимальные токи при допустимом напряжении. В этом случае он так же не погорит ...