LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
Artykuły

Obsługa interfejsu CAN w mikrokontrolerach STM32

Filtry akceptacyjne

Jak wspomniano, magistrala CAN jest siecią rozgłoszeniową, a więc na każdej stacji podłączonej do magistrali ciąży obowiązek filtrowania nadchodzących ramek i decydowania, czy otrzymane dane są przeznaczone dla niej, czy nie. Można do rozwiązania tego problemu podejść od strony programowej, jednak obciążenie mikroprocesora w tym przypadku nie będzie niezauważalne. Znacznie lepszym pomysłem jest filtrowanie ramek już na poziomie sprzętowym. Zadanie to jest wykonywane przez filtry akceptacyjne. Filtry można tak ustawić, aby do buforów odbiorczych były przepisywane jedynie ramki, które są przeznaczone dla danego węzła (np. mają zakodowany odpowiedni adres odbiorcy). Zyskiem z używania filtrów sprzętowych jest znaczne odciążenie rdzenia układu mikroprocesorowego, ponieważ obsługiwane są jedynie wiadomości przeznaczone dla danego urządzenia, reszta jest po prostu pomijana.

Aplikacja demonstracyjna

Omawiana aplikacja przykładowa może być w łatwy sposób przenoszona pomiędzy różnymi zestawami uruchomieniowymi wyposażonymi w mikrokontroler STM32 i układ nadajnika/odbiornika CAN (m.in. ZL29ARM). Przedstawiona konfiguracja dotyczy zestawu ewaluacyjnego STM3210B-EVAL z mikrokontrolerem STM32F103 oraz w transceiverem SN65HVD230, podłączonym do mikrokontrolera według schematu przedstawionego na rys. 9. Aplikację przygotowano z wykorzystaniem pakietu TrueSTUDIO firmy Atollic. W zastosowanym zestawie ewaluacyjnym transceiver podłączono do alternatywnych wyprowadzeń kontrolera CAN, a zatem do poprawnej pracy wymagane jest przemapowanie wyprowadzeń.

 

Alternatywnie do SN65HVD230 można stosować także układy: L9616, L9669, MCP2551 lub inne.

 

 

Rys. 9. Schemat połączeń pomiędzy mikrokontrolerem, a układem transceivera CAN

Rys. 9. Schemat połączeń pomiędzy mikrokontrolerem, a układem transceivera CAN

 

 

Po standardowej konfiguracji sygnałów zegarowych niezbędną czynnością potrzebną do poprawnej pracy układu kontrolera CAN, podobnie jak ma to miejsce dla wszystkich układów peryferyjnych wbudowanych w mikrokontrolery STM32, jest włączenie sygnału taktującego. Ta, oraz wszystkie pozostałe czynności konfiguracyjne związane z kontrolerem CAN są przeprowadzane w wywołaniu funkcji CAN_Configuration(), której ciało zamieszczono na list. 1. Przedstawiony fragment kodu jest wyraźnie podzielony na dwa bloki. Pierwszy odpowiada za konfigurację samego sterownika CAN, natomiast drugi wprowadza parametry pracy sprzętowego filtru akceptacyjnego ramek przychodzących.

 

List. 1. Funkcja CAN_Configuration()

void CAN_Configuration(void)
{
    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);

    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = DISABLE;
    CAN_InitStructure.CAN_RFLM = ENABLE;
    CAN_InitStructure.CAN_TXFP = DISABLE;
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    CAN_InitStructure.CAN_BS1 = CAN_BS1_10tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;
    CAN_InitStructure.CAN_Prescaler = 8;
    CAN_Init(CAN1, &CAN_InitStructure);

    CAN_FilterInitStructure.CAN_FilterNumber=0;
    CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
    CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
}

 

Poprzez wypełnianie kolejnych pól struktury CAN_InitStructure ustalane są parametry pracy magistrali. Wyłączane są:

  • komunikacja wyzwalana czasowo (TTCM – Time Triggered Communication Mode),
  • automatyczne zarządzanie odcinaniem od sieci (ABOM – Automatic Bus-off Managment),
  • trybu automatycznego wybudzania (AWUM – Automatic Wake-up Mode),
  • priorytety kolejek FIFO dla danych wysyłanych (TXFP – Transmit FIFO priority).

Natomiast włączane są:

  • tryb automatycznej retransmisji (NART – No-automatic retransmission mode), tutaj warto zaznaczyć, że występuje podwójne negowanie – wyłączany jest tryb nieautomatycznej retransmisji danych,
  • tryb zabezpieczenia przed nadpisaniem danych przechowywanych w kolejkach FIFO przez nowe dane (RFLM – Receive FIFO Locked mode).

Dalej wybierany jest tryb pracy kontrolera CAN. Tutaj wybrano tryb normalny, ale istnieją jeszcze trzy inne tryby pracy: w pętli powrotnej, cichy i połączenie obydwu. Praca w trybie normalnym oznacza pełny dostęp do magistrali. Tryb pętli powrotnej polega na odcięciu odbiornika CAN od magistrali i podłączeniu w to miejsce bezpośrednio części nadawczej CAN. W konsekwencji sterownik nie może odbierać danych z magistrali. Analogicznie praca w trybie cichym (silent mode) oznacza niemożność wysyłania danych przez magistralę. Kombinacja obydwu powyższych wiąże się z całkowitym odcięciem od magistrali, a dane są wewnętrznie kierowane z nadajnika CAN do odbiornika.
W kolejnym kroku konfiguracji ustalane są czasy trwania segmentów cyklu transmisji bitu, a więc pośrednio również prędkość komunikacji. Ponieważ wartość preskalera wynosi osiem, to prędkość transmisji dla takich ustawień będzie wynosić 250 kb/s.
Ramki – nadawcza oraz odbiorcza – posiadają w bibliotece firmy ST specjalnie dla nich stworzony typ danych. Są to struktury, których deklaracje zamieszono na list.2. Wysłanie ramki danych odbywa się za pomocą wywołania funkcji CAN_Transmit(). Odbiór, jeśli włączone zostało przerwanie USB_LP_CAN1_RX0_IRQn może zostać przeprowadzony w funkcji obsługi przerwania USB_LP_CAN1_RX0_IRQHandler, która powinna zostać zamieszczona w pliku stm32f10x_it.c.

 

List. 2. Struktury ramek: nadawczej i odbiorczej

typedef struct
{
    uint32_t StdId;  
    uint32_t ExtId; 
    uint8_t IDE; 
    uint8_t RTR;   
    uint8_t DLC;   
    uint8_t Data[8]; 
} CanTxMsg;


typedef struct
{
    uint32_t StdId;  
    uint32_t ExtId; 
    uint8_t IDE; 
    uint8_t RTR;
    uint8_t DLC; 
    uint8_t Data[8]; 
    uint8_t FMI;   
} CanRxMsg;