Iš archyvo ištraukiau “motininę PCB” su nesupjaustytom schemutėm. Tai husqvarnos išmanios žoliapjovės “loop sensor” plokštė. Dabar tas “loop” visiškai nedomina. Prilituojam USB lizdą ir bandom suprogramuoti CAN protokolo siuntėją ir gavėją.
PCB numatytas maitinimas iš CAN jungties, todėl norint maitinti iš USB, reikia pajugti papildomą laidelį. Visą kitą paliekam kaip buvo. Iš aiškių elementų: Texas Instruments TCAN330 čipas ir SPI EEPROM, toliau komparatorius, analoginis multipleksorius ir keletas tranzistorių. Loop ryšiui- ritė laido juodame korpuse.
Perdaryta plokštė jau su ISP jungtimi ir sujungta į grupę per CAN laidus (laidinio telefono kabelis).
Procesoriukas (STM32F302CCT6) turi “hardwarinį” CAN, tai dar ir panaudojus CubeMX sukurtą skeletą darbo nelieka daug. Ryšiui su išoriniu pasauliu nutariau panaudoti USB CDC (serial) įrenginį. Kad viskas veiktu, procesoriaus CLK turi būti kiek aukštesnis nei pagal nutylėjimą sugeneruoja kubikas. Aš pasirinkau 72MHz, maksimumą. Dar, kad nesipjautų pertraukimai, CAN RX1 kiek pažeminau prioritetuose iki “1”.
Apie softą:
CAN siuntimui naudojam HAL paprogramę HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox)
. TxHeaderyje nurodom kam siunčia ir kokio tipo paketas. TxData- tai max 8 baitai duomenų. TxMailbox- nežinau kas tai, teoriškai “pašto dėžutė” kurioje kabo paketas, kol nėra pristatytas. Kaip jis veikia nežinau ir nesvarbu.
CAN paketo priėmimas kiek įdomesnis. MCU turi kažkiek “hardwarinio” spartinimo, todėl paketų filtrą ir priėmimą galima automatizuoti. Pats priėmimas geriausiai veikia per pertraukimą- gaunam paketą, jį priima ir pakelia vėliavėlę. O toliau jau softas rūpinasi kas bus toliau.
Todėl pirma reikia sukonfiguruoti paketų filtrą:
void can_filter(void) //CAN filtas- tai hardwarinis (softwarinis) paketu filtras, kad duomenys eitu tik reikalingi.
{
CAN_FilterTypeDef canfilterconfig;canfilterconfig.FilterActivation = CAN_FILTER_ENABLE;
canfilterconfig.FilterBank = 10; // which filter bank to use from the assigned ones??? Kodėl?
//canfilterconfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; //Ziureti kuris yra. Šits kažko neveikė
canfilterconfig.FilterFIFOAssignment = CAN_FILTER_FIFO1; //O šitas jau veikia.
canfilterconfig.FilterIdHigh = CAN_ID_RX << 5;
canfilterconfig.FilterIdLow = 0;
canfilterconfig.FilterMaskIdHigh = CAN_ID_RX << 5;
canfilterconfig.FilterMaskIdLow = 0x0000;
canfilterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
canfilterconfig.FilterScale = CAN_FILTERSCALE_32BIT;
canfilterconfig.SlaveStartFilterBank = 0; // how many filters to assign to the CAN1 (master can)
// doesn't matter in single can controllers
HAL_CAN_ConfigFilter(&hcan, &canfilterconfig);
}
Čia yra niuansų- CAN_FILTER_FIFO0 ir FIFO1.
Ir kitas niuansas RX pertraukimo Call-back:
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) //RX interrupto callbackas. Gali buti "Fifo0", zr. filtrą ir galimus int.
{
HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &RxHeader, RxData);
CAN_MSG_R=1;
}
Matot “CAN_RX_FIFO1” ir “HAL_CAN_RxFifo1MsgPendingCallback”? Fifo0 ar Fifo1 nėra taip paprastai pasirenkamas, o nuo ko priklauso aš pilnai ir nesupratau. Kažkodėl FIFO0 neveikė. Gal buvo per vėlus vakaras ar panašiai. Bet su FIFO1 viskas veikia.
Kitas momentas- pirma sukonfiguruoji, poto paleidi. Jei reikia perkonfiguruoti- pirma stabdom, poto perkonfiguruojam ir poto paleidžiam:
can_filter(); //pirma filtras, poto start
HAL_CAN_Start(&hcan );
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO1_MSG_PENDING);
Visas veikiantis demo source kodas: STM32F302 USB CAN writer reader source code.
Ten dar yra windows console programėlė filtro konfiguracijos testavimui (su source code, ne mano).