[NOWY FRAMEWORK] Microchip Harmony dla PIC32, część 2
Zobaczmy teraz jak wygląda możliwość przeniesienia naszego programu na inny mikrokontroler. Do tego celu zostanie wykorzystany moduł PIC32MZ EC Starter Kit z mikrokontrolerem PIC32MZ2048ECH144. Pracę z nowym mikrokontrolerem zaczynamy od utworzenia nowego projektu, uruchomienia MHC i skonfigurowania układu taktowania. Mikrokontrolery PIC32MZ mogą być taktowane częstotliwością do 200MHz, ale dla uproszczenia taktowanie będzie się odbywało z taką samą częstotliwością jak w module z PIC32MX czyli z 80MHz.
Rys. 14. Konfiguracja taktowania mikrokontrolera PIC32MZ
Na rysunku 14 pokazano okno MPLAB Harmony Clock Configuration dla układu taktowania mikrokontrolerów PIC32MZ. Źródłem sygnału zegarowego został wybrany wewnętrzny oscylator RC o częstotliwości 8MHz. Ten sygnał jest podawany na układ PLL, gdzie jest potem powielany przez 80 i dzielony przez 8. Taktowanie układów peryferyjnych jest podzielone na 8 grup. Dla każdej z tych grup można zdefiniować różne częstotliwości taktowania. Nas interesuje moduł liczników taktowany przez sygnał PBCLK3. Tu również ustawimy częstotliwość 80MHz.
W kolejnym kroku trzeba dodać konfigurację drivera Timer4/5 dokładnie tak samo jak w poprzednim przykładzie, oraz konfigurację BSP z modułem PIC32MZ EC Starter Kit. Kiedy te wszystkie czynności zostaną wykonane, to trzeba wygenerować pliki źródłowe (MHC – Generate) i zmodyfikować procedurę APP_Tasks. Ja po prostu skopiowałem całą funkcję z projektu z mikrokontrolerem PIC32MX. Włączenie opcji wsparcia modułów firmowych BSP spowodowało wygenerowanie definicji linii sterujących diodami LED. Jedyna modyfikacją jaką należy wprowadzić jest definicja portu. Diody LED są sterowane w module PIC32MX USB starter Kit II z portu PORTD, a w module PIC32MZ EC Starter Kit z portu PORTH.
List. 13. Funkcja APP_Tasks dla projektu z PIC32MZ
void APP_Tasks (void ) { /* Check the application's current state. */ switch (appData.state ) { /* Application's initial state. */ case APP_STATE_INIT: { SYS_PORTS_PinDirectionSelect(PORTS_ID_0, SYS_PORTS_DIRECTION_OUTPUT, PORT_CHANNEL_H ,BSP_LED_1); SYS_PORTS_PinDirectionSelect(PORTS_ID_0, SYS_PORTS_DIRECTION_OUTPUT, PORT_CHANNEL_H ,BSP_LED_2); DRV_TMR0_Start(); DRV_TMR0_CounterClear(); appData.state=APP_LED_ON; break; } case APP_LED_ON : { led=led&1; if(led==1) {SYS_PORTS_PinSet(PORTS_ID_0,PORT_CHANNEL_H ,BSP_LED_1); SYS_PORTS_PinSet(PORTS_ID_0,PORT_CHANNEL_H ,BSP_LED_2); appData.state=APP_LED_OFF;} } case APP_LED_OFF : { led=led&1; if(led==0) {SYS_PORTS_PinClear(PORTS_ID_0,PORT_CHANNEL_H ,BSP_LED_1); SYS_PORTS_PinClear(PORTS_ID_0,PORT_CHANNEL_H ,BSP_LED_2); appData.state=APP_LED_ON;} } case APP_NOP: { ; } /* The default state should never be executed. */ default: { /* TODO: Handle error in application's state machine. */ break; } } }