본문 바로가기

CAN

(21)
STM32를 이용해 Control Area Network (CAN) 통신 이해 - 목차 1. 개발환경 및 설명 방식개발환경 및 설명 방식 2. 통신 흐름(1) CAN 컨트롤러 - CAN 트랜시버 - 버스(2) MCU 어플리케이션 – CAN 컨트롤러 3. 초기 설정(1) CAN_BTR (CAN bit timing register)(2) CAN_MCR (CAN master control register)(3) CAN_HandleTypeDef 구조체(4) HAL_CAN_Init 함수 4. 필터 설정(1) 설정 방법(2)~(5) 필터 종류(6) CAN_FilterConfTypeDef 구조체와 HAL_CAN_ConfigFilter 함수 5. 데이터 송신 (인터럽트 방식)(1) 데이터 프레임 (2) 리모트 프레임(3) CanTxMsgTypeDef 구조체 (4) HAL_CAN_Transmit_IT 함수..
8. HAL 드라이버 수정/추가 (3) 필터 설정 구조체와 필터 설정 함수 개선 필터 설정 파트에서 이미 필터 설정 구조체인 CAN_FilterConfTypeDef 구조체를 설명했습니다. 필터는 식별자 정보 뿐만 아니라 RTR과 IDE에 대한 정보도 들어가는데 CAN_FilterConfTypeDef 구조체의 맴버 변수를 보면 식별자와 RTR, IDE에 대한 모든 정보를 사용자가 알아서 배열한 다음 FilterIdHigh, FilterIdLow, FilterMaskIdHigh, FilterMaskIdLow 맴버 변수에 넣어주게 되어 있습니다. 좀 귀찮습니다. 하지만 CAN_FilterConfTypeDef 구조체와 HAL_CAN_ConfigFilter 함수를 새로 만들기는 더 귀찮습니다. 그래서 FilterIdHigh, FilterIdLow, FilterMaskIdHigh, Filter..
8. HAL 드라이버 수정/추가 (2) HAL_CAN_Receive 개선 및 HAL_CAN_Receive_All로 업그레이드 함수의 선언입니다.잘 보면 두개의 RX 메일박스 FIFO 중 하나를 선택해서 수신하고 있습니다. 즉, 두개의 RX 메일박스를 동시에 수신할 수 없다는 의미입니다. 그래서 FIFONumber 변수를 HAL_CAN_Receive 함수 내부로 넣어주고, CAN_RFxR 레지스터에서 FMP 필드를 읽어오기 위한 변수 FMP0와 FMP1을 만든 후에 while 문을 다음과 같이 수정합니다. 참고로 __HAL_CAN_MSG_PENDING 함수도 CAN_RFxR 레지스터에서 FMP 필드를 읽어 오는 함수입니다. 이렇게 하면 두개의 RX 메일박스 FIFO를 모두 검사할 수 있습니다. 그런데 HAL_CAN_Receive 함수에는 한가지 문제가 더 있습니다. 바로 핸들을 잠그고 while문에 진입하는 것인데요. 그렇게 되..
8. HAL 드라이버 수정/추가 (1) 인터럽트가 2번 걸리는 문제 HAL_CAN_IRQHandler에서 전송에 의해 HAL_CAN_IRQHandle에 접근했는지 검사하는 블록입니다. 저는 전송이 완료될 때마다 핸들러의 state 맴버 변수나 반환값을 확인하는게 귀찮아서 이 코드 마지막에 printf 함수를 써서 전송 완료를 확인할 수 있게 해봤습니다. 원래 2줄 위에 써야하지만 실수로 아래 코드와 같이 입력했는데 터미널에서 HAL_CAN_IRQHandler에 2번 접근하는 것을 알게되었습니다. 버튼을 눌렀을 때 스위치가 불안정하여 EXTI_ISR에 두번 진입하는 것은 하드웨어 문제이지만(소프트웨어로 어느 정도 해결할 수 있지만), HAL_CAN_IRQHandler에 두번 진입하는 이유는 레퍼런스 매뉴얼을 찾아보면 알 수 있습니다. 인터럽트를 이용한 송신은 CAN_TSR..
7. 오류 검출과 오류 상태 프레임 모니터링 과정에서 검출될 수 있는 오류들과 그 범위는 다음과 같습니다. 인식 주체오류 종류내용송신 노드비트 오류송신하고 있는 비트값과 다른 값을 검출했을 때 발생하며, STM32는 비트 오류를 비트 도미넌트 오류와 비트 리세시브 오류로 나누고 있습니다. 하지만 비트 도미넌트 오류가 도미넌트 비트를 송신했는데 리세시브 비트를 수신했다는 것인지 리세시브 비트를 송신했는데 도미넌트 비트를 수신했다는 것인지는 모르겠습니다.인지 오류송신 노드는 ACK 비트를 리세시브(1)로 보낸다고 했습니다. 그래도 자신은 도미넌트(0)를 수신할 것으로 예상하고 있습니다. 이때 도미넌트 비트를 수신하지 못한 경우 발생합니다.수신 노드스태프 오류동일한 비트가 연속으로 6비트 이상 수신된 경우 발생합니다.CRC 오류자신이 계..
6. 데이터 수신 (풀링 방식) (2) CanRxMsgTypeDef 구조체 (3) HAL_CAN_Receive 함수 (2) CanRxMsgTypeDef 구조체 CanTxMsgTypeDef 구조체와 비슷한 기능을 합니다. RX 메일박스 레지스터들과 대응되며 RX 메일박스에 있는 가장 최근에 수신된 CAN 프레임에 대한 정보를 임시 저장하는 구조체입니다. CAN_HandleTypeDef 구조체는 CanTxMsgTypeDef형 포인터 변수만 가지고 있기 때문에 CanTxMsgTypeDef 구조체와 마찬가지로 사용자가 CanRxMsgTypeDef형의 변수를 만들어서 CAN_HandleTypeDef형 핸들에 직접 연결시켜주어야 합니다. RX 메일 박스에서 가져온 내용을 임시 저장하는 변수이기 때문에 각 맴버 변수들은 RX 메일박스의 필드들과 거의 100% 대응됩니다. (3) HAL_CAN_Receive 함수 HAL_Status..
6. 데이터 수신 (풀링 방식) (1) 필터와 FMI 송신과 달리 수신 동작을 위한 컨트롤 비트는 따로 없습니다. CAN_MCR 레지스터의 SLEEP 비트와 INRQ 비트를 클리어하여 노멀 모드에 진입하면, 바로 수신 가능 상태가 됩니다. 전에도 설명했지만 필터를 통과한 데이터 프레임 또는 리모트 프레임은 STM32 CAN 컨트롤러에 의해 통과한 필터에 연결되어 있는 RX 메일박스 FIFO에 정리되어 적재됩니다. 이것은 STM32 CAN 컨트롤러만의 특징으로 알고 있습니다. 또한 STM32F091RC는 2개의 RX 메일박스 FIFO를 제공합니다. 초기 설정 파트에서 설명했지만 CAN_FFA1R 레지스터를 사용하여 필터 뱅크 단위로 필터를 RX 메일박스 FIFO에 연결시킬 수 있습니다. RX 메일박스는 TX 메일박스와 같은 단층 구조가 아닌 FIFO 구조로 ..
5. 데이터 송신 (6) 오실로스코프로 데이터 프레임 파형 관찰 (7) 기타 의문점.. 위에 있는 숫자는 연속적인 유효한 비트의 개수이고 아래 부분은 필드의 끝부분과 필드명을 표시해 놨습니다. 전송 속도는 다음과 같습니다.프리스칼라 1024 BS 1 3 BS 2 5 SJW 1 비트타임/속도 192000ns/5280bps 오실로스코프의 작은 네모의 가로 길이가 500us이므로 작은 눈금 약 1.9개가 1비트의 길이입니다. hcan.pTxMsg->Data[3] = 0x1F;hcan.pTxMsg->Data[2] = 0xFF;hcan.pTxMsg->Data[1] = 0xFF;hcan.pTxMsg->Data[0] = 0xFF;hcan.pTxMsg->DLC = 4;hcan.pTxMsg->ExtId = 0x1FFFFFFF;hcan.pTxMsg->IDE = CAN_ID_EXT;hcan.pTxMsg->RT..