[PIC18F] Uruchomienie PWM

Nasze polecane książki, kursy, strony internetowe, fora itp. pomocne przy przyswajaniu wiedzy związanej z PIC i pisaniem programów dla nich.
Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1117
Rejestracja: czwartek 03 wrz 2015, 22:02

[PIC18F] Uruchomienie PWM

Postautor: Antystatyczny » sobota 26 lis 2016, 18:30

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.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

Awatar użytkownika
Marcin
User
User
Posty: 198
Rejestracja: środa 09 wrz 2015, 19:30

Re: [PIC18F] Uruchomienie PWM

Postautor: Marcin » poniedziałek 01 sty 2018, 16:17

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 ?

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1117
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: [PIC18F] Uruchomienie PWM

Postautor: Antystatyczny » poniedziałek 01 sty 2018, 16:29

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.
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

Awatar użytkownika
Marcin
User
User
Posty: 198
Rejestracja: środa 09 wrz 2015, 19:30

Re: [PIC18F] Uruchomienie PWM

Postautor: Marcin » poniedziałek 01 sty 2018, 16:51

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.
Ostatnio zmieniony poniedziałek 01 sty 2018, 16:54 przez Marcin, łącznie zmieniany 1 raz.

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1117
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: [PIC18F] Uruchomienie PWM

Postautor: Antystatyczny » poniedziałek 01 sty 2018, 16:53

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ść.
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

Awatar użytkownika
Marcin
User
User
Posty: 198
Rejestracja: środa 09 wrz 2015, 19:30

Re: [PIC18F] Uruchomienie PWM

Postautor: Marcin » poniedziałek 01 sty 2018, 16:56

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.


Wróć do „Źródła wiedzy na temat PIC”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 2 gości