반응형

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);
	  }
 }
반응형
Posted by 덕력킹
,