(2) CanRxMsgTypeDef 구조체
CanTxMsgTypeDef 구조체와 비슷한 기능을 합니다. RX 메일박스 레지스터들과 대응되며 RX 메일박스에 있는 가장 최근에 수신된 CAN 프레임에 대한 정보를 임시 저장하는 구조체입니다. CAN_HandleTypeDef 구조체는 CanTxMsgTypeDef형 포인터 변수만 가지고 있기 때문에 CanTxMsgTypeDef 구조체와 마찬가지로 사용자가 CanRxMsgTypeDef형의 변수를 만들어서 CAN_HandleTypeDef형 핸들에 직접 연결시켜주어야 합니다. RX 메일 박스에서 가져온 내용을 임시 저장하는 변수이기 때문에 각 맴버 변수들은 RX 메일박스의 필드들과 거의 100% 대응됩니다.
(3) HAL_CAN_Receive 함수
HAL_StatusTypeDef HAL_CAN_Receive( CAN_HandleTypeDef *hcan, uint8_t FIFONumber, uint32_t Timeout ) { uint32_t tickstart = 0; __HAL_LOCK(hcan); /* 핸들을 잠근다. */ if (hcan->State == HAL_CAN_STATE_BUSY_TX) /* 핸들이 송신 상태였다면, */ { hcan->State = HAL_CAN_STATE_BUSY_TX_RX; /* 핸들을 송수신 상태로 바꾼다. */ } else /* 핸들이 송신 상태가 아니라면, */ { hcan->State = HAL_CAN_STATE_BUSY_RX; /* 핸들을 송신 상태로 바꾼다. */ } tickstart = HAL_GetTick(); /* 현재 SysTick의 틱 값을 가져온다. 다음에 나오는 while문의 타임아웃을 위한 기준 틱이다. */ /* CAN_RFxR 레지스터의 FMP 필드가 0인동안 반복하지만, 타임아웃 */ while (__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0U) { /* 입력 변수의 Timeout 값이 HAL_MAX_DELAY(0xFFFFFFFF)가 아니라면, HAL_MAX_DELAY라면 무한정 기다린다. */ if (Timeout != HAL_MAX_DELAY) { /* while문 진입 후 SysTick의 틱 값을 다시 얻어와 tickstart 값을 빼서 경과한 시간을 계산한다. 이때 경과시간이 Timeout보다 크면 탈출한다. */ if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) { /* 핸들을 풀어주고, 타임아웃 상태로 만든 뒤 탈출. */ hcan->State = HAL_CAN_STATE_TIMEOUT; __HAL_UNLOCK(hcan); return HAL_TIMEOUT; } } } /* while문을 탈출했다는 것은 메시지가 수신되었다는 의미이다. RX 메일박스에서 메시지 임시 저장용도로 사용되는 CanTxMsgTypeDef형 변수로 데이터를 복사한다.*/ /* CAN_RIxR 레지스터에서 비트2만 남기고 모두 지우고, IDE 맴버 변수에 복사한다. */ hcan->pRxMsg->IDE = (uint8_t)0x04U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR; if (hcan->pRxMsg->IDE == CAN_ID_STD) /* 표준 식별자를 사용한 프레임이라면, */ { /* CAN_RIxR 레지스터에서 하위 11비트만 남기고 모두 지우고, StdId 맴버 변수에 복사한다. */ hcan->pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U); } else /* 확장 식별자를 사용한 프레임이라면, */ { /* CAN_RIxR 레지스터에서 하위 29비트만 남기고 모두 지우고, StdId 맴버 변수에 복사한다. */ hcan->pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U); } /* CAN_RIxR 레지스터에서 비트2만 남기고 모두 지우고, RTR 맴버 변수에 복사한다. */ hcan->pRxMsg->RTR = (uint8_t)0x02U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR; /* CAN_RDTxR 레지스터에서 하위 4비트만 남기고 모두 지우고, DLC맴버 변수에 복사한다. */ hcan->pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR; /* CAN_RDTxR 레지스터에서 비트8부터 비트15까지의 값을 FIM 맴버 변수에 복사한다. */ hcan->pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U); /* CAN_RDL/HR 레지스터에서 데이터 값을 Data 맴버 변수에 복사한다.*/ hcan->pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR; hcan->pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U); hcan->pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U); hcan->pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U); hcan->pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR; hcan->pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U); hcan->pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U); hcan->pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U); /* RX FIFO를 풀어준다. 릴리즈(release) 해 준다. */ if (FIFONumber == CAN_FIFO0) /* RX FIFO 0을 선택했다면, */ { /* CAN_RF0R 레지스터에서 RFOM0 비트에 1을 쓴다. */ __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0); } else /* RX FIFO 1을 선택했다면, */ { /* CAN_RF1R 레지스터에서 RFOM1 비트에 1을 쓴다. */ __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1); } if (hcan->State == HAL_CAN_STATE_BUSY_TX_RX) /* 현재 핸들의 상태가 송수신 상태라면, */ { /* 수신은 완료했으므로 다시 송신 상태로 바꿔준다.*/ hcan->State = HAL_CAN_STATE_BUSY_TX; } else /* 현재 핸들의 상태가 송수신 상태가 아니라면, */ { hcan->State = HAL_CAN_STATE_READY; /* 준비 상태로 바꿔준다. */ } __HAL_UNLOCK(hcan); /* 핸들을 풀어준다. */ return HAL_OK; }
'CAN' 카테고리의 다른 글
8. HAL 드라이버 수정/추가 (1) 인터럽트가 2번 걸리는 문제 (0) | 2017.03.25 |
---|---|
7. 오류 검출과 오류 상태 (0) | 2017.03.25 |
6. 데이터 수신 (풀링 방식) (1) 필터와 FMI (0) | 2017.03.25 |
5. 데이터 송신 (6) 오실로스코프로 데이터 프레임 파형 관찰 (7) 기타 의문점.. (0) | 2017.03.22 |
5. 데이터 송신 (인터럽트 방식) (5) HAL_CAN_IRQHandler와 CAN_Transmit_IT 함수 (0) | 2017.03.22 |