код за урока за таймерите в пик процесорите -

link here >>> http://karadev.net/basto/?dir=timer_pic1829

препоръчително използване на NOTEPAD++ с настройка за разпознаване на С/С++ код за да можете да видите различните регистри, променливи и другите особенности на езика за програмиране на пик процесорите.

симулацията е в програмата протеус, версия последна има я в нета, или си начертайте собствена схема според графиките в предните уроци. успех

========================= MAIN.C =============================

#include <xc.h>
//#include <pic16f1829.h>
#include "initcpu.h"
#include "main.h"
#include "fuse.h"
#include "timers.h"            // here is interrupt function
//#include "lcd.h"            // for later use in this project

void main(void)
{    init_cpu();
        //PORTB = 8;
    while(1)
    {    
    // increase Postscaler value 0<>15
    if(T2OUTPS_plus == 1)
        { __delay_ms(350); //delay for button
            T2CONbits.T2OUTPS++;
             // sum + 16 for start count from RB4
            PORTB = PORTB + 16; // indicator plus + 1
            if(T2CONbits.T2OUTPS == 0)
            { PORTB = 0;} // null indicator
        }
    
     // decrease Postscaler value 0<>15
    if(T2OUTPS_minus == 1)
        {__delay_ms(350);//delay for button
            T2CONbits.T2OUTPS--;
            PORTB--; // indicator minus - 1
            if(T2CONbits.T2OUTPS == 0)
            { PORTB = 0; } // null indicator
        }
    
    // increase Prescale value 0<>3
    if(T2CKPS_plus == 1)
        {__delay_ms(350);//delay for button
            T2CONbits.T2CKPS++;PORTA++;
            if(T2CONbits.T2CKPS == 0)
            {
            PORTA = 0;    
            }
        }
} // END WHILE


} // END MAIN

========================= TIMERS.C =============================
функцята която обработва прекъсвате е предварително дефининирана в ХС8 и трябва само да я извиката както е показано в кода по-долу. вътре във функцията нулирате флага на таймера и след това изпълнявате командите който ви трябват. колкото и софтуер да напишете в таймера честотата на който  и да използвате таймер няма да се промени. което е целта на задачата.

========================= TIMERS.C =============================

#include <xc.h>
#include "main.h"
#include "timers.h"

unsigned char flag_timerirq = 0;

void __interrupt() timer2(void)
{    PIR1bits.TMR2IF = 0;
    //======================
    // check on scope for frequency VARIANT 1
    //notused6 = 1; //PORTAbits.RA5
    //notused6 = 0; //PORTAbits.RA5
    //======================
    // check on scope for frequency VARIANT 2
    if(flag_timerirq == 0) // full period freq
            {                    // multypile by 2 for
            LATA5 = 1;        // real frequency
                flag_timerirq = 1;
            }
        else
            {    LATA5 = 0;
                flag_timerirq = 0;
            }


} // END OF INTERRUPT TIMER2

========================= INITSPU.C =============================

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

========================= INITSPU.C =============================


#include <xc.h>
//#include <pic16f1829.h>
#include "main.h"

void init_cpu(void)
{
OSCCON = 0x72; // 4F - 1Mhz // 6A - 4Mhz
                // 0x72 - 8Mhz // 0x7A - 16Mhz
OPTION_REG = 0b10000000; // TIMER0 REG // pull up is DISABLE

CM1CON0 = 0b00000000;
CM1CON1 = 0b00000000;

CM2CON0 = 0b00000000;
CM2CON1 = 0b00000000;
                
ADCON0 = 0b00000000;
ADCON1 = 0b00000000;

CLKRCON = 0b00000000; // slew rate is OFF
MDCON = 0b00000000; // slew rate is OFF

ANSELA = 0b00000000;
TRISA  = 0b00001000; // /MCLR = 1 always
PORTA = 0x00;
WPUA = 0x00;

ANSELB = 0b00000000;
TRISB  = 0b00000000;
PORTB = 0x00;
WPUB = 0x00;

ANSELC = 0b00000000;
TRISC  = 0b00000111;
PORTC = 0x00;
WPUC = 0x00;

MDMSODIS = 1; // logic cell disables

GIE = 1 ; // enable general interrupts FOR ALL
PEIE = 1; // enable peripherial interrupts FOR ALL
TMR2IE = 1; // // enable TIMER2 interrupts
// set bits from pdf for timer prescaler and post scaller
T2CON = 0b00000000; // and timer2 on / off
T2CONbits.T2OUTPS = 0; //0-15 // Timerx Output Postscaler Select bits
T2CONbits.T2CKPS = 0; //0-3  // Timer2-type Clock Prescale Select bits
T2CONbits.TMR2ON = 1; // enable timer2 to start


}
========================= INITSPU.C =============================

ОЧАКВАЙТЕ СОФТУЕРА И ВСИЧКО УПОТРЕБАТА НА ТАЙМЕРИТЕ С КОМАНДИТЕ ОТ ЦЕНТРАЛНАТА ПРОГРАМА, КАКТО И ВЪВ ФУНКЦИЯТА ЗА ОБРАБОТКА НА ПРЕКЪСВАНИЯТА !!!!

ДАДЕНИТЕ ГРАФИКИ ВЪВ ПРЕДНИТЕ УРОЦИ СА ОТ СИМУЛАЦИЯТА НА СЪЩИЯ СОФТУЕР КОЙТО ЩЕ БЪДЕ РАЗГЛЕДАН ВЪВ СЛЕДВАЩИТЕ УРОЦИ И ОБЯСНЕН ПОДРОБНО, КАКТО И ЦЯЛОСТЕН РАР ФАЙЛ ЗА СВАЛЯНЕ И УПОТРЕБА ОТ ВСЕКИ ПРОЧЕЛ И УСВОИЛ ТАЙМЕРИТЕ НА ПИК ПРОЦЕСОРИТЕ


малко графики от интернета показващи някои важни процеси и настройки за таймерите, както и как да се управляват и какъв ще е резултата от тяхното управление в обия процес.

показаните регистри имат възможност за зареждане от софтуера, както и промяна в работния процес чрез зареждане на нова стойност в регистъра.

регистърът TMR2  е стартовият регистър от който таймерът почва да брои или казано да му увеличава стойноста АВТОМАТИЧНО = ХАРДУЕРНО !!!! всеки път когато постъпи импулс на входа на TMR2 регистърс от изхода на програмируемия делител регистър PRESCALER !!! не е необходимо софтуерно да увеличавате стойността, това се прави хардуерно от самия таймер !!!! просто съм показал какво се случвам със стойността на таймера при стартирането му и при постъпването на импулси.

регистърът PR2 е този който е краят на броенето и с който регитър КОМПАРАТОР / COMPARATOR/ сравнява дали TMR2 е достигнал стойноста за генериране на прекъсване в основната програма на процесора.

когато стойностите на двата регистъра се изравнят, се подава импулс към TMROUPUT и едновременно с това се генерира прекъсване, като е подава импулс към POSTSCALER регистъра който е програмируем делител, както и PRESCALER регистъра. ПРЕКЪСВАНЕТО се отчита от флага за прекъсване на този таймер TMR2IF, като флага се установява в единица и софтуерно трябва да се нулира преди да се изпълнят командите във функцията за прекъсване на таймера.

когато се изпълнят всички команди във функцията за прекъсване, управлението се предава към централната програма и процеса се повтаря отново и отново докато има захранване на схемата :) и/или се случи събитие което влияе на самият таймер дали да бъде спрян или пуснат по време на централната програма. варианти за употреба на таймерите има много, както хардуерни управления така и чисто софтуерни варианти за обработка на данни, времена и други функции.


 

Софтуерните функции на таймерите се програмират във специална функция за прекъсване, в която се проверява флага на прекъсване на таймера, като след това се нулира и след това се изпълнява кода който искате периодично таймера да изпълнява като функция на процесора.

от блоковата схема по-надолу можете да видите как са свързани таймерите като хардуерни блокове към общата шина за данни в ядрото на процесора. диаграмата както и цялата налична информация за процесора е написана във пдф файла на страницата на сайта на микрочип за този процесор.

различните блокове на процесора са описани подробно във същия файл на процесора, като разделените в отделни глави теми съдържат както описание на регистрите, графики на подаваните сигнали от и към процесора, така и пълна техническа документация за управлението на всеки блок поотделно като хардуерен модул в ядрото на процесора.

 

ОЧАКВАЙТЕ СОФТУЕРА КЪМ ТАЗИ СИМУЛАЦИЯ И РАЗЯСНЕНИЕТО НА ВСИЧКИ ПРОЦЕСИ КОИТО СЕ СЛУЧВАТ ЗА ДА РАБОТИ ЕДИН ТАЙМЕР ИЛИ АКО ПРИЛОЖЕНИЕТО НА ПРОЦЕСОРА ИЗИСКВА МОЖЕ И СЪС ДВА И ТРИ ТАЙМЕРА !!!!!

менюто показано по-долу е менюто в което по време на ПАУЗА НА СИМУЛАЦИЯТА МОЖЕ ДА ПОКАЖЕ МЕНЮТА ЗА ИНФОРМАЦИЯ КЪМ ПРОЦЕСОРА И/ИЛИ ДРУГИ ЧИПОВЕ В СИМУЛАЦИЯТА


Регистри и първоначална настройка на таймера
Така, до сега дадохме описание на важните параметри на таймерите. Не забравяйте, че има и доста по сложни таймерни блокове, които се използват за различни цели в процесорната техника.
Настройката на таймерите, както и всички хардуерни блокове се прави чрез хардуерните регистри и техните битове, като както знаете за всеки хардуерен блок на процесора си има отделен регистър, в някои процесори единични битове са обединени в общ регистър.
В процесора 16F1829 настройката на таймерите 2, 4, 6 се прави във регистъра показан на графиката по-надолу


 

Ето в този регистър TxCON се настройва стартирането на таймера, делителя преди самия таймер и делителя след самия таймер. Буквата която е малко х се замества със номера на самия таймер който искате да настроите и да ползвате. Това са таймерите 2, 4, 6 като другите два таймера – таймер 0 и таймер 1 са във отделни графи на документацията. Както се вижда от блоковата графика на таймера входящата честота е директно зададена FOSC/4, което означава че входящата честота на таймера е настроена да бъде предварително разделена на 4 без значение дали ползвате външен или вътрешен генератор.

Има таймери на които входящата честота може да бъде подавана от външен пин на процесора, като това може да бъде отделен честотен генератор с външна интегрална схема или изобщо някаква външна електроника, която да подава правоъгълни импулси към таймера. За информация може да разгледате другите два таймера на този процесор, като обърнете внимание на блок схемата която е в началото на всеки раздел, където е описано от къде таймера може да вземе входяща честота, както и какви са хардуерните функции които може да изпълни таймера чрез управлението със съответните за него регистри.

Какво се случва когато таймера се препълни ? Това правят всички таймери и това е тяхната цел, да се препълнят за да генерират прекъсване и да изпълнят командите, които сте задали във функцията за прекъсване на таймера. По този начин следим някакво време което ни изпълнява определени команди в процесора за управление на някакъв хардуер, променливи, часовници и много други. Прекъсването ще даде възможност на точно определено време да се изпълни някакво събитие, което ни помага при отчитане на входящи и/или изходящи данни, процеси и други.

1.       Когато таймера се препълни се вдига флага за прекъсване на таймера, процесора обработва командите които са във функцията на прекъсването и след това се връща към изпълнение на функциите в главната функция void main(void) във файла main.c

2.       ВНИМАНИЕ !!!!! КОЛКОТО ПО-ЧЕСТО ПРЕПЪЛВАТЕ ТАЙМЕРА, ТОЛКОВА ПО-ЧЕСТО ЩЕ СЕ ГЕНЕРИРА ПРЕКЪСВАНЕ В ПРОЦЕСОРА И МОЖЕ ДА НЕ ОСТАНЕ ВРЕМЕ ЗА ИЗПЪЛНЕНИЕ НА ОСНОВНИТЕ ФУНКЦИИ ВЪВ ГЛАВНАТА ФУНКЦИЯ !!!! АКО СТАРТИРАТЕ ПОВЕЧЕ ОТ ЕДИН ТАЙМЕР КОИТО И ДА СА ТЕ ВНИМАВАЙТЕ ЗА ВРЕМЕТО ЗА КОЕТО ГИ ПРЕПЪЛВАТЕ СЪОТВЕТНО В ПРОЦЕСОРА СЕ ГЕНЕРИРА ПРЕКЪСВАНЕ !!!

3.       Ще разгледаме това във показания код по-надолу във урока
На тази графика има няколко съществени разлики в настройката на таймер 2, таймер 4 и/или таймер 6. Таймерите в процесора с тази конфигурация като три отделни хардуерни блока са три броя с имена таймер 2, таймер 4 и таймер 6. В описанието на процесора микрочип са дали възможност да използваме няколко различни по хардуерна настройка таймера с цел по-голяма гъвкавост в различните приложения в електрониката.



 

Описание на параметрите на таймера :
1.       FOSC/4 е тактовата честота подавана на входа на таймера разделена предварително на 4.

2.       PRESCALER – е делител преди таймера, който с конфигурация от битове можете да изберете коефициент на делене показан на графиката, както и описанието на регистъра отговарящ за всеки от трите таймера поотделно.

3.       TMRx e регистъра на таймера 2,4,6 който се увеличава с 1 на всеки постъпил импулс след входящия делител според коефициента на делене.

4.       PRx е регистъра в който давате стойност до колко да брои таймера. В таймер 0 този регистър го няма. Таймер 0 винаги брой до 255 от колкото му зададете предварително. Таймерите 2,4,6 имат възможност да зададете и стойност на регистъра от колко да започне, както и стойност до колко да брои със тактова честота постъпваща от делителя преди таймера и подавани след делителя на таймера ако искате да го използвате и него.

5.       COMPARATOR e регистърът който ще отчете дали има равенство между двата регистъра, което съответно ще означава, че таймера се е препълнил и ще се подаде импулс на ИЗХОДЯЩИЯ ДЕЛИТЕЛ – POSTSCALER

6.       POSTSCALER – това е също делител на честота, но след таймера, който има възможност да бъде настроен да дели или да не дели а директно да подава изходящия импулс към флаговете за прекъсване всеки съответно на таймерите 2, 4, 6.

7.       TMRxIF е флага съответно 2, 4, 6 за всеки от трите таймера, който ще се установи в 1, когато таймера се препълни и се генерира прекъсване.