PIC32 – первая программа

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, откуда мы берем тактовую частоту и как можно управлять длительностью формируемых таймером интервалов времени.

catcatcat_pic32_03

Тактовые импульсы поступают с делителя тактовой частоты который тактирует всю периферию (на рисунке его нет, он относится к главному генератору, рассмотрим позже), через входной коммутатор, цель его выбрать источник тактовых импульсов настройкой битов 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 секунды.

Для начала достаточно, мы запустили микроконтроллер, настроили тактовый генератор (еще не понятно как) написали первую программу и заставили мигать светодиод.


Поделись этим!