W mikrokontrolerach 32-bitowych firmy Microchip serii PIC32MM mamy do dyspozycji dodatkową funkcjonalność na portach I/O nazwaną Input Change Notification. Funkcjonalność polega na tym, że każdy praktycznie pin I/O może spełniać rolę przerwania zewnętrznego INT. Dowolny pin I/O skonfigurowany jako wejście jest w stanie wykryć nam zmianę sygnału podanego na wejście i wygenerować przerwanie. W sumie jest to bardzo ciekawa funkcjonalność i przydatna w praktyce. Możemy ustawić dowolny pin I/O tak aby generował przerwanie po nadejściu zbocza narastającego lub/i opadającego. W artykule pokażę jak ustawić tę funkcjonalność i zdefiniować przerwanie. Moim bazowym mikrokontrolerem jest PIC32MM0256GPM048 i do niego odnoszę ten wpis, aczkolwiek wszystko co piszę tutaj odnosi się do całej rodziny PIC32MM.
Na początek założenie co chcemy uzyskać. Na wybranym pinie RA2 chcę wykrywać zmiany sygnału z 1 na 0 (zbocze opadające) i wygenerować po tym fakcie przerwanie. Poniżej kroki jakie trzeba wykonać :
1. Ustawiamy pin RA2 jako wejście (Input) :
TRISAbits.RA2 = 1;
2. Podciągamy wejście RA2 do High :
CNPUAbits.CNPUA2 = 1;
3. Konfigurujemy rodzaj detekcji w naszym przypadku z 1 na 0 (zbocze opadające) :
CNCONAbits.CNSTYLE = 1;
CNEN1Abits.CNIE1A2 = 1;
CNEN0Abits.CNIE0A2 = 0;
3. Konfigurujemy rodzaj detekcji w naszym przypadku z 1 na 0 (zbocze opadające) :
CNCONAbits.CNSTYLE = 1;
CNEN1Abits.CNIE1A2 = 1;
CNEN0Abits.CNIE0A2 = 0;
poniżej tabelka z której odczytujemy jak konfigurować rejestry dla różnych rodzajów detekcji :
4. Ustawiamy priorytet dla przerwań :
IPC2bits.CNAIP = 2; /*priority = 2*/
IPC2bits.CNAIS = 1; /*sub priority = 1*/
5. Zerujemy profilaktycznie flagi :
IFS0CLR = 1 << _IFS0_CNAIF_POSITION ; /*atomic clear flag*/
CNFAbits.CNFA2 = 0 ; /*normal clear status*/
i tu istotna bardzo uwaga , po wystąpieniu przerwania koniecznie należy wyzerować odpowiedni bit w rejestrze CNFx , jeśli tego nie zrobimy to przerwanie wywoła się tylko raz a potem będziemy się drapać w głowę czemu tak, skoro wyzerowaliśmy podstawową flagę przerwania IFS0
6. Włączamy przerwanie :
IEC0bits.CNAIE = 1;
7. Definicja przerwania CN :
/*Routime CN Interrupt for PORTA*/
void __attribute__((vector(_CHANGE_NOTICE_A_VECTOR), interrupt(IPL2SOFT))) CN_ISR()
{
/*kod użytkownika*/
/*zerowanie statusu CN dla pinu RA2*/
CNFAbits.CNFA2 = 0 ;
/*zerowanie flagi przerwania*/
IFS0CLR = 1 << _IFS0_CNAIF_POSITION ;
}
Numerek w IPLxSOFT dajemy taki jak numer priorytetu w naszym przypadku jest to cyfra 2.
Od tego momentu po każdej zmianie sygnału z 1 na 0 na pinie RA2 zostanie wywołane przerwanie i taki efekt możemy uzyskać na każdym pinie I/O w PIC32MM
Funkcjonalność tę wykorzystałem w projekcie z kontrolerem CAN FD MCP2517FD po stronie węzła odbierającego ramkę. Przerwanie występuje po nadejściu każdej ramki CAN i działa to doskonale.
Pozdrawiam
picmajster.blog@gmail.com
Funkcjonalność tę wykorzystałem w projekcie z kontrolerem CAN FD MCP2517FD po stronie węzła odbierającego ramkę. Przerwanie występuje po nadejściu każdej ramki CAN i działa to doskonale.
Pozdrawiam
picmajster.blog@gmail.com
Czy próbowałeś zapisu do pamięci Flash zmiennej a potem odczyt , inkrementacja i kolejny zapis do tej samej komórki?
OdpowiedzUsuńPowoduje to zawieszenie uP i po włączeniu zasilania już nie rusza , problem wrzuciłem na forum https://www.microchip.com/forums/m1057087-p2.aspx (pic32mm0256GPM)
Nie korzystałem z zapisu do Flasha ale zrobię to w takim razie. Widzę trochę rejestrów obsługujących flash może tam trzeba zajrzeć . Spróbuj zapisać zmienną samymi rejestrami NVMDATA i NVMADDR. Spróbuję rozpoznać temat.
OdpowiedzUsuńPierwszy zapis jest prawidłowy (bo zmieniłem w funkcji unlock dodając lininijkę NVMCONbits.WREN=0;potem dopiero bity NVMOP, podając od razu np: 0x4002 nie odblokuje się pamięci i brak zapisu) , ta druga próba zapisu powoduje crash totalny. Chciałem zrobić licznik uruchomień zrobić na przykład
OdpowiedzUsuńrozwiązałem , należy zrobić ERASE PAGE po odczycie a potem znowu zapisać ;-)
OdpowiedzUsuńWidzę , że rozwiązałeś sobie sam problem na forum Microchipa i przy okazji uchwyciłeś błąd w manualu Flash. Brawo. No i fajnie, że masz w nicku ...Polska, niech wiedzą jankesi , że Polacy są the best w rozwiązywaniu problemów. W końcu to my złamaliśmy Enigmę.
OdpowiedzUsuńUdało się dzięki podpowiedzi że jednak strony trzeba zerować . Zaglądam na twój blog , bo to jedyna w języku polskim strona o pic32mm jaką znam . Także w domu już mam płytki twojego projektu aby się szkolić , na razie mam to wszystko podstawkach
OdpowiedzUsuńJeśli chcesz coś świrować z pamięcią to spróbuj EERAM Microchipa, to naprawdę genialny wynalazek. PIC32MM jest w/g mnie optymalnie skrojonym prockiem dla hobbysty można za pomocą niego beztresowo wejść w świat 32-bitów. W 32-bitach ta seria jest wspierana przez MCC i to jest dodatkowy plus.I nie ma jak np. w świecie STM32 zagrożenia, że jak zaczniesz używać jakieś biblioteki do programowania to się za jakiś czas okaże, że biblioteka jest przestarzała i nie zalacana przez producenta. Moje płytki to pikuś jest tutaj czytacz mojego bloga , który jest wirtuozem płytek z PIC32MM i to w docelowych aranżacjach. Jak bedziesz miał jakieś problemy, pytania to wal śmiało, jeśli będę potrafił to pomogę.
OdpowiedzUsuńWłaśnie po przejściu z avr nie moglem się odnaleźć w 32bitach. Nxp, stm32, xmc infineon nie podeszły mi. Pic32mm z mcc i mplab to akurat coś mi bliższego.
OdpowiedzUsuńTrochę jest tych min w manualach, widzę po blogu że nie tylko ja mam takie problemy. Dzięki, będę regularnie pisał
So what about CNCONAbits.ON = 1; ?
OdpowiedzUsuń