Mikrokontrolery Infineon XMC4500 w praktyce, część 7. Obsługa magistrali CAN
Zastosowaną w projekcie konfigurację przedstawiono na rysunku 8. W zakładce CAN Configuration wybrano normalny tryb pracy węzła CAN, dwa obiekty wiadomości (jeden do wysyłania ramek CAN, drugi do odbierania ramek CAN) i prędkość transmisji 500 kb/s. W zakładce Message Configuration pierwszy z obiektów wiadomości, o nazwie LMO2, został skonfigurowany do odbierania ramek CAN. Jako maska filtrowania tego obiektu wiadomości została ustawiona wartość 0, co pozwoli na odbieranie wiadomości o dowolnym identyfikatorze. Dla obiektu wiadomości LMO2 zaznaczona została ponadto opcja włączająca generowanie przerwań w momencie odebrania wiadomości. Drugi obiekt wiadomości, nazwany LMO1, został skonfigurowany do wysyłania ramek CAN. Wysyłane przy jego udziale ramki będą sygnowane identyfikatorem o wartości szesnastkowej 12.
Rys. 8. Zakładki konfiguracyjne komponentu CAN001
Aby odbiór wiadomości CAN realizowany był za pomocą przerwania, należy powiązać ze sobą komponenty CAN001 i NVIC002. Polega to na przypisaniu sygnału LMO2 Receive Interrupt (przerwanie wygenerowane przez odbiorczy obiekt wiadomości CAN) komponentu CAN001 do sygnału Interrupt Node komponentu NVIC002 (rysunek 9).
Rys. 9. Skojarzone ze sobą sygnały komponentu CAN001 i NVIC002
Jako ostatnia została do przeprowadzenia konfiguracja komponentu NVIC002. Zakładka tego komponentu udostępnia pola służące do :
- ustawienia priorytetu przerwania,
- włączenia/wyłączenia przerwania w momencie startu programu,
- wpisania nazwy funkcji przerwania.
W porównaniu do domyślnej konfiguracji włączono przerwanie w momencie startu programu oraz wpisano nazwę przerwania: EvenHandlerCAN (rysunek 10).
Rys. 10. Zakładka konfiguracyjna komponentu CAN001
Uwaga!
Opis powyższych czynności (dodawanie do projektu komponentów DAVE Apps, przyporządkowanie komponentom wyprowadzeń mikrokontrolera, ustawienie parametrów pracy komponentów, wiązanie ze sobą komponentów poprzez skojarzenie sygnałów) można znaleźć w drugim odcinku kursu poświęconego mikrokontrolerom XMC4000, który dostępny jest tutaj. |
Wymagane przez aplikację komponenty DAVE Apps zostały dodane do projektu oraz konfiguracja komponentów została zakończona, dlatego kolejnym krokiem jest uruchomienie generatora kodu, który na bazie wykonanych czynności wytworzy pliki z kodem źródłowym i doda je do projektu.
W tym momencie można przejść do edycji kodu pliku main.c. Jako że aplikacja wcześniej realizowała sterowanie portami wejścia/wyjścia, w pliku main.c znajduje się już kod źródłowy pozwalający na odczytywanie stanu przycisku i włączanie/wyłączanie diody LED (listing 1).
List. 1. Program odczytujący stan przycisku i włączanie/wyłączanie diody LED
#include bool Value = 0; int main(void) { // status_t status; DAVE_Init(); while(1) { Value = IO003_ReadPort(IO003_Handle0); if(Value == 0) { IO003_TogglePort(IO003_Handle1,1); } } return 0; } void delay (unsigned int count) { while (count != 0) { count--; } }
Teraz main.c trzeba zmodyfikować reorganizując istniejący kod i dodając kod źródłowy dla CAN. Plik ten powinien zostać uzupełniony o:
- deklarację zmiennej, do której zapisywany będzie status operacji wysłania wiadomości CAN,
- deklarację tablicy, w której przechowywane będą bajty danych wiadomości CAN do wysłania,
- deklarację typu strukturalnego do przechowywania odebranej wiadomości CAN,
- wywołanie funkcji wpisującej bajty danych z tablicy do obiektu wiadomości przeznaczonego do wysyłania wiadomości CAN,
- wywołanie funkcji wysyłającej wiadomość CAN,
- deklarację funkcji przerwania od odebrania wiadomości CAN,
- definicję funkcji przerwania od odebrania wiadomości CAN, składającą się z:
- wywołania funkcji sprawdzającej status obiektu wiadomości przeznaczonego do odbierania wiadomości CAN,
- instrukcji warunkowej if sprawdzającej wartość zwróconą przez powyższą funkcję,
- wywołanie funkcji zerującej status obiektu wiadomości przeznaczonego do odbierania wiadomości CAN,
- wywołanie funkcji odczytującej odebraną wiadomość CAN i przekazującą ją do zadeklarowanej wcześniej struktury,
- wywołanie funkcji zmieniającej stan portu (sterowanie diodą LED),
- wywołanie funkcji opóźnienia.
Po dokonaniu wymienionych zmian zawartość pliku main.c powinna prezentować się tak jak na listingu 2.
List. 2. Kod źródłowy aplikacji
#include uint32_t Status = CAN001_ERROR; uint8_t Data[8] = {0xBC,0x11,0x22,0xA5,0xEF,0xFF,0x89,0x01}; CAN001_MessageHandleType CanRecMsgObj; bool Value = 0; int main(void) { DAVE_Init(); while(1) { Value = IO003_ReadPort(IO003_Handle0); if(Value == 0) { CAN001_UpdateMODataRegisters(&CAN001_Handle0,1,8,Data); Status = CAN001_SendDataFrame(&CAN001_Handle0,1); if(Status == DAVEApp_SUCCESS) { } } } return 0; } void EventHandlerCAN() { if(CAN001_GetMOFlagStatus(&CAN001_Handle0,2,RECEIVE_PENDING) == CAN_SET) { CAN001_ClearMOFlagStatus(&CAN001_Handle0,2,RECEIVE_PENDING); CAN001_ReadMsgObj(&CAN001_Handle0,&CanRecMsgObj,2); IO003_TogglePort(IO003_Handle1,1); delay(10000000); } } void delay (unsigned int count) { while (count != 0) { count--; } }
Program jest gotowy. Można go teraz skompilować, wgrać do pamięci mikrokontrolerów obu płytek XMC4500 Relax Kit i uruchomić lub debugować.