stmでHALドライバーを用いたcan通信ができたのでその備忘録。(下書きの中に眠っていた・・・)
can通信は複数のマイコンが通信するときに使えるもので、ノイズに強く自動車の車載ネットワークなんかにも使われているらしい。
特徴としては、先に言った、ノイズに強い点や、マスターやスレーブを設けず、一つのバスで複数のマイコンをつなぐことができるため配線がすっきりする点がある。
stmには、canの波形を生成できるが、canトランシーバを介さないと通信ができない点に注意する。
ICを通して、初めて上下の波形が見える。
使用環境
- OS:Windows10 Home
- CPU:i5-6200U
- IDE:System Workbench for STM32
- STM32CubeMX(初期コード作成に使用)
- stm32,446re
初期コード作成
CubeMXにて初期コードを作成する。ペリフェラルでCANを使えるように設定しておきます。
次に、この初期コードに少し追加をします。
MX_CAN1_Initという関数の先頭に
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
hcan1.pTxMsg = &TxMessage;
hcan1.pRxMsg = &RxMessage;
と記述してください。
これは、can通信におけるバッファのようなものです。
送る情報は、cantxmsgに入れてから送信し、受信した情報はcanrxmsgに格納されます。
メイン関数
送信、受信する関数をwhile文で回します。
この関数はstmのフォーラムにあったものをを参考にしてみました。
まずは、書き込み送信関数から
void CAN_Tx(void)
{
hcan1.pTxMsg->StdId = 0x124;
hcan1.pTxMsg->RTR = CAN_RTR_DATA;
hcan1.pTxMsg->IDE = CAN_ID_STD;
hcan1.pTxMsg->DLC = 2;
hcan1.pTxMsg->Data[0] = 0xCA;
hcan1.pTxMsg->Data[1] = 0xFE;
TransmitMailbox = HAL_CAN_Transmit_IT(&hcan1);
do
{
TransmitMailbox = HAL_CAN_Transmit_IT(&hcan1);
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_0);
}
while( TransmitMailbox == CAN_TXSTATUS_NOMAILBOX );
}
次に受信関数
void CAN_Rx(void)
{
HAL_CAN_Receive_IT(&hcan1,CAN_FILTER_FIFO0);
datarx[0]=hcan1.pRxMsg->StdId ;
datarx[1] =hcan1.pRxMsg->DLC;
datarx[2]= hcan1.pRxMsg->RTR;
datarx[3]= hcan1.pRxMsg->DLC;
datarx[4]= hcan1.pRxMsg->Data[0];
datarx[5]= hcan1.pRxMsg->Data[1];
if(datarx[0]==0x124)
{
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
}
HAL_Delay(100);
}