Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP

p.kaczmarek2 02 Nov 2020 00:23 2469 4
Computer Controls
  • [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Witajcie moi drodzy
    W tym temacie pokażę jak każdy początkujący może najprościej uruchomić w warunkach amatorskich mikrokontroler PIC32MX795F512H bez potrzeby trawienia/kupowania pod niego konkretnego PCB. Oprócz minimalnego niezbędnego układu pracy tego mikrokontrolera umieszczę tutaj kilka przykładowych kodów/projektów które będą napisane w dwóch środowiskach: w Mikro C PRO for PIC32 oraz w MPLAB X z kompilatorem XC32.
    Wszystkie kody będą do pobrania, zamieszczę też schemat wykonanych połączeń.

    Wstęp
    Bohaterem tematu jest 32-bitowy PIC32MX795F512H w obudowie TQFP-64:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    PIC32MX795F512H występuje tylko w takich 'mniej przyjaznych' hobbystom obudowach, ale jest co uruchamiać:
    80MHz, 512KB pamięci Flash, 128KB SRAM, sześć modułów UART, trzy moduł SPI, 4 moduły I2C, sprzętowe wsparcie USB w trybie zarówno urządzenia, jak i hosta (!), dwa moduły CAN i znacznie więcej.
    PIC32MX795F512H uruchamiałem już na różne sposoby. Raz uruchomiłem go na samodzielnie wytrawionej płytce (tak, ze ścieżkami pod TQFP), innym razem na płytce, którą tylko zaprojektowałem, a wykonanie jej zleciłem chińskiej płytkarni.
    Tutaj jednak pokażę trzeci, najtańszy sposób, a mianowicie użycie gotowej uniwersalnej płytki pod dowolny układ w obudowie TQFP (lub podobnej).
    Taka płytka jest naprawdę bardzo tania a posiada wszystko czego potrzebujemy (dodatkowe zewnętrzne elementy też na nią można przylutować).
    W wielu sklepach online można kupić okazyjnie jej pojedyncze sztuki lub całe zestawy:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    wychodzi około 1-2zł za sztukę, jest to zdecydowanie taniej niż jakbyśmy zlecali produkcje kilku sztuk własnego PCB pod PICa lub nawet jakbyśmy chcieli samodzielnie coś wytrawiać.
    Taka płytka jest dość uboga (pasuje pod każdy układ w TQFP), ale naprawdę starcza, choć będziemy musieli do niej dolutować niezbędne elementy 'na pająka'...

    Schemat minimalnego wymaganego podłączenia
    Schemat minimalnego wymaganego podłączenia znajduje się w nocie katalogowej tego PICa w sekcji Basic Connection Requirements - obrazek RECOMMENDED MINIMUM CONNECTION:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    PIC32MX795F512H nie potrzebuje wielu zewnętrznych elementów do uruchomienia. Zasadniczo potrzeba tylko:
    - kilku kondensatorów 100nF (najlepiej na każdy pin zasilania, możliwie blisko PICa)
    - kondensatora 10uF na pin VCAP
    - rezystora 10k na pin MCLR
    - dodatkowo kondensator elektrolityczny rzędu kilku uF na zasilanie
    Rezystor 10 omów od zasilania sekcji analogowej pozwoliłem sobie pominąć, choć też warto go przylutować. Oczywiście sekcja analogowa powinna być zasilana, nawet jeśli z niej nie korzystamy.
    Tyle wystarczy, by nieco podziałać z tym PICem, choć musimy mieć świadomość, że płytki idące na produkcje mają nieco większe wymagania. Nota katalogowa określa nawet największą zalecaną długość ścieżek od pinów do kondensatorów:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Nieco dalej w nocie jest też polecany sposób umieszczenia rezonatora kwarcowego przy tym PICu:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Na szczęście ten PIC posiada też wewnętrzny oscylator 8MHz, który sprawdza się do większości zastosowań poza m. in. USB.

    Lutowanie płytki
    Do lutowania użyłem najtańszej lutownicy grotowej z prostą regulacją temperatury:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Spoiwa lutowniczego 0.5mm:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Pasty do lutowania:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Oczywiście, Wy możecie mieć lepszy sposób na lutowanie.
    Po przylutowaniu PICa sprawdziłem, czy nie ma mostków pomiędzy jego nóżkami, nieliczne mostki usunąłem plecionką:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    PIC został przylutowany i teraz przyszła pora na niezbędne połączenia. Na początek punkty masy i zasilania (powinny być połączone poza PICem):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Dodatkowo przy każdym pinie zasilania powinien być kondensator 100nF:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Od spodu przylutowałem też kondensator Vcap, czyli 10uF:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Potem wziąłem się za blok zasilania. Ten PIC wymaga napięcia 3.3V, a nie 5V które mamy w USB. Do otrzymania stabilnego 3.3V z 5V użyłem regulatora LDO 3.3V TC1264 wraz z uniwersalną płytką wierconą i płytką breakout ze złączem USB oraz dodatkowymi kondensatorami (pary ceramiczny 100nF + elektrolityczny kilka uF):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    (w przypadku kondensatora elektrolitycznego po stronie 5V od USB należy pamiętać, by nie dać za dużej pojemności, bo taka pobierałaby za duży prąd z portu USB w momencie podłączenia, 4.7uF starczy)
    Złącze USB na pokładzie pozwoli wszystko wygodnie zasilać i w razie czego będą wyprowadzone też sygnały D+ i D- które możemy potem podprowadzić do PICa (ten PIC ma sprzętowe USB, a nawet może być hostem USB).
    Wszystko podłączyłem przewodami od płytek stykowych, by w razie czego łatwo było rozłączyć. Dodałem podwójne złącze goldpin 2.54mm które pasuje do użytej uniwersalnej płytki:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Gotowy blok zasilania podłączony do płytki z PICem:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Na koniec dodałem drobny rezystor 10k na pin MCLR od PICa (bez niego będzie dało się wykryć i programować PICa, ale program nie ruszy, chyba, że wyłączymy specjalnie funkcję RESET):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP

    Pierwsze wykrycie PICa
    PIC32 można programować w układzie poprzez ICSP. Użyłem do tego PICKIT3:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    PIC32MX795F512H ma kilka par pinów PGD/PGC, podłączyłem się do PGEC1, PGED1:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Dodatkowo oczywiście VDD, GND, i MCLR (pin reset).
    (Próbowałem też początkowo zasilić PICa z PICKIT3, ale były problemy - wykrywało za niskie napięcie na VDD i działało tylko jak ustawiłem w PICKIT3 VDD na nieco poniżej 3V, więc odpuściłem sobie takie komplikowanie. Może u Was będzie lepiej)
    Zatem do PICa podprowadziłem też z zewnątrz zasilanie (3.3V poprzez TC1264):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Tak podłączony PICKIT3 powinien poprawnie wykrywać PICa. Do kontroli PICKITa użyłem MPLAB X IPE 5.20:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Od tego momentu możemy wgrywać już na PICa swój firmware:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    A jeśli piszemy kod w MPLAB X z XC32 jest nawet prościej - nie trzeba używać MPLAB IPE, gdyż można kompilować i wgrywać soft jednym kliknięciem bezpośrednio z samego IDE.

    Przykład - MikroC PRO for PIC32 - Blink
    Zacznę od najprostszego przykładu, czyli migania diodą. Tutaj napisanego w Mikro C PRO for PIC32. Zrobienie migania diodą sprowadza się do:
    - poprawnego skonfigurowania oscylatora w ustawieniach projektu (wewnętrzny 8MHz)
    - ustawienia trybu pinów na wyjścia (rejestr TRIS*, określa on czy dany pin jest wejściem czy wyjściem)
    - wyłączenia JTAG (JTAGEN_bit, nieużywany przez nas JTAG może nam przeszkadzać na pinach)
    - wyłączenia ADC (rejestr AD1PCFG, bo piny AN* mają domyślnie włączony tryb analogowy)
    - odpowiedniego zmieniania wartości LAT* czyli wartości podanej na piny (gdy chcemy ustawiać wartość pinów użwamy LAT*, gdy chcemy odczytać to używamy PORT*)
    Pełny kod:
    Code: c
    Log in, to see the code

    W Mikro C prezentuje się tak:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Do tego oczywiście potrzebna jest jeszcze dioda z rezystorem. W rezultacie powinniśmy otrzymać miganie diodą:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Jeśli dioda miga ale z innym odstępem czasowym niż byśmy oczekiwali z kodu to znaczy, że być może źle skonfigurowaliśmy oscylator PICa.
    Załącznik (kod, projekt Mikro C PRO for PIC32 + hex):
    PIC32MX795...INTOSC.zip Download (196.46 kB)

    Przykład - MikroC PRO for PIC32 - Blink (przerwanie Timer1)
    Miganie diodą można też zrealizować w nieco lepszy sposób, bez niewygodnych funkcji oczekiwania w głównej pętli. Używa się do tego przerwań. MikroElektronika oferuje bardzo wygodne, darmowe narzędzie "MikroElektronika Timer Calculator" które pozwala nam wygodnie wygenerować kod konfiguracji timera:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Kod wprowadzony do mikro C:
    Code: c
    Log in, to see the code

    Poza odpowiednim ustawieniem Timera warto jest pamiętać, by w ogóle włączyć przerwania, czyli wywołać funkcję EnableInterrupts. Kod wygenerowany przez TimerCalculator nie zawiera tej linijki, co może sprawiać problemy początkującym którzy zapomną samodzielnie ją dodać.
    Można pobrać go za darmo stąd:
    https://libstock.mikroe.com/projects/view/398/timer-calculator
    Załącznik (kod, projekt Mikro C PRO for PIC32 + hex):
    PIC32MX795...INTOSC.zip Download (205.52 kB)

    Przykład - MikroC PRO for PIC32 - UART_Write
    Do UART w Mikro C PRO for PIC32 jest gotowa biblioteka, dostępna od razu z IDE. Obsługuje ona wszystkie dostępne porty UART:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Dla wygody wybrałem UART3, czyli ten port do którego miałem już przylutowane goldpiny:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Po stronie komputera użyłem przejściówki USB<->UART i programu RealTerm:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Użycie UART w MikroC właściwie sprowadza się do inicjalizacji wybranego portu na dany baud i potem wypisywania przez niego tego co chcemy.
    Pełny kod przykładu:
    Code: c
    Log in, to see the code

    Rezultat na UART:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Jeśli odbieramy ''krzaczki''/losowe znaki zamiast oczekiwanego tekstu to być może mamy różne ustawienia baud na PICu i na komputerze. Jeśli oba baudy są takie same, to zapewne zegar/oscylator PICa jest źle skonfigurowany...
    Załącznik (kod, projekt Mikro C PRO for PIC32 + hex):
    PIC32MX795...INTOSC.zip Download (203.35 kB)

    Przykład - MikroC PRO for PIC32 - UART_Read
    UART zapewnia oczywiście komunikację w obie strony. Możemy też odebrać za jego pomocą jakieś dane na PICu. Dla uproszczenia odbiorę tutaj jeden znak. W momencie odebrania znaku zmienię stan diody LED (byśmy wiedzieli, że coś się odbiera).
    Odbieranie można zrealizować na dwa sposoby:
    - można często w pętli sprawdzać, czy jest coś odebrane i jeśli jest, to to odczytać (poprzez bibliotekę)
    - można obsłużyć je w przerwaniu od UART (ręcznie, od razu gdy coś się odbierze)
    Użyję tej pierwszej metody. Są do tego funkcje UART3_Data_Ready i UART3_Read (dla innych UART analogicznie).
    Pełen przykład:
    Code: c
    Log in, to see the code

    W powyższym kodzie też zliczam ilość odebranych znaków. Warto zwrócić uwagę też na sposób zamiany typu liczby całkowitej int na napis (tablicę charów), jest do tego funkcja sprintf. Sam UART3_Write_Text niestety nie jest w stanie formatować tekstu tak jak ogólnie znany printf.
    Rezultat (miganie diody):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Rezultat w Real Term (zwiększenie licznika następuje gdy wyślę jeden znak przez terminal):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Załącznik (kod, projekt Mikro C PRO for PIC32 + hex):
    PIC32MX795...ounter.zip Download (285.39 kB)Points: 0.22 for user

    Przykład - MikroC PRO for PIC32 - ADC
    Mamy już działający UART, można go teraz użyć do zrealizowania przykładu ADC, czyli przetwornika analogowo-cyfrowego. Pozwala on nam zmierzyć napięcie na danym pinie i przedstawić je w postaci cyfrowej, czyli po prostu zmienić na liczbę typu int. Tutaj ADC jest 10-bitowe, odczyt 0 oznacza 0V, a 1023 oznacza tutaj 3.3V (napięcie zasilania PICa; może jednak być inaczej, jak używamy zewnętrznego Vref). Dostępne piny oferujące wejście analogowe (AN) są podane w nocie katalogowej. Wybrałem pin AN5:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    W Mikro C mamy do ADC gotową biblioteką która wykona za nas większość pracy:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Moduł ADC 1 (nie pin AN1, tylko cały moduł) uruchamiamy funkcją ADC1_Init a potem możemy odczytywać wartości z różnych pinów AN* poprzez ADC1_Read(index_pinu).
    Musimy jednak pamiętać o tym, by ustawić odpowiedni pin cyfrowy (znajdujący się na pinie AN którego chcemy użyć) na tryb wejścia, linijka TRISB |= 32; w przykładzie poniżej:
    Code: c
    Log in, to see the code

    Na wybrany pin podłączyłem "nastawny dzielnik napięcia", czyli najzwyklejszy potencjometr (środkowy odczep do pinu, a skrajne na masę i zasilanie):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    UWAGA: Jak nie ustawimy danego portu ADC w tryb wejścia to będziemy otrzymywać z ADC niepoprawne wyniki, ja otrzymywałem ciągle "1023".
    Rezultat w RealTerm w trakcie obracania potencjometrem:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Załącznik (kod, projekt Mikro C PRO for PIC32 + hex):
    PIC32MX795...SC_adc.zip Download (287.2 kB)Points: 0.22 for user

    Przykład - MikroC PRO for PIC32 - I2C skaner
    Uruchomiliśmy już UART, teraz pora na I2C.
    PIC32MX oferuje kilka magistrali I2C. W Mikro C jest dla nich gotowa biblioteka:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    I2C wykorzystuje do komunikacji dwa piny - SCL (zegar) oraz SDA (data). Do tego przykładu wybrałem moduł I2C1 z PICa, czyli piny SCL1 i SDA1:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Magistrala I2C jest o tyle lepsza od UART, że pozwala na podłączenie naprawdę wielu urządzeń - ich liczba jest ograniczona dostępną ilością adresów I2C.
    To właśnie te adresy urządzeń będzie wykrywać ten przykład - przykład będzie skanować całą magistralę I2C i sprawdzać czy jest do niej coś podłączone.
    Kod skanera pozornie sprawdza "co drugi adres" I2C, to dlatego, że najmłodszy bit tak naprawdę określa to czy chcemy odbierać dane czy wysyłać do danego urządzenia, a sam jego adres to starsze 7 bitów.
    Adresy wykrytych urządzeń będą wysyłane na UART.
    Pełny kod:
    Code: c
    Log in, to see the code

    Jednakże aby ten przykład miał jakiś sens, musimy coś podłączyć na I2C.
    W celach demonstracyjnych wybrałem TC74 (termometr w TO220):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Linie SCLK i SDA wymagają rezystorów pull-up.
    Zdjęcie pokazuje sposób podłączenia TC74 na płytce stykowej wraz z rezystorami (potencjometr nie jest używany w tym przykładzie):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Schemat połączeń powyżej (dioda LED do migania i podłączenie UART pominięte):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Rezultat, wyniki skanu. PIC poprawnie wykrywa adres tego TC74:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Na koniec dodam, że warto pamiętać, iż niektóre urządzenia I2C albo dają możliwość wyboru swojego adresu poprzez podpinanie swoich wybranych pinów do masy/zasilania (piny 'A0' ,'A2', itp), bądź mają różne adresy wgrane fabrycznie. TC74 jest dostępny w kilku wariantach o różnych adresach:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Załącznik (kod, projekt Mikro C PRO for PIC32 + hex):
    PIC32MX795...INTOSC.zip Download (292.5 kB)Points: 0.23 for user

    Przykład - MikroC PRO for PIC32 - I2C termometr TC74
    Warto jeszcze pokazać jak wygląda użycie I2C w praktyce. Sam sposób użycia I2C zależy od urządzenia (na I2C zrealizowane są różne protokoły), ale podstawowy budulec komunikacji (funkcje I2C_Read, I2C_Write) są wszędzie takie same.
    Sposób odczytu temperatury z TC74 opisany jest w jego nocie katalogowej:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Do odczytu temperatury służy komenda RTR (Read Temperature) o kodzie 00h. Zwraca ona temperature zakodowaną jako 8-bitową liczbę całkowitą.
    W I2C najpierw musimy wykonać Write (wysłać 00h do urządzenia), a potem Read (odczytać wartość temperatury).
    Pełny kod poniżej:
    Code: c
    Log in, to see the code

    Rezultat odczytu temperatury pokojowej u mnie w warsztacie:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Reakcja po dotknięciu palcem:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Załącznik (kod, projekt Mikro C PRO for PIC32 + hex):
    PIC32MX795...INTOSC.zip Download (295.55 kB)Points: 0.23 for user

    Przykład - MikroC PRO for PIC32 - PWM
    Uruchomienie PWM w Mikro C na PIC32 wymaga od nas tylko wywołania jednej funkcji i podania częstotliwości oraz wypełnienia generowanego sygnału prostokątnego.
    W tym przykładzie uruchomię wyjście PWM 1, czyli OC1:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Do tego wystarczy użyć trzech funkcji. Częstotliwość podajemy w PWM_Init, a wypełnienie określamy jako część wartości pwm_period1 (pwm_period1 odpowiada 100% wypełnienia, pwm_period1/2 odpowiada 50%, itp).
    Przykładowy kod (1000Hz, 50% wypełnienie):
    Code: c
    Log in, to see the code

    Rezultat na oscyloskopie:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Analogicznie, dla 33.3% wypełnienia i 2kHz:
    Code: c
    Log in, to see the code

    Rezultat na oscyloskopie:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Możemy też podejrzeć wartość pwm_period1 za pomocą UART:
    Code: c
    Log in, to see the code

    Rezultat (dla 1kHz):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    (warto tutaj zaznaczyć, że to PWM działa w oparciu o jeden z timerów PICa i nam go zajmuje, i jeśli mu nadpiszemy np. licznik przepełnienia to popsujemy sobie PWM)

    Przykład - MikroC PRO for PIC32 - PWM - Jasność diody LED
    Nie każdy jednak ma oscyloskop. Na szczęście działanie PWM można zobrazować znacznie łatwiej. W tym przykładzie użyję PWM do kontroli jasności diody LED.
    Kod zmodyfikowałem odpowiednio tak, by wypełnienie PWM rosło od 0 do 100%:
    Code: c
    Log in, to see the code

    Rezultat na filmiku (dioda stopniowo zwiększa swoją jasność i gaśnie):



    Można też popatrzeć jak to wygląda na oscyloskopie:



    Załącznik (kod, projekt Mikro C PRO for PIC32 + hex):
    PIC32MX795...INTOSC.zip Download (208.59 kB)

    Przykład - MPLAB/XC32 - Blink
    W MPLAB/XC32 potrzebujemy nieco więcej kodu by móc zamruga diodą. Na szczęście ten kod będziemy mieli już gotowy i nie musimy go pisać za każdym razem od 0. Przy okazji mamy tutaj też własną funkcję delay_ms, w oparciu o Timer. Przykład stąd bazowałem na jednym z przykładów dla PIC32MX2*, ale przeportowałem go pod PICa z tematu. Pełny kod poniżej:
    Code: c
    Log in, to see the code

    Zrzut ekranu z IDE:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Kod stąd wykonuje też rzeczy o których wspomniałem w przypadku Mikro C, np. wyłącza JTAG. Tyle wystarczy by zamigać diodą przy użyciu wewnętrznego oscylatora z PICa.
    Załącznik (kod, projekt MPLAB X + hex):
    XC32_PIC32...link.X.zip Download (65.26 kB)

    Przykład - MPLAB/XC32 - UART
    W MPLAB/XC32 mamy słynną funkcję printf (strumień stdio) która obsługuje też zamianę różnych typów na tekst (znaczniki %i, %f, itp.) i pozwala wypisać go na wybrany przez nas port UART. Dzięki temu nie musimy osobno korzystać ze sprintf tak jak w Mikro C.
    Aby z niej korzystać musimy do poprzedniego przykładu dodać nagłówki stdio.h i plib.h.
    Dodatkowo trzeba dopisać krótką funkcję która wysyła jeden znak na UART (ona jest wewnętrznie linkowana z printfem):
    Code: c
    Log in, to see the code

    Funkcja ta jest znajdywana po nazwie przez linkera, więc musi nazywać się "_mon_putc". Linker nie da nam żadnych błędów jeśli nazwiemy ją inaczej, gdyż posiada ją już zdefiniowaną wewnętrznie z atrybutem ''weak linking'', ale wtedy nie będzie ona wywoływana. Więc nazwa musi być taka jak pokazałem.
    Warto zwrócić uwagę, że ta implementacja _mon_putc jest blokująca, tzn. blokuje wykonanie programu dopóki znak nie zostanie wysłany. Można by to zrealizować inaczej - dodawać znaki do bufora i wysyłać w tle.
    Uruchomienie UART wymaga ustawienia wartości z dwóch rejestrów - U3MODEbits i U3STAbits.
    Do ustawienia baud używa się UARTSetDataRate.
    Poniżej pełny przykład:
    Code: c
    Log in, to see the code

    Kod miga diodą i wypisuje kolejne liczby na UART. Rezultat:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Załącznik (kod, projekt MPLAB X + hex):
    XC32_PIC32...ART2.X.rar Download (79.65 kB)

    Przykład - MPLAB/XC32 - I2C skan
    W samym MPLAB/XC32 nie znalazłem gotowych funkcji do I2C, ale na szczęście ich implementacja nie jest trudna. Możemy bardzo łatwo odwzorować tutaj mechanizmy z Mikro C za pomocą tylko kilku linijek kodu. Wszystko sprowadza się do odpowiednich operacji na rejestrach powiązanych z danym modułem I2C (dla I2C1 to są I2C1BRG, I2C1CONbits, I2C1STATbits, I2C1TRN do transmisji i I2C1RCV do odbioru):
    Code: c
    Log in, to see the code

    (kod powyżej bazowałem na przykładach z internetu, dodatkowo dostosowałem go tak by konwencja nazewnictwa była zgodna z tym co było w Mikro C)
    Po zrobieniu kodu powyżej pozostaje nam tylko proste przeportowanie wcześniej przedstawionego przykładu skaneru I2C.
    Gotowy kod:
    Code: c
    Log in, to see the code

    W kodzie zmieniłem nieco komunikaty UART, by było widać, że to jest wsad z XC32. Rezultat:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Wszystko działa - termometr TC74 na linii I2C jest wykrywany.
    Załącznik (kod, projekt MPLAB X + hex):
    XC32_PIC32...Scan.X.zip Download (96.05 kB)

    Przykład - MPLAB/XC32 - I2C termometr TC74
    Mamy już gotową podstawę funkcji dla I2C, więc obsługę TC74 też można łatwo przerzucić. Gotowy kod:
    Code: c
    Log in, to see the code

    Posiadanie ustandaryzowanych nazw funkcji pomiędzy różnymi IDE/kompilatorami jest bardzo wygodne, umożliwia łatwe przenoszenie kodu.
    Rezultat:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Załącznik (kod, projekt MPLAB X + hex):
    XC32_PIC32...TC74.X.zip Download (96.7 kB)

    Przykład - MPLAB/XC32 - PWM
    PWM w MPLAB/XC32 jest proste do uruchomienia, choć i tak nieco bardziej skomplikowane niż w Mikro C. Są do tego gotowe funkcje w bibliotece plib. Zasadniczo potrzebne będą nam trzy:
    - OpenOC1
    - OpenTimer2
    - SetDCOC1PWM
    Tutaj widzimy nieco więcej szczegółów działania PWM na PIC32MX niż w przypadku Mikro C. PWM opiera się o tryb Compare timera i działa tak, że:
    - częstotliwość PWM określa licznik przepełnienia timera (PR2)
    - stopień wypełnienia określa argument SetDCOC1PWM (jego wartość może być od 0 do wartości PR2)
    Samą częstotliwość PWM musimy przełożyć na wartość licznika przepełnienia timera (tutaj timera 2) sami, choć możemy posłużyć się do tego makrem.
    Trzeba wziąć pod uwagę wartość preskalera timera i częstotliwość pracy PICa:
    Code: c
    Log in, to see the code

    Funkcję GetSystemClock() mamy zdefiniowaną wcześniej w podanym przeze mnie szablonie main/blink LED.
    Poniżej pierwszy przykład - ustawia wypełnienie PWM na 50%, częstotliwość 1000Hz.
    (PWM opiera się tu na Timerze 2, wartość PR2 odpowiada 100% wypełnienia, wiec PR2/2 to 50%, itp)
    Code: c
    Log in, to see the code

    Tak możemy wygenerować szeroką gamę częstotliwości, choć trzeba pamiętać, by ustawienie #define PRESCALE 1 odzwierciedlać argumentem T2_PS_1_1 (jak zmieniamy jedno, to też trzeba drugie).
    Rezultat (1kHz 50% wypełnienia):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    To samo, ale po zmianie ustawienia wypełnienia na:
    Code: c
    Log in, to see the code

    Rezultat (1kHz 75% wypełnienia):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Możemy też skorzystać z UART by podejrzeć wartość zmiennej TICKS (czyli PR2):
    Code: c
    Log in, to see the code

    Dla 1kHz wynosi ona:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Powyższe makro działa dla różnych częstotliwości.
    Załącznik (kod, projekt MPLAB X + hex):
    XC32_PIC32..._PWM.X.zip Download (97.45 kB)

    Przykład - MPLAB/XC32 - Urządzenia USB HID - Klawiatura
    Na PIC32MX można zrealizować też łatwo wiele projektów powiązanych z USB. Da się zarówno zrobić urządzenia USB (klawiaturę, myszkę, pamięć, itp.) jak również i hosta USB (obsłużyć np. zewnętrzną klawiaturę).
    Tutaj pokażę jak zrealizować prostą klawiaturę USB która będzie wysyłać kolejne znaki po wciśnięciu przez nas przycisku na płytce stykowej.
    Nie jest to skomplikowane, mój "pająk" z tego tematu starczy - trzeba tylko będzie dolutować do niego zewnętrzny rezonator 8MHz:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Wewnętrzny rezonator tego PICa nie jest na tyle dokładny by dobrze sprawdzać się w zastosowaniach USB:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    (zrzut ekranu z PIC32 USB Starter Kit II User’s Guide, warto poczytać).
    Rezonator dolutowałem od spodu płytki:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Trzeba też będzie podłączyć piny powiązane z USB:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Czyli:
    - D+ (do D+ z kabla USB)
    - D- (do D- z kabla USB)
    - VBUS (5V, do 5V z kabla USB)
    - VUSB (do VDD czyli do 3.3V; bez tego nie zadziała)
    Pinu USBID nie podłączałem (on służy do określenia czy jesteśmy hostem czy device, ale tu nie jest potrzebny).
    Do USB mamy gotową bibliotekę i całe mnóstwo przykładów. Są przykłady klawiatury, myszki i wielu innych urządzeń. Wszystko macie m. in tutaj:
    https://github.com/mentatpsi/Microchip/tree/master/USB
    Przykłady powyżej dostępne są dla wielu PICów z różnych rodzin, PIC18F, PIC24 i też PIC32. Jest też przykład dla bliźniaczego PIC32MX795F512L (tutaj używam PIC32MX795F512H), więc mamy zasadniczo wszystko gotowe, wystarczy zmienić tylko kilka #ifdef i ustawienie mikrokontrolera z projektu.
    Kod jest za długi by go tu opisać, ale w dużym skrócie w Keyboard.c posiadamy funkcję Keyboard:
    Code: c
    Log in, to see the code

    Sprawdza ona czy przycisk jest wciśnięty i kolejno wysyła kolejne znaki (key++). Tajemnicza funkcja Switch3IsPressed() jest zdefiniowana nieco wyżej, ona po prostu sprawdza, czy zmienił się stan przycisku na wciśnięty:
    Code: c
    Log in, to see the code

    Zostaje jeszcze kwestia sw3 - ono jest zdefiniowane w odpowiednim HardwareProfile.h, dla mojej płytki jest to
    Code: c
    Log in, to see the code

    czyli po prostu odczyt stanu z portu.
    Przycisk na RD7 podłączony jest wraz z rezystorem pull-up:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Oprócz tego warto jest jeszcze wiedzieć o pliku usb_descriptors.c. Opisuje on jak będzie nasze urządzenie widoczne przez komputer. Znajduje się tam tzw. deskryptor USB:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Możemy tam zmienić np. nazwę naszego urządzenia.
    Tyle teorii, teraz pora sprawdzić, czy wszystko działa.
    Po pierwszym podłączeniu PICa do komputera nasz system powinien wykryć nowe urządzenie:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Więcej szczegółów o wykrytym urządzeniu możemy znaleźć w menedżerze urządzeń albo w wygodniejszym do tego celu programu USBDevView:
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Teraz pora na główny test - czy PIC może pełnić rolę klawiatury?



    Jak najbardziej tak. Przyciski są poprawnie odbierane przez komputer. Na bazie tego przykładu możemy zrealizować też dowolny joystick, pad i myszkę - wystarczy zmodyfikować deskryptor USB i wysyłać inne dane, też poprzez HID.
    Schemat połączeń z powyższego przykładu (wraz ze złączem ICSP, diody LED pominięte):
    [Minitutorial PIC32] Uruchamiamy PIC32MX795F512H na uniwersalnej płytce pod TQFP
    Tylko tyle potrzeba by uruchomić USB device na PIC32MX795F512H.
    Załącznik (kod, projekt MPLAB X + hex):
    Device - H...d 2020.zip Download (271.88 kB)Points: 0.21 for user
    (Załącznik wymaga bibliotek z repozytorium git wspomnianego powyżej)

    Alternatywy do przedstawionych tu kompilatorów i środowisk
    Warto jeszcze wspomnieć, że nie jesteśmy skazani tylko na Mikro C albo XC32.
    Dla PIC32MX795F512H dostępne jest również:
    - kompilator GCC-MIPS-ELF
    https://github.com/PinguinoIDE/pinguino-compilers/tree/master/windows32/p32/bin
    https://blogs.fsfe.org/pboddie/?p=1654
    - środowisko Chipkit/MPIDE (oferuje pisanie programów w stylu Arduino i bootloader USB):
    https://chipkit.net/started/install-chipkit-software/install-mpide-windows/
    https://chipkit.net/wiki/index.php?title=Boards
    - środowisko Pinguino (oferuje pisanie programów w stylu Arduino i bootloader USB):
    https://pinguino.cc/

    Podsumowanie
    Pokazałem tutaj, że absolutnie każdy może w amatorskich warunkach uruchomić gołego PIC32MX795F512H na najtańszej, uniwersalnej płytce pod TQFP kosztującej niecałe 2 złote. Jak widać, do przygody z mocniejszymi PICami dostępnymi tylko w obudowach SMD wcale nie potrzeba żadnych droższych zestawów uruchomieniowych czy tam własnych zaawansowanych płytek zlecanych płytkarnii. Partyzantka z tematu działa, choć oczywiście trzeba mieć też świadomość, że długość ścieżek, ich pojemności, impedancja mają bardzo duże znaczenie i mogą powodować różnego rodzaju trudne do zdiagnozowania błędy i zakłócenia. Na dłuższą metę lepiej jest zaprojektować własne PCB i zlecić je płytkarni, ale na początek nauki metoda z tego tematu jak najbardziej starcza.
    Temat będzie jeszcze edytowany. Być może dodam jeszcze jakieś przykłady.

    Cool? Ranking DIY
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
    About Author
    p.kaczmarek2
    Moderator Smart Home
    Offline 
  • Computer Controls
  • #2
    JarekC
    Level 32  
    Tylko pytanie dlaczego ktoś miałby wybrać ten procesor,zresztą niezbyt tani 43PLN/szt (w TME).
    Płytka z 2PLN w stosunku do ceny procesora raczej nie ma tutaj znaczenia.
    W podobnej cenie można kupić gotową płytkę Nucleo od ST z wbudowanym debuggerem.

    Po przejęciu Atmela (z rodziną SAM uP ARM)przez Microchipa rodzina PIC32MX,MZ (oparta o rdzeń MPIS) raczej poszła w odstawkę.
    Wiele błędów krzemu ciągnie się w tych rodzinach od wielu lat i nie są naprawiane.
    Sam popełniłem projekty na PIC32MX270 i PIC32MZ1024EF ale wybór PIC32MX był podyktowany przez zleceniodawcę a PIC32MZ przez dostępność portu USB HS z wbudowanym PHY.
    Teraz to już straciło znaczenie bo są np. procesory LPC5xx od NXP.
    Jestem uczestnikiem forum Microchipa i ruch w zakładce PIC32 jest raczej niewielki

    Aby zachęcić kogoś do użycia PIC32 trzeba by wskazać jego zalety w stosunku do innych uP.
    Inną niezbyt przyjemną sprawą jest blokada optymalizacji kodu dla kompilatorów w wersjach bezpłatnych.
  • Computer Controls
  • #3
    bolek
    Level 35  
    Polityką microchipa nigdy nie był niski próg wejścia jak STM. Akurat 32MX675 płacę po dwie dychy, stosuje ze względu na ethernet i np FAT32 z kartą SD który łatwo się dało odpalić.

    32 bity skończyły się na wersji MX, które osobiście uważam za fajne procki i środowisko. MZty to tragedia, tam się zmusiłem do wersji z grafiką. Zaleta taka że ma DDR na plecach i jakoś to analogiczne do MX.

    Darmowa optymalizacja jest tylko do pierwszego stopnia, a to i tak mocno kompresuje kod. Nie dramatyzujmy, "twój procek nie jest lepszy niż mój" ;)
  • #4
    p.kaczmarek2
    Moderator Smart Home
    JarekC wrote:
    Tylko pytanie dlaczego ktoś miałby wybrać ten procesor,zresztą niezbyt tani 43PLN/szt (w TME).
    Płytka z 2PLN w stosunku do ceny procesora raczej nie ma tutaj znaczenia.

    Microchip wspiera studentów i jest możliwość otrzymania tego PICa za darmo, też w Polsce.

    JarekC wrote:
    Inną niezbyt przyjemną sprawą jest blokada optymalizacji kodu dla kompilatorów w wersjach bezpłatnych.

    W przypadku początkujących i hobbystów raczej większym problemem jest to, że oni sami piszą niewydajny kod (naprawdę różne rzeczy już widziałem). A jak ktoś robi profesjonalnie firmware to na jego poziomie już można zainwestować w licencję kompilatora.
  • #5
    JarekC
    Level 32  
    Z PIC32MZxxxxEC było chyba najgorzej, z serią jest EF już lepiej.
    Po wybraniu procesora do projektu należy w pierwszej kolejności przeczytać erratę i dotyczy to nie tylko Microchipa
    ale wszystkich producentów, bo naprawdę można się zdziwić co nie działa.
    Moje projekty skupione były wokół USB i np dla PIC32MZ dokumentacja poświęcona USB-HS jest cały czas "Preliminary",
    w której brakuje wielu ważnych informacji.
    Próba przebicia się przez pomoc techniczną Microchipa i zdobycie dodatkowych informacji skończyło się nie powodzeniem.
    Z MX nie miałem takich problemów, potem była jeszcze próba z PIC32MM ale klient zakończył projekt i próbki leżą w szufladzie.

    Dodano po 4 [minuty]:

    p.kaczmarek2 wrote:
    JarekC wrote:


    JarekC wrote:
    Inną niezbyt przyjemną sprawą jest blokada optymalizacji kodu dla kompilatorów w wersjach bezpłatnych.

    W przypadku początkujących i hobbystów raczej większym problemem jest to, że oni sami piszą niewydajny kod (naprawdę różne rzeczy już widziałem). A jak ktoś robi profesjonalnie firmware to na jego poziomie już można zainwestować w licencję kompilatora.


    Mógłbym to zrozumieć gdyby to był ich własny kompilator ale XC32 bazuje na GCC.