Strona 1 z 1

[PIC18F] Uruchomienie PWM

: sobota 26 lis 2016, 18:30
autor: Antystatyczny
Witam i od razu wrzucam przykładowy programik uruchamiający moduł CCP2 w trybie PWM. Jest tam co nieco komentarzy, więc nie powinno być problemów ze zrozumieniem, ale w razie czego proszę pytać.

Kod: Zaznacz cały

/*
 * File:   main.c
 * Author: Arkadiusz Pytlik
 *
 * Created on 17 listopada 2016, 23:54
 */

#include "config.h"

#ifndef _XTAL_FREQ
#define _XTAL_FREQ 4000000UL
#endif

#include <xc.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>


/* 2.5 factor */
const uint16_t gamma[]  = {
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,
  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,
  2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,
  3,  3,  3,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5,
  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  6,  6,  6,  7,  7,  7,  7,  7,
  7,  7,  7,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9, 10, 10,
 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13,
 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16,
 17, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20,
 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25,
 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 30, 30, 30,
 31, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36,
 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 41, 41, 41, 42, 42, 42,
 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 47, 47, 47, 48, 48, 49, 49, 49,
 50, 50, 51, 51, 52, 52, 52, 53, 53, 54, 54, 54, 55, 55, 56, 56, 57, 57,
 58, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 64, 65, 65,
 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74,
 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 83, 83, 84, 84,
 85, 85, 86, 86, 87, 88, 88, 89, 89, 90, 90, 91, 92, 92, 93, 93, 94, 95,
 95, 96, 96, 97, 98, 98, 99,100,100,101,101,102,103,103,104,105,105,106,
106,107,108,108,109,110,110,111,112,112,113,114,114,115,116,116,117,118,
118,119,120,121,121,122,123,123,124,125,125,126,127,128,128,129,130,130,
131,132,133,133,134,135,136,136,137,138,139,139,140,141,142,142,143,144,
145,146,146,147,148,149,149,150,151,152,153,153,154,155,156,157,157,158,
159,160,161,162,162,163,164,165,166,167,167,168,169,170,171,172,172,173,
174,175,176,177,178,179,179,180,181,182,183,184,185,186,187,187,188,189,
190,191,192,193,194,195,196,197,198,199,199,200,201,202,203,204,205,206,
207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,
243,244,245,246,248,249,250,251,252,253,254,255,256,257,258,259,261,262,
263,264,265,266,267,268,269,271,272,273,274,275,276,277,279,280,281,282,
283,284,285,287,288,289,290,291,292,294,295,296,297,298,300,301,302,303,
304,306,307,308,309,311,312,313,314,315,317,318,319,320,322,323,324,325,
327,328,329,330,332,333,334,336,337,338,339,341,342,343,345,346,347,348,
350,351,352,354,355,356,358,359,360,362,363,364,366,367,368,370,371,373,
374,375,377,378,379,381,382,384,385,386,388,389,391,392,393,395,396,398,
399,400,402,403,405,406,408,409,410,412,413,415,416,418,419,421,422,424,
425,427,428,430,431,432,434,435,437,438,440,441,443,445,446,448,449,451,
452,454,455,457,458,460,461,463,464,466,468,469,471,472,474,475,477,479,
480,482,483,485,487,488,490,491,493,495,496,498,499,501,503,504,506,508,
509,511,513,514,516,518,519,521,523,524,526,528,529,531,533,534,536,538,
539,541,543,545,546,548,550,551,553,555,557,558,560,562,564,565,567,569,
571,572,574,576,578,579,581,583,585,587,588,590,592,594,596,597,599,601,
603,605,606,608,610,612,614,616,617,619,621,623,625,627,629,630,632,634,
636,638,640,642,644,645,647,649,651,653,655,657,659,661,663,665,667,668,
670,672,674,676,678,680,682,684,686,688,690,692,694,696,698,700,702,704,
706,708,710,712,714,716,718,720,722,724,726,728,730,732,734,736,738,740,
742,744,747,749,751,753,755,757,759,761,763,765,767,770,772,774,776,778,
780,782,784,786,789,791,793,795,797,799,801,804,806,808,810,812,814,817,
819,821,823,825,828,830,832,834,836,839,841,843,845,848,850,852,854,857,
859,861,863,866,868,870,872,875,877,879,881,884,886,888,891,893,895,898,
900,902,904,907,909,911,914,916,918,921,923,926,928,930,933,935,937,940,
942,944,947,949,952,954,956,959,961,964,966,968,971,973,976,978,981,983,
985,988,990,993,995,998,1000,1003,1005,1008,1010,1013,1015,1018,1020,1023
};

void PWM_SetDuty(uint16_t duty);

int main(void)
{
    /* GPIO init */
    TRISC &= ~_TRISC_RC1_MASK; /* Output */
    LATC &= ~_LATC_LATC1_MASK; /* Low state */
   
    /* Timer 2 init */
    PR2 = 255; /* Period register */
    T2CON = _T2CON_TMR2ON_MASK;/* Prescaler 1:1, postscaler 1:1 */
   
    /* CCP2 init */
    CCP2CON = _CCP2CON_CCP2M3_MASK | _CCP2CON_CCP2M2_MASK;/* pwm mode */
   
    while(true)
    {
        for(size_t loop = 0; loop < sizeof(gamma) / sizeof(uint16_t); ++loop)
        {
            PWM_SetDuty( gamma[loop] );
            __delay_ms(1);
        }
       
       
    }
}

void PWM_SetDuty(uint16_t duty)
{
    /* Correct values are from 0 to 1023 */
    if(duty > 1023)
    {
        duty = 1023;
    }
   
    /* Two duty cycle LSB's are in CCP2CON register */
    if(duty & (1 << 0) != 0)
    {
        CCP2CON |= _CCP2CON_DC2B0_MASK;
    }
    else
    {
        CCP2CON &= ~_CCP2CON_DC2B0_MASK;
    }
   
    if(duty & (1 << 1) != 0)
    {
        CCP2CON |= _CCP2CON_DC2B1_MASK;
    }
    else
    {
        CCP2CON &= ~_CCP2CON_DC2B1_MASK;
    }
    /* Rest load into CCPR2L register */
    CCPR2L = (uint8_t)(duty >> 2);
}


A tu cały projekt:
PIC18F4550_pwm.X.7z


Pozdrawiam.

Re: [PIC18F] Uruchomienie PWM

: poniedziałek 01 sty 2018, 16:17
autor: Marcin
Czytam o CCP w PICach, z tego co widzę CCP w trybie PWM współpracuje tylko z timerem 2. Jest to ośmiobitowy timer, rejestr PR2 decyduje o częstotliwości PWM. Max prescaller to 16 dla tego licznika, tu by osiągnąć niską częstotliwość trzeba mocno zredukować taktowanie, dla 50 Hz musi być ono niższe niż 1MHz. Dla 1MHz freq PWM będzie równe 61Hz. Sprzętowo inaczej nie da się osiągnąć tak niskiej częstotliwości jak redukcja zegara ?

Re: [PIC18F] Uruchomienie PWM

: poniedziałek 01 sty 2018, 16:29
autor: Antystatyczny
Nie wiem, jaki układ analizujesz, ale np. w przypadku PIC16F877 o maksymalnym taktowaniu kwarcem 20MHz można zejść z taktowaniem timera 2 do 312,5kHz. Zerknij również w Reference Manual: http://ww1.microchip.com/downloads/en/d ... 33023a.pdf Od strony 195 opisany jest Timer 2, a na stronie 211 są wzory do obliczania okresu oraz współczynnika wypełnienia generowanego przebiegu.

Re: [PIC18F] Uruchomienie PWM

: poniedziałek 01 sty 2018, 16:51
autor: Marcin
Korzystam z tego dokumentu http://ww1.microchip.com/downloads/en/AppNotes/00594B.PDF a mikrokontroler to PIC16F716.

I tu jest wzór określający okres PWM

PWM Period = [(PR2) + 1] • 4 TOSC • (Timer 2 prescale value)

A więc PR2 może mieć maksymalną wartość 255, prescaler dla timera 2 maksymalnie 16, więc by zejść do 50Hz trzeba drastycznie obniżyć TOSC.

Sprawdzałem również w innym PICu (PIC18F2550) tu tak samo:
• 8-bit timer and period registers (TMR2 and PR2, respectively)
• Software programmable prescaler (1:1, 1:4 and 1:16)

Więc żadnych innych możliwości nie mam, chyba że jest jeszcze coś o czym jeszcze nie wiem. Ale z PR2 max 255 i prescalera 16 przy 20MHz nie uzyskasz 50Hz na wyjściu PWMa.

Oczywiście narazie tylko teoretyczne rozważania, bo jeszcze nie mam żadnej platformy sprzętowej do testowania, PICKIT3 oraz kilka PICów w drodzie.

Re: [PIC18F] Uruchomienie PWM

: poniedziałek 01 sty 2018, 16:53
autor: Antystatyczny
Marcin pisze:by zejść do 50Hz trzeba drastycznie obniżyć TOSC


Raczej podwyższyć/zwiększyć. T_osc oznacza okres sygnału taktującego, a nie jego częstotliwość.

Re: [PIC18F] Uruchomienie PWM

: poniedziałek 01 sty 2018, 16:56
autor: Marcin
Antystatyczny pisze:
Marcin pisze:by zejść do 50Hz trzeba drastycznie obniżyć TOSC


Raczej podwyższyć/zwiększyć. T_osc oznacza okres sygnału taktującego, a nie jego częstotliwość.

Tak, masz rację, miałem na myśli obniżyć częstotliwość, czyli zwiększyć Tosc (czyli okres) co obniża częstotliwość.
Ale by uzyskać freq 50 Hz trzeba mocno zejść z taktowaniem procka, poniżej 1MHz.