[STM32#29] CAN통신 모듈인 SN65HVD230을 연결해서 설정하는 방법을 알아보고 ecan-u01s을 이용해서 패킷을 확인해보기!(녹칸다 내맘대로 STM32)
프로그래밍/STM32 2026. 1. 26. 23:02
https://youtube.com/live/Y64tBhImAvo
[STM32#29] CAN통신 모듈인 SN65HVD230을 연결해서 설정하는 방법을 알아보고 ecan-u01s을 이용해서 패킷을 확인해보기!(녹칸다 내맘대로 STM32)
심심한녹칸다의 내맘대로 STM32시리즈이다!
STM32시리즈의 모든 자료는 구글 슬라이드에 작성하고 모두에게 공유되어있음!
https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bb3c8bdfec_1_0#slide=id.g3bb3c8bdfec_1_0
이번편은 stm32보드로 간단하게 can통신을 해보도록 함!



1.STM32가 1초간격으로 CAN통신 메시지를 PC로 전송할때, PC에 CAN통신을 모니터링하는 전용 프로그램으로 그 결과를 확인하시오!

/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
void Can_Set(){
sFilterConfig.FilterBank= 0;
sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh= 0x0000;
sFilterConfig.FilterIdLow= 0x0000;
sFilterConfig.FilterMaskIdHigh= 0x0000;
sFilterConfig.FilterMaskIdLow= 0x0000;
sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
sFilterConfig.FilterActivation= ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan);
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
//캔통신 시작~
Can_Set();
/* USER CODE END 2 */
while (1)
{
//STM32가 1초간격으로 메시지를 전송한다!
//송신
TxMessage.DLC = 8; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x123; //0x000 ~ 0x7FF
TxMessage.TransmitGlobalTime = DISABLE;
TxData[0] = 1;
TxData[1] = 2;
TxData[2] = 3;
TxData[3] = 4;
TxData[5] = 5;
TxData[6] = 6;
TxData[7] = 7;
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
2.이번에는 PC쪽 프로그램에서 8개의 길이를 가지는 데이터를 송신했을때 STM32의 usart2를 이용해서 putty에 log를 출력하시오!

/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
sFilterConfig.FilterBank= 0;
sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh= 0x0000;
sFilterConfig.FilterIdLow= 0x0000;
sFilterConfig.FilterMaskIdHigh= 0x0000;
sFilterConfig.FilterMaskIdLow= 0x0000;
sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
sFilterConfig.FilterActivation= ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan);
}
//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
if(RxMessage.RTR == CAN_RTR_DATA && RxMessage.IDE == CAN_ID_STD){
sprintf(tx_buff,"CAN ID = %X, Length = %d, ",RxMessage.StdId,RxMessage.DLC);
HAL_UART_Transmit(&huart2, tx_buff, strlen(tx_buff), 100);
for(int i = 0;i<RxMessage.DLC;i++){
sprintf(tx_buff,"%d, ",RxData[i]);
HAL_UART_Transmit(&huart2, tx_buff, strlen(tx_buff), 100);
}
HAL_UART_Transmit(&huart2, "\n", 1, 100);
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
//캔통신 시작~
Can_Set();
/* USER CODE END 2 */
while (1)
{
//STM32가 1초간격으로 메시지를 전송한다!
//송신
TxMessage.DLC = 8; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x123; //0x000 ~ 0x7FF
TxMessage.TransmitGlobalTime = DISABLE;
TxData[0] = 1;
TxData[1] = 2;
TxData[2] = 3;
TxData[3] = 4;
TxData[5] = 5;
TxData[6] = 6;
TxData[7] = 7;
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
3.녹칸다의 STM32쉴드에보면 LED가 8개 붙어있는데, PC에서 8byte의 CAN메시지를 송신해서 각 바이트가 0이면 LED가 OFF이고 1이면 LED가 ON되도록하시오!(일괄제어)

/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
sFilterConfig.FilterBank= 0;
sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh= 0x0000;
sFilterConfig.FilterIdLow= 0x0000;
sFilterConfig.FilterMaskIdHigh= 0x0000;
sFilterConfig.FilterMaskIdLow= 0x0000;
sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
sFilterConfig.FilterActivation= ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan);
}
//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
if(RxMessage.RTR == CAN_RTR_DATA && RxMessage.IDE == CAN_ID_STD){
//LED 8개가 제어됨!
if(RxData[0]){
//0이 아닌 모든경우(ON)
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, 1);
}else{
//0을 수신(OFF)
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, 0);
}
if(RxData[1]){
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 1);
}else{
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 0);
}
if(RxData[2]){
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, 1);
}else{
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, 0);
}
if(RxData[3]){
HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, 1);
}else{
HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, 0);
}
if(RxData[4]){
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, 1);
}else{
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, 0);
}
if(RxData[5]){
HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, 1);
}else{
HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, 0);
}
if(RxData[6]){
HAL_GPIO_WritePin(LED7_GPIO_Port, LED7_Pin, 1);
}else{
HAL_GPIO_WritePin(LED7_GPIO_Port, LED7_Pin, 0);
}
if(RxData[7]){
HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, 1);
}else{
HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, 0);
}
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
//캔통신 시작~
Can_Set();
/* USER CODE END 2 */
4.예제3번과 유사하지만 CAN데이터를 2개만 보내서, 첫번째 바이트가 LED번호, 두번째 바이트가 0이면 OFF, 1이면 ON인 스타일로 접근하시오!(번호 8이면 전체를 ON/OFF)

/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
sFilterConfig.FilterBank= 0;
sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh= 0x0000;
sFilterConfig.FilterIdLow= 0x0000;
sFilterConfig.FilterMaskIdHigh= 0x0000;
sFilterConfig.FilterMaskIdLow= 0x0000;
sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
sFilterConfig.FilterActivation= ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan);
}
//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
if(RxMessage.RTR == CAN_RTR_DATA && RxMessage.IDE == CAN_ID_STD){
//LED 8개가 제어됨!
if(RxMessage.DLC == 2){
//RxData[0] LED 번호
//RxData[1] LED 작동명령
if(RxData[0] == 0){
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, RxData[1]);
}else if(RxData[0] == 1){
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, RxData[1]);
}else if(RxData[0] == 2){
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, RxData[1]);
}else if(RxData[0] == 3){
HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, RxData[1]);
}else if(RxData[0] == 4){
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, RxData[1]);
}else if(RxData[0] == 5){
HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, RxData[1]);
}else if(RxData[0] == 6){
HAL_GPIO_WritePin(LED7_GPIO_Port, LED7_Pin, RxData[1]);
}else if(RxData[0] == 7){
HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, RxData[1]);
}else if(RxData[0] == 8){
//전체 일괄제어
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, RxData[1]);
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, RxData[1]);
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, RxData[1]);
HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, RxData[1]);
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, RxData[1]);
HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, RxData[1]);
HAL_GPIO_WritePin(LED7_GPIO_Port, LED7_Pin, RxData[1]);
HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, RxData[1]);
}
}
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
//캔통신 시작~
Can_Set();
/* USER CODE END 2 */
5.녹칸다의 STM32쉴드에 PB11에 서보모터(SG90)을 연결하고 CAN통신 메시지를 1바이트 범위로 0~180의 값을 전송해서 서보모터의 각도를 제어하시오!

/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void set_servo(uint8_t degree){
TIM2->CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
void Can_Set(){
sFilterConfig.FilterBank= 0;
sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh= 0x0000;
sFilterConfig.FilterIdLow= 0x0000;
sFilterConfig.FilterMaskIdHigh= 0x0000;
sFilterConfig.FilterMaskIdLow= 0x0000;
sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
sFilterConfig.FilterActivation= ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan);
}
//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
if(RxMessage.RTR == CAN_RTR_DATA && RxMessage.IDE == CAN_ID_STD){
//LED 8개가 제어됨!
if(RxMessage.DLC == 1){
//RxData[0] 서보모터의각도 0~180
if(RxData[0] > 180) RxData[0] = 180;
set_servo(RxData[0]);
}
}
}
/* USER CODE END 0 */
//캔통신 시작~
Can_Set();
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);
/* USER CODE END 2 */
6.이번에는 STM32에 붙어있는 버튼 8개가 있는데, 8바이트의 정보로 각버튼이 눌려지면 1, 안눌려지면 0의 값을 CAN메시지로 송신하시오!

/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
sFilterConfig.FilterBank= 0;
sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh= 0x0000;
sFilterConfig.FilterIdLow= 0x0000;
sFilterConfig.FilterMaskIdHigh= 0x0000;
sFilterConfig.FilterMaskIdLow= 0x0000;
sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
sFilterConfig.FilterActivation= ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan);
}
//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
//캔통신 시작~
Can_Set();
/* USER CODE END 2 */
while (1)
{
//0.1초간격으로 8byte array에 버튼의 눌려짐 상태를 넣어서 송신한다!
TxMessage.DLC = 8; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x123; //0x000 ~ 0x7FF
TxMessage.TransmitGlobalTime = DISABLE;
TxData[0] = !HAL_GPIO_ReadPin(BTN1_GPIO_Port, BTN1_Pin);
TxData[1] = !HAL_GPIO_ReadPin(BTN2_GPIO_Port, BTN2_Pin);
TxData[2] = !HAL_GPIO_ReadPin(BTN3_GPIO_Port, BTN3_Pin);
TxData[3] = !HAL_GPIO_ReadPin(BTN4_GPIO_Port, BTN4_Pin);
TxData[4] = !HAL_GPIO_ReadPin(BTN5_GPIO_Port, BTN5_Pin);
TxData[5] = !HAL_GPIO_ReadPin(BTN6_GPIO_Port, BTN6_Pin);
TxData[6] = !HAL_GPIO_ReadPin(BTN7_GPIO_Port, BTN7_Pin);
TxData[7] = !HAL_GPIO_ReadPin(BTN8_GPIO_Port, BTN8_Pin);
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
HAL_Delay(100);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
7.버튼1~버튼8까지있을때 버튼1을 최하위bit로 생각하고 8bit로 계산해서 can메시지를 1바이트 전송하시오!

/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
sFilterConfig.FilterBank= 0;
sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh= 0x0000;
sFilterConfig.FilterIdLow= 0x0000;
sFilterConfig.FilterMaskIdHigh= 0x0000;
sFilterConfig.FilterMaskIdLow= 0x0000;
sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
sFilterConfig.FilterActivation= ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan);
}
//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
//캔통신 시작~
Can_Set();
GPIO_TypeDef * myport[] = {BTN1_GPIO_Port,BTN2_GPIO_Port,BTN3_GPIO_Port,BTN4_GPIO_Port,BTN5_GPIO_Port,BTN6_GPIO_Port,BTN7_GPIO_Port,BTN8_GPIO_Port};
uint16_t mypin[] = {BTN1_Pin,BTN2_Pin,BTN3_Pin,BTN4_Pin,BTN5_Pin,BTN6_Pin,BTN7_Pin,BTN8_Pin};
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
//0.1초간격으로 1byte 버튼의 눌려짐 상태를 bit연산으로 송신한다!
TxMessage.DLC = 1; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x123; //0x000 ~ 0x7FF
TxMessage.TransmitGlobalTime = DISABLE;
TxData[0] = 0;
for(int i = 0;i<8;i++){
TxData[0] |= (!HAL_GPIO_ReadPin(myport[i], mypin[i]) << i);
}
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
HAL_Delay(100);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
8.버튼1을 누르면 0~255범위에서 숫자가 1씩 업카운트된다! 버튼2를 누르면 1씩 다운카운트된다! 그리고 버튼3을 누르면 0으로 초기화된다! 이 카운터값을 버튼이 눌려지는 타이밍에 can통신으로 1바이트 전송하시오!

/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
sFilterConfig.FilterBank= 0;
sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh= 0x0000;
sFilterConfig.FilterIdLow= 0x0000;
sFilterConfig.FilterMaskIdHigh= 0x0000;
sFilterConfig.FilterMaskIdLow= 0x0000;
sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
sFilterConfig.FilterActivation= ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan);
}
//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
}
int cnt = 0;
void send_can_msg(){
TxMessage.DLC = 1; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x123; //0x000 ~ 0x7FF
TxMessage.TransmitGlobalTime = DISABLE;
TxData[0] = cnt;
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
//캔통신 시작~
Can_Set();
/* USER CODE END 2 */
while (1)
{
if(HAL_GPIO_ReadPin(BTN1_GPIO_Port, BTN1_Pin) == 0){
cnt++;
if(cnt > 255) cnt = 255;
send_can_msg();
HAL_Delay(200);
}
if(HAL_GPIO_ReadPin(BTN2_GPIO_Port, BTN2_Pin) == 0){
cnt--;
if(cnt < 0) cnt = 0;
send_can_msg();
HAL_Delay(200);
}
if(HAL_GPIO_ReadPin(BTN3_GPIO_Port, BTN3_Pin) == 0){
cnt = 0;
send_can_msg();
HAL_Delay(200);
}
}

