CAN
概要
このライブラリは、HAL を利用した、CAN通信を簡単に扱うためのクラスを提供する
クラス概要
CAN
CANクラスは、CAN通信の初期化、フィルタ設定、メッセージ送信、受信コールバックの設定を行う
コンストラクタ
CAN(CanHandleType *CanHandle);CanHandle: HALによって生成されたCANハンドラへのポインタ
CAUTION
f303k8などの一部のマイコンでは、HALライブラリと干渉するため、
CANAlt(CAN_HandleTypeDef *CanHandle);のように、CANAltクラスを使用する必要がある。 f303k8以外のマイコンを使用している場合でかつ、干渉によってビルドエラーが発生する場合、CANAltクラスを使用するようインクルードガードを編集してください。
メソッド
void init()
CANの初期化を行う
void filterSetup(uint32_t filter_id, uint32_t filter_mask, uint8_t is_extended, uint8_t fifo)
CANフィルタの設定を行う
filter_id: フィルタIDfilter_mask: フィルタマスクis_extended: 拡張IDかどうかfifo: FIFO番号 (0 または 1)
NOTE
この関数は HAL_CAN_ConfigFilter を内部で使用する CubeMX 側で FIFO 割り込みが有効になっている必要がある
void filterSetupWithConfig(const CAN_FilterTypeDef &FilterConfig)
CANフィルタの設定を行う (CAN_FilterTypeDefを引数として受け取る)
FilterConfig: CANフィルタ設定構造体
bool write(CANMessageType msg)
CANメッセージの送信を行う
msg: 送信するCANメッセージtrue: 送信成功false: 送信失敗
bool writeable()
CAN送信が可能かどうかを確認
true: 送信可能false: 送信不可
void attach(std::function<CallbackFnType> &&fn, uint8_t priority = 100, uint8_t fifo = 0)
コールバック関数を設定
fn: コールバック関数priority: コールバックの優先度fifo: FIFO番号 (0 または 1)
使用方法
CubeMX の設定
使用するピンを設定

クロック設定を確認する
- CubeMXのClock ConfigurationでCANのクロック源のAPB1の周波数を確認する

- CubeMXのClock ConfigurationでCANのクロック源のAPB1の周波数を確認する
CANの転送速度とサンプリングポイントを設定
- (2.)で確認したクロック設定と、ボーレート&サンプリングポイントを設定する
受信割り込みの設定をする
- FIFOを有効化し、受信割り込みの設定を行います
- FIFO0 :
CANx RX0 interrupts - FIFO1 :
CANx RX1 interrupts
NOTE
画像は 'STM23 F446re' を使用し、1Mbps ,サンプリングポイント 88.9% で計算 各パラメータは CAN Bit Time Calculation などのWEBツールを使用して計算できる 多くの場合、サンプリングポイントは 75% 以上にすることが推奨されている
app_main.cpp内
CANクラスのインスタンスを作成cppCAN can(&hcan1);必要に応じて初期化
cppcan.init();フィルタIDとマスクを設定
cppcan.filterSetup(filter_id, filter_mask, is_extended, fifo);コールバック関数を設定
cppcan.attach(callback_function, priority, fifo);メッセージを送信
cppif (can.writeable()) { CANMessage msg; msg.id = 0x123; msg.data[0] = 1; msg.data[1] = 2; msg.data[2] = 3; msg.data[3] = 4; msg.size = 4; can.write(msg); }
注意事項
- 割り込み処理内での長時間の処理やブロッキング処理は避ける
サンプルコード
動作
プログラム開始時に、UARTを通じて以下のメッセージが表示されます。
Start mainCANメッセージが送信されるたびに、以下のメッセージが表示されます。
send doneCANメッセージを受信すると、LEDがトグルされ、UARTを通じて以下のメッセージが表示されます。
Received CAN message: ID = 0x123, Data = 01 02 03 04
#include "main.h"
#include "../../Library/HALbed/Inc/HALbed.hpp"
using namespace HALbed;
extern UART_HandleTypeDef huart2; // 外部宣言
extern CAN_HandleTypeDef hcan1;
UART pc(&huart2);
CAN can(&hcan1);
void canListen_main(const CANMessage &msg);
extern "C" void app_main(void) {
pc.enableRxInt(); // 受信割り込みを有効にする
// コールバック関数を設定
can.attach([](const CANMessage &msg) { canListen_main(msg); }, 0);
can.init(); // CANをスタートする
uint32_t filter_id = 0x000; // 0xXXX のID
uint32_t filter_mask = 0x000; // 0xXXX で共通するビット(上位4ビットだけを比較)
// フィルタIDとマスクを設定
can.filterSetup(filter_id, filter_mask, 0, 0);
pc.xprintf("Start main\r\n");
while (1) {
if (can.writeable()) { // CAN busに書き込み可能か
CANMessage msg; // 送信するデータを設定
msg.id = 0x123;
msg.data[0] = 1;
msg.data[1] = 2;
msg.data[2] = 3;
msg.data[3] = 4;
msg.size = 4;
if(can.write(msg)){
pc.xprintf("send done\r\n"); // 正常に送信できたら出力
}
}
HAL_Delay(500);
}
}
void canListen_main(const CANMessage &msg) {
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
pc.xprintf("Received CAN message: ID = 0x%X, Data = ", msg.id);
for (int i = 0; i < msg.size; i++) {
pc.xprintf("%02X ", msg.data[i]);
}
pc.xprintf("\r\n");
}