이번에는 CAN 통신을 라이브러리화 하여 CAN1 LoopBack 해 봤습니다.
이번에 만든 라이브러리 입니다.
지속적으로 업 그레이드 될 겁니다.
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
// SyS Lib
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// My Lib
#define F446RE 1
#include "My_ARM_GPIO_Lib_V3_6.h"
#define My_Uart_LIB_EN 1
#define Console_Ch2 2
#define USART_Ch_2_EN 3
#define IRQ_EN_Uart_2 6
#include "My_ARM_UART_Lib_V4_7.h"
#define ARM_Mcu_Mode 1
#define FND_595_IF 2
//#include "My_FND_Lib_V3_8.h"
#define ARM_Mode 1
#define UART 2
extern int out_dev_set_mode;
#include "My_MCU_Printf_Lib_V2_6.h"
#define debug 1
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
CAN_TxHeaderTypeDef TxHeader;
CAN_RxHeaderTypeDef RxHeader;
uint8_t TxData[8] = {'0', '1', '2', '3', '4', '5', '6', '7'};
uint8_t RxData[8];
HAL_StatusTypeDef TxStatus;
char can_tx(CAN_HandleTypeDef *hcan, uint16_t dev_msg_id, uint8_t tx_byte, uint8_t *pdata)
{
TxHeader.DLC = tx_byte; // default = 8 byte;
TxHeader.IDE = CAN_ID_STD; // mode
TxHeader.StdId = dev_msg_id;
TxHeader.ExtId = 0;
TxHeader.RTR = CAN_RTR_DATA; // 0 = My TX(내가 전송할때), 1 = TX Call(전송요청)
uint32_t TxMailbox;
if(HAL_CAN_AddTxMessage(&hcan->Instance, &TxHeader, pdata, &TxMailbox) == HAL_OK)
{
#if debug
printf("CAN TX OK!!!\r\n");
#endif
return 1;
}
else
{
#if debug
printf("CAN TX ERROR!!!\r\n");
#endif
return 0;
}
}
char can_rx(CAN_HandleTypeDef *hcan)
{
// Polling
if(HAL_CAN_GetRxFifoFillLevel(&hcan->Instance, CAN_RX_FIFO0) > 0)
{
if(HAL_CAN_GetRxMessage(&hcan->Instance, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
{
#if debug
printf("Rx data = %s\r\n", RxData);
#endif
return 1;
}
else
{
#if debug
printf("Rx data Error\r\n");
#endif
return 0;
}
}
else return 0;
}
// 필터 설정 (모든 메시지 수신 허용)
// CAN 필터 설정 함수
char CAN_Filter_Config(CAN_HandleTypeDef *hcan)
{
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = (hcan->Instance == CAN1) ? 0 : 14; // CAN2는 14번 이상을 사용 == 요게 매우 중요함
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_FILTER_FIFO0;//0
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) == HAL_OK)
{
return 1;
}
else return 0;
}
/* USER CODE END PD */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_CAN1_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
CAN_Filter_Config(&hcan1);
HAL_CAN_Start(&hcan1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
can_tx(&hcan1, 0x123, 8, &TxData);
HAL_Delay(100);
can_rx(&hcan1);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}