Views: 1058
В мире микроконтроллеров первой программой всегда становиться программа которая позволяет управлять состоянием порта. В нашем случае будет классика – мигание светодиода.
Для задания временных интервалов воспользуемся таймером TMR1 – это 16 битный таймер. В нашем варианте тактовая частота 80 МГц и предделитель для периферии настроен на 1. Сейчас просто настроим на максимальный коэффициент деления для того, чтобы можно было видеть мигание светодиода.
Расчет частоты на выходе таймера 80 000 000 / 256 / 65535 = 4,8 Гц. С учетом, того, что в программе будем использовать переключение, то частота мигания составит 2,4Гц.
Первое, что надо сделать в программе сообщить компилятору с каким контроллером он работает и какая тактовая частота:
#include <xc.h> // для настройки под выбранный контроллер #include <plib.h> #define SYS_FREQ (80000000L)
Выполним конфигурацию микроконтроллера:
// конфигурирование микроконтроллера #pragma config FSRSSEL = PRIORITY_0 // SRS Select / SRS Priority 0 // конфигурирование модуля Ethernet #pragma config FMIIEN = OFF // Ethernet RMII/MII Enable / RMII Enabled #pragma config FETHIO = OFF // Ethernet I/O Pin Select / Alternate Ethernet I/O // конфигурирование модкля CAN #pragma config FCANIO = OFF // CAN I/O Pin Select / Alternate CAN I/O // конфигурирование модуля USB #pragma config FUSBIDIO = OFF // USB USID Selection / Controlled by Port Function /*FUSBIDIO = ON*/ #pragma config FVBUSONIO = OFF // USB VBUS ON Selection / Controlled by Port Function /*FVBUSONIO = ON*/ // конфигурирование USB PLL Input Divider #pragma config UPLLIDIV = DIV_2 // 2x Divider // конфигурирование USB PLL Enable #pragma config UPLLEN = OFF // Disabled and Bypassed // конфигурирование тактового генератора для 80 МГц от кварца 8 МГц. (8/2*20 = 80) // конфигурирование Oscillator Selection Bits #pragma config FNOSC = PRIPLL // Primary Osc w/PLL (XT+,HS+,EC+PLL) // конфигурирование PLL Input Divider #pragma config FPLLIDIV = DIV_2 // 2x Divider // конфигурирование PLL Multiplier #pragma config FPLLMUL = MUL_20 // 20x Multiplier // конфигурирование System PLL Output Clock Divider #pragma config FPLLODIV = DIV_1 // PLL Divide by 1 // конфигурирование Secondary Oscillator Enable #pragma config FSOSCEN = OFF // Disabled // Internal/External Switch Over #pragma config IESO = OFF // Disabled // Primary Oscillator Configuration #pragma config POSCMOD = HS // HS osc mode // CLKO Output Signal Active on the OSCO Pin #pragma config OSCIOFNC = OFF // Disabled // Настройка тактовой частоты тактирования переферии #pragma config FPBDIV = DIV_1 // Pb_Clk is Sys_Clk/1 //Clock Switching and Monitor Selection #pragma config FCKSM = CSDCMD // Clock Switch Disable, FSCM Disabled // Watchdog Timer Postscaler #pragma config WDTPS = PS16384 // 1:16384 // Watchdog Timer Enable #pragma config FWDTEN = OFF // WDT Disabled (SWDTEN Bit Controls) // Background Debugger Enable #pragma config DEBUG = OFF // Debugger is disabled // ICE/ICD Comm Channel Select #pragma config ICESEL = ICS_PGx1 // ICE EMUC1/EMUD1 pins shared with PGC1/PGD1 // Program Flash Write Protect #pragma config PWP = OFF // Disable //Boot Flash Write Protect bit #pragma config BWP = OFF // // Code Protect #pragma config CP = ON //Protection Enabled
Настроим порты для работы в цифровом режиме:
TRISB = 0b0000000000000000; // регистр направления данных PORTB = 0; // регистр приема данных LATB = 0; // регистр передаваемых данных ODCB = 0; // регистр настройки "открытого коллектора" TRISC = 0b0000000000000000; // PORTC = 0; LATC = 0; ODCC = 0; TRISD = 0b0000000000000000; // PORTD = 0; LATD = 0; ODCD = 0; TRISE = 0b0000000000000000; // PORTE = 0; LATE = 0; ODCE = 0; TRISF = 0b0000000000000000; // PORTF = 0; LATF = 0; ODCB = 0; TRISG = 0b0000000000000000; // PORTG = 0; LATG = 0; ODCG = 0; AD1PCFG = 0; // все входы цифровые CNCON = 0; // регистр управления контроль изменения изменения состояния на входах CNEN = 0; // регистр разрешения
Включим и настроим работу таймера 1:
// настройка работы таймера T1CON = 0b00000000000000001000000000110000; /* | ||| | || |+--- TCS:выбор источника тактовых импульсов 0 = внутрений генератор * | ||| | || +---- TSYNC:управление синхронизацией 0 - игнорируется, так как тактируется от внутренего генератора * | ||| | ++------ TCKPS<1:0>: предделитель 11 = 1:256 * | ||| +--------- TGATE: Врата управления таймером отключен * | ||+------------- TWIP: Флаг индикации режима записи в таймер TMR1 * | |+-------------- TWDIS: Управление компенсационной записью 0 - разрешена (1 = Запись в TMR1 игнорируются до ожидании операции записи завершает) * | +--------------- SIDL: управление работой в режиме ожидания. 0 - работать всегда * +----------------- ON: Включить таймер */ PR1 = 0xFFFF; //
И добавит в программу главный цикл работы:
/*главный цикл*/ while(1) { if(IFS0bits.T1IF)// ожидания установки флага переполнения { IFS0bits.T1IF=0;//сброс флага LATBINV = LED01;//инвертирование состояния светодиода } }
Теперь можно загрузить проект
Рассмотрим таймер 1, откуда мы берем тактовую частоту и как можно управлять длительностью формируемых таймером интервалов времени.
Тактовые импульсы поступают с делителя тактовой частоты который тактирует всю периферию (на рисунке его нет, он относится к главному генератору, рассмотрим позже), через входной коммутатор, цель его выбрать источник тактовых импульсов настройкой битов TCS и TGATE выбираем внутренний генератор. Далее проходит через модуль синхронизации напрямую, синхронизировать нам не нужно, так-как используется внутренний системный генератор и поступает на счетчик таймера. Таймер считаем приходящие импульсы, схема сравнения сравнивает с числом записанным в регистре PR1 и при совпадении устанавливает флаг переполнения. Если мы запишем в PR1 число 0xFFFF то получим максимальное время счета и саму низкую частоту на выходе таймера. Уменьшая значение записанное в регистре PR1 мы можем регулировать выходную частоту.
Изменим значение записанное в регистр PR1 и понаблюдаем за изменением периода мигания светодиода, для начала внесем значение 0x5FFF (изменим, увеличим частоту). Т.е. чем ниже число записанное в PR1 тем выше частота или меньше длительность формируемая на выходе таймера.
Как рассчитать частоту или длительность?
PBCLK – у нас 80 МГц,
Частота на выходе таймера Ft1 = PBCLK /Prescaler/PR1.
Для нашего примера в первом случае Ft1 = 80 000 000 / 256 / 0xFFFF = 80 000 000/256/65535 = 4.768 Гц.
Или длительность Dt1 = 1/ Ft1.
Dt1 = 1/4.768 = 0.209712 секунды.
Для начала достаточно, мы запустили микроконтроллер, настроили тактовый генератор (еще не понятно как) написали первую программу и заставили мигать светодиод.