STM32 + レジスタをたたいてCAN通信を実装する 最終回 送受信を行う

こんにちは。STM32のレジスタをたたいてCAN通信の実装を行うことの最終回です。

↑前回の記事




プログラムの実装を行う

送信用の処理

void CAN_TransmitData(CAN_TypeDef* CANx, uint32_t stdid, uint32_t rtr_data,
uint32_t use_id, uint8_t length, uint8_t* tx_data) {
  if (length > 8) length = 8;
  CAN_TxHeaderTypeDef TxHeader;
  uint32_t txMailbox;
  TxHeader.StdId = stdid;
  TxHeader.RTR = rtr_data;
  TxHeader.IDE = use_id;
  TxHeader.DLC = length;
  TxHeader.TransmitGlobalTime = DISABLE;
  CAN_AddTxMessage(CANx, &TxHeader, tx_data, &txMailbox);
  while (CAN_GetTxMailboxesFreeLevel(CAN) != 3);
}

初期化周りの実装

void CAN_Start(CAN_TypeDef* CANx) {
  CLEAR_BIT(CANx->MCR, CAN_MCR_INRQ);
  while ((CANx->MSR & CAN_MSR_INAK) != 0);
}
void CAN_Init(void) {
  CAN_MspInit();
  CAN_Param_Init();
  CAN_FilterParam_Init();
  CAN_EnableIT(CAN);
  CAN_Start(CAN);
}
void CAN_RX0_IRQHandler(void) {
  // CAN_RX0_IRQn
  CAN_RxHeaderTypeDef RxHeader;
  uint8_t RxData[8];
  CAN_GetRxMessage(CAN, CAN_RXFIFO0, &RxHeader, RxData);
  printf(" id=%ld [0]=%d [1]=%d[2]=%d\r\n", RxHeader.StdId, RxData[0],RxData[1], RxData[2]);
}

main

  /* USER CODE BEGIN 2 */
  uint8_t TxData[8];
  uint8_t cnt = 0;
  setbuf(stdout, NULL);
  printf("start can\r\n");
  CAN_Init();
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1) {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
    LL_mDelay(100);
    TxData[0] = 100;
    TxData[1] = 200;
    TxData[2] = cnt;
    CAN_TransmitData(CAN, 0x456, CAN_RTR_DATA, CAN_ID_STD, 3, TxData);
    if (cnt > 250) {
      cnt = 0;
    } else {
      cnt++;
    }
  }
  /* USER CODE END 3 */

動作実験

CAN通信の結果を以下に示します。

それぞれのマイコンで送信受信を行いました。

さいごに

いままでのまとめだったこともあり、使い方の例を簡単にまとめさせていただきました。他の機能を使いたいときは、リファレンスマニュアルと戯れましょう!
マイコン関連の機能を使う記事では一番長いものになりました。さいごまでお付き合いいただきありがとうございました