poniedziałek, 10 września 2018

Input Change Notification (ICN) w PIC32MM

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;

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

9 komentarzy:

  1. Czy próbowałeś zapisu do pamięci Flash zmiennej a potem odczyt , inkrementacja i kolejny zapis do tej samej komórki?
    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)

    OdpowiedzUsuń
  2. 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ń
  3. 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ń
  4. rozwiązałem , należy zrobić ERASE PAGE po odczycie a potem znowu zapisać ;-)

    OdpowiedzUsuń
  5. 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ń
  6. 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ń
  7. 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ń
  8. 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.
    Trochę jest tych min w manualach, widzę po blogu że nie tylko ja mam takie problemy. Dzięki, będę regularnie pisał

    OdpowiedzUsuń
  9. So what about CNCONAbits.ON = 1; ?

    OdpowiedzUsuń