Podstawowe informacje o przerwaniach .....
Podstawowe rejestry do obsługi przerwań w mikrokontrolerach PIC o których powinniśmy mieć pojęcie bawiąc się nimi to :
INTCON1: Interrupt Control Register 1 (Rejestr kontrolny)
W tym rejestrze interesuje nas tylko jeden bit oznaczony jako NSTDIS . Bit ten włącza lub wyłącza zagnieżdżenie przerwań. Jeśli korzystamy z priorytetów w przerwaniach to włączmy zagnieżdżenie.
Przykład :
INTCON1bits.NSTDIS = 0 ; /* włącz zagnieżdzenia przerwań */
INTCON2: Interrupt Control Register 2 (Rejestr kontrolny)
Ten rejestr dedykowany jest dla przerwań zewnętrznych INT0 – INT4. Ustawiamy w nim jakim zboczem jest przerwanie zewnętrzne wyzwalane. I w zasadzie tyle co powinniśmy o nim wiedzieć.
Przykład :
INTCON2bits.INT0EP = 0 ; /*zbocze narastające wyzwala przerwanie zewnętrzne INT0 */
IFSx (gdzie x od 0 do 4): Interrupt Flag Status Registers (Rejestr flagowy)
Każde przerwanie (zewnętrzne/wewnętrzne/od peryferiów) zgłasza swoje wystąpienie za pomocą ustawienia odpowiedniego bitu w rejestrze flkagowym IFSx. Jeśli na przykład Timer1 zgłosi przerwanie to w rejestrze IFS0 na bicie T1IF pojawi się stan logiczny „1”. Należy jednak pamiętać i jest to specyfika mikrokontrolerów PIC aby w funkcji obsługi wektora przerwania wyzerować bit flagi przyporządkowany do źródła przerwania. Czyli na przykład w przypadku Timer1 musimy ustawić w funkcji wektora obsługi przerwania T1IF = 0 ;. Przy inicjalizacji przerwania bit ten również należy wyzerować.
Przykład :
void __attribute__((interrupt, no_auto_psv))_T1Interrupt() /* tak wygląda funkcja przerwania dla Timer1. Uwaga na ilość dolnych _*/
{
/*kod użytkownika do obsługi przerwania*/
/* Clear Timer1 interrupt */
IFS0bits.T1IF = 0 ; /* (NazwaRejestru.nazwaBitu) zerowanie flagi dla Timer1.To zerowanie musi być koniecznie !!! */
/*lub inny prostszy zapis : _T1IF = 0 ; (_nazwaBitu)*/
}
IECx (gdzie x od 0 do 4) : Interrupt Enable Control Registers (Rejestr typu Włacz/Wyłącz przerwania dla poszczególnych źródeł )
W AVR włączaliśmy globalnie przerwania a tutaj włączamy indywidualnie dla wybranego źródła.
W myśl zasady to czego nie używamy to niech śpi i nie marnuje prądu.
Posłużymy się znowu Timer1 czyli to będzie nasze źródło przerwania.
W tym przypadku musimy odszukać w odpowiednim rejestrze IECx bitu dla Timer1.
Znajdujemy w IEC0 bit T1IE:(Timer1 Interrupt Enable bit). Aby właczyć przerwanie od Timer1 musimy ustawić ten bit na „1”. Odpowiednio ustawienie bitu T1IE na „0” wyłączy nam przerwanie od Timer1.
Widzimy , że jest to proste jak budowa cepa, musimy tylko zapamiętać , że jak chcemy skorzystać z źródła , które zgłasza przerwanie musimy te źródło włączyć w rejestrze IECx.
Przyład :
IEC0bits.T1IE = 1 ; /* włącz przerwanie od Timer1.*/
/* lub inny prostszy zapis : _T1IE = 1 ; */
IPCx (gdzie x od 0 do 17): Interrupt Priority Control Registers (Rejestr do ustawiania priorytetów dla zgłaszanych przerwań)
Mamy do wyboru 7 poziomów priorytetów. Im wyższa cyferka tym wyższy priorytet.
Czyli 7 to najwyższy priorytet dla przerwania a 1 najniższy. Wartość 0 wyłącza priorytetowość. Dla przykładu posłużmy się znowu Timer1. Chcemy ustawić priorytet dla zgłaszanego przerwania od Timer1 na poziomie 4. Szukamy w rejestrach IPCx bitów przyporządkowanych Timer1, znajdujemy je w IPC0, trzy bity oznaczone jako T1IP.
Przykład :
IPC0bits.T1IP = 0b100 ; /* ustaw priorytet na poziomie 4 dla przerwania od Timer1.*/
O co chodzi z tą całą priorytetowością :) Ano wyobraźmy sobie , że mamy dwa przerwania X i Y. X ma priorytet 4 a Y ma priorytet 5. Przerwanie X zostaje zgłoszone i wykonuje się akurat funkcja wektora przerwania, i wtedy pach przychodzi zgłoszenie przerwania Y o wyższym priorytecia. CPU zamraża na stosie funkcję wektora przerwania X i zajmuje się wektorem przerwania Y. Po obsłużeniu Y wraca do obsługi wektora X.
Jeśli oba przerwania nie miałyby ustawionego priorytetu to pierw zostaje wykonane w sposób kompletny przerwanie , które pierwsze zgłosiło się a następnie kolejne.
I to w zasadzie wszystko co zgrubsza powinniśmy wiedzieć o ustawianiu przerwań w PIC.
Są jeszcze dwa rejestry o istnieniu których można wiedzieć i zajrzeć sobie w ich noty :
SR: CPU Status Register – ustawiamy priorytety przerwań od CPU
CORCON: Core Control Register – współpracuje z rejestrem SR w zakresie zmiany zakresów poziomów priorytetów dla przerwań od CPU .W rejestrze tym wybieramy zakres 0-7 albo 8-15.
Link :
http://ww1.microchip.com/downloads/en/DeviceDoc/70304A.pdf
Podstawowe rejestry do obsługi przerwań w mikrokontrolerach PIC o których powinniśmy mieć pojęcie bawiąc się nimi to :
INTCON1: Interrupt Control Register 1 (Rejestr kontrolny)
W tym rejestrze interesuje nas tylko jeden bit oznaczony jako NSTDIS . Bit ten włącza lub wyłącza zagnieżdżenie przerwań. Jeśli korzystamy z priorytetów w przerwaniach to włączmy zagnieżdżenie.
Przykład :
INTCON1bits.NSTDIS = 0 ; /* włącz zagnieżdzenia przerwań */
INTCON2: Interrupt Control Register 2 (Rejestr kontrolny)
Ten rejestr dedykowany jest dla przerwań zewnętrznych INT0 – INT4. Ustawiamy w nim jakim zboczem jest przerwanie zewnętrzne wyzwalane. I w zasadzie tyle co powinniśmy o nim wiedzieć.
Przykład :
INTCON2bits.INT0EP = 0 ; /*zbocze narastające wyzwala przerwanie zewnętrzne INT0 */
IFSx (gdzie x od 0 do 4): Interrupt Flag Status Registers (Rejestr flagowy)
Każde przerwanie (zewnętrzne/wewnętrzne/od peryferiów) zgłasza swoje wystąpienie za pomocą ustawienia odpowiedniego bitu w rejestrze flkagowym IFSx. Jeśli na przykład Timer1 zgłosi przerwanie to w rejestrze IFS0 na bicie T1IF pojawi się stan logiczny „1”. Należy jednak pamiętać i jest to specyfika mikrokontrolerów PIC aby w funkcji obsługi wektora przerwania wyzerować bit flagi przyporządkowany do źródła przerwania. Czyli na przykład w przypadku Timer1 musimy ustawić w funkcji wektora obsługi przerwania T1IF = 0 ;. Przy inicjalizacji przerwania bit ten również należy wyzerować.
Przykład :
void __attribute__((interrupt, no_auto_psv))_T1Interrupt() /* tak wygląda funkcja przerwania dla Timer1. Uwaga na ilość dolnych _*/
{
/*kod użytkownika do obsługi przerwania*/
/* Clear Timer1 interrupt */
IFS0bits.T1IF = 0 ; /* (NazwaRejestru.nazwaBitu) zerowanie flagi dla Timer1.To zerowanie musi być koniecznie !!! */
/*lub inny prostszy zapis : _T1IF = 0 ; (_nazwaBitu)*/
}
IECx (gdzie x od 0 do 4) : Interrupt Enable Control Registers (Rejestr typu Włacz/Wyłącz przerwania dla poszczególnych źródeł )
W AVR włączaliśmy globalnie przerwania a tutaj włączamy indywidualnie dla wybranego źródła.
W myśl zasady to czego nie używamy to niech śpi i nie marnuje prądu.
Posłużymy się znowu Timer1 czyli to będzie nasze źródło przerwania.
W tym przypadku musimy odszukać w odpowiednim rejestrze IECx bitu dla Timer1.
Znajdujemy w IEC0 bit T1IE:(Timer1 Interrupt Enable bit). Aby właczyć przerwanie od Timer1 musimy ustawić ten bit na „1”. Odpowiednio ustawienie bitu T1IE na „0” wyłączy nam przerwanie od Timer1.
Widzimy , że jest to proste jak budowa cepa, musimy tylko zapamiętać , że jak chcemy skorzystać z źródła , które zgłasza przerwanie musimy te źródło włączyć w rejestrze IECx.
Przyład :
IEC0bits.T1IE = 1 ; /* włącz przerwanie od Timer1.*/
/* lub inny prostszy zapis : _T1IE = 1 ; */
IPCx (gdzie x od 0 do 17): Interrupt Priority Control Registers (Rejestr do ustawiania priorytetów dla zgłaszanych przerwań)
Mamy do wyboru 7 poziomów priorytetów. Im wyższa cyferka tym wyższy priorytet.
Czyli 7 to najwyższy priorytet dla przerwania a 1 najniższy. Wartość 0 wyłącza priorytetowość. Dla przykładu posłużmy się znowu Timer1. Chcemy ustawić priorytet dla zgłaszanego przerwania od Timer1 na poziomie 4. Szukamy w rejestrach IPCx bitów przyporządkowanych Timer1, znajdujemy je w IPC0, trzy bity oznaczone jako T1IP.
Przykład :
IPC0bits.T1IP = 0b100 ; /* ustaw priorytet na poziomie 4 dla przerwania od Timer1.*/
O co chodzi z tą całą priorytetowością :) Ano wyobraźmy sobie , że mamy dwa przerwania X i Y. X ma priorytet 4 a Y ma priorytet 5. Przerwanie X zostaje zgłoszone i wykonuje się akurat funkcja wektora przerwania, i wtedy pach przychodzi zgłoszenie przerwania Y o wyższym priorytecia. CPU zamraża na stosie funkcję wektora przerwania X i zajmuje się wektorem przerwania Y. Po obsłużeniu Y wraca do obsługi wektora X.
Jeśli oba przerwania nie miałyby ustawionego priorytetu to pierw zostaje wykonane w sposób kompletny przerwanie , które pierwsze zgłosiło się a następnie kolejne.
I to w zasadzie wszystko co zgrubsza powinniśmy wiedzieć o ustawianiu przerwań w PIC.
Są jeszcze dwa rejestry o istnieniu których można wiedzieć i zajrzeć sobie w ich noty :
SR: CPU Status Register – ustawiamy priorytety przerwań od CPU
CORCON: Core Control Register – współpracuje z rejestrem SR w zakresie zmiany zakresów poziomów priorytetów dla przerwań od CPU .W rejestrze tym wybieramy zakres 0-7 albo 8-15.
Link :
http://ww1.microchip.com/downloads/en/DeviceDoc/70304A.pdf
PIC24HJ128GP502 Interrupt Vectors
The
table below specifies the interrupt vectors for these 16-bit devices.
IRQ# | Primary Name | Alternate Name | Vector Function |
---|---|---|---|
N/A | _OscillatorFail | _AltOscillatorFail | Oscillator Fail Trap Vector |
N/A | _AddressError | _AltAddressError | Address Error Trap Vector |
N/A | _StackError | _AltStackError | Stack Error Trap Vector |
N/A | _MathError | _AltMathError | Math Error Trap Vector |
N/A | _DMACError | _AltDMACError | DMAC Error Trap Vector |
0 | _INT0Interrupt | _AltINT0Interrupt | INT0 - External Interrupt 0 |
1 | _IC1Interrupt | _AltIC1Interrupt | IC1 - Input Compare 1 |
2 | _OC1Interrupt | _AltOC1Interrupt | OC1 - Output Compare 1 |
3 | _T1Interrupt | _AltT1Interrupt | T1 - Timer1 |
4 | _DMA0Interrupt | _AltDMA0Interrupt | DMA0 - DMA Channel 0 |
5 | _IC2Interrupt | _AltIC2Interrupt | IC2 - Input Capture 2 |
6 | _OC2Interrupt | _AltOC2Interrupt | OC2 - Output Compare 2 |
7 | _T2Interrupt | _AltT2Interrupt | T2 - Timer2 |
8 | _T3Interrupt | _AltT3Interrupt | T3 - Timer3 |
9 | _SPI1ErrInterrupt | _AltSPI1ErrInterrupt | SPI1E - SPI1 Error |
10 | _SPI1Interrupt | _AltSPI1Interrupt | SPI1 - SPI1 Transfer Done |
11 | _U1RXInterrupt | _AltU1RXInterrupt | U1RX - UART1 Receiver |
12 | _U1TXInterrupt | _AltU1TXInterrupt | U1TX - UART1 Transmitter |
13 | _ADC1Interrupt | _AltADC1Interrupt | ADC1 - A/D Converter 1 |
14 | _DMA1Interrupt | _AltDMA1Interrupt | DMA1 - DMA Channel 1 |
16 | _SI2C1Interrupt | _AltSI2C1Interrupt | SI2C1 - I2C1 Slave Events |
17 | _MI2C1Interrupt | _AltMI2C1Interrupt | MI2C1 - I2C1 Master Events |
18 | _CMPInterrupt | _AltCMPInterrupt | CMP - Comparator Interrupt |
19 | _CNInterrupt | _AltCNInterrupt | Change Notification Interrupt |
20 | _INT1Interrupt | _AltINT1Interrupt | INT1 - External Interrupt 1 |
22 | _IC7Interrupt | _AltIC7Interrupt | IC7 - Input Capture 7 |
23 | _IC8Interrupt | _AltIC8Interrupt | IC8 - Input Capture 8 |
24 | _DMA2Interrupt | _AltDMA2Interrupt | DMA2 - DMA Channel 2 |
25 | _OC3Interrupt | _AltOC3Interrupt | OC3 - Output Compare 3 |
26 | _OC4Interrupt | _AltOC4Interrupt | OC4 - Output Compare 4 |
27 | _T4Interrupt | _AltT4Interrupt | T4 - Timer4 |
28 | _T5Interrupt | _AltT5Interrupt | T5 - Timer5 |
29 | _INT2Interrupt | _AltINT2Interrupt | INT2 - External Interrupt 2 |
30 | _U2RXInterrupt | _AltU2RXInterrupt | U2RX - UART2 Receiver |
31 | _U2TXInterrupt | _AltU2TXInterrupt | U2TX - UART2 Transmitter |
32 | _SPI2ErrInterrupt | _AltSPI2ErrInterrupt | SPI2E - SPI2 Error |
33 | _SPI2Interrupt | _AltSPI2Interrupt | SPI2 - SPI2 Transfer Done |
34 | _C1RxRdyInterrupt | _AltC1RxRdyInterrupt | C1RX - ECAN1 Receive Data Ready |
35 | _C1Interrupt | _AltC1Interrupt | C1 - ECAN1 Event |
36 | _DMA3Interrupt | _AltDMA3Interrupt | DMA3 - DMA Channel 3 |
45 | _PMPInterrupt | _AltPMPInterrupt | PMP - Parallel Master Port |
46 | _DMA4Interrupt | _AltDMA4Interrupt | DMA4 - DMA Channel 4 |
61 | _DMA5Interrupt | _AltDMA5Interrupt | DMA5 - DMA Channel 5 |
62 | _RTCCInterrupt | _AltRTCCInterrupt | RTCC - Real-Time Clock and Calendar |
65 | _U1ErrInterrupt | _AltU1ErrInterrupt | U1E - UART1 Error |
66 | _U2ErrInterrupt | _AltU2ErrInterrupt | U2E - UART2 Error |
67 | _CRCInterrupt | _AltCRCInterrupt | CRC - Cyclic Redunancy Check |
68 | _DMA6Interrupt | _AltDMA6Interrupt | DMA6 - DMA Channel 6 |
69 | _DMA7Interrupt | _AltDMA7Interrupt | DMA7 - DMA Channel 7 |
70 | _C1TxReqInterrupt | _AltC1TxReqInterrupt | C1TX - ECAN1 Transmit Data Request |
Pozdrawiam
picmajster.blog@gmail.com
picmajster.blog@gmail.com
Very rapidly this web page will be famous among all blog users, due to it's nice content
OdpowiedzUsuń