[STM32#30] CAN통신으로 각종 센서값을 전송하고 자동차에서 사용하는 OBD2 프로토콜을 간단하게 모방해보기!(녹칸다 내맘대로 STM32)
프로그래밍/STM32 2026. 1. 28. 16:07
https://youtube.com/live/zxJ_ntNADKc
[STM32#30] CAN통신으로 각종 센서값을 전송하고 자동차에서 사용하는 OBD2 프로토콜을 간단하게 모방해보기!(녹칸다 내맘대로 STM32)
심심한녹칸다의 내맘대로 STM32시리즈이다!
STM32시리즈의 모든 자료는 구글 슬라이드에 작성하고 모두에게 공유되어있음!
https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3be1268f534_1_233#slide=id.g3be1268f534_1_233
이번편까지 해서 CAN통신은 마무리!
1.녹칸다의 STM32쉴드에 PA0에 붙어있는 가변저항값을 측정해서 CAN통신으로 PC로 전송하기!

/* USER CODE BEGIN 0 */
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//main에서 1회 호출
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 */
HAL_ADC_Start(&hadc1); //딱 한번만 호출
Can_Set();
uint16_t adc_value0 = 0;
/* USER CODE END 2 */
while (1)
{
//측정할때마다 호출
if(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)
{
// 값 처리
adc_value0 = HAL_ADC_GetValue(&hadc1); //0~4095
//CAN데이터로 송신!
TxMessage.DLC = 1; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x600;
TxMessage.TransmitGlobalTime = DISABLE;
//0~4095범위의 ADC값을 0~255범위로 축소
TxData[0] = (uint8_t)(adc_value0/4095.0*255);
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
}
HAL_Delay(100);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
2.예제1에서 0~4095의 숫자를 각 자리로 나눠서 4byte로 전송하기!

/* USER CODE BEGIN 0 */
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//main에서 1회 호출
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 */
HAL_ADC_Start(&hadc1); //딱 한번만 호출
Can_Set();
uint16_t adc_value0 = 0;
/* USER CODE END 2 */
while (1)
{
//측정할때마다 호출
if(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)
{
// 값 처리
adc_value0 = HAL_ADC_GetValue(&hadc1); //0~4095
//CAN데이터로 송신!
TxMessage.DLC = 4; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x600;
TxMessage.TransmitGlobalTime = DISABLE;
TxData[0] = adc_value0/1000; //천의자리
TxData[1] = (adc_value0/100)%10; //백의자리
TxData[2] = (adc_value0/10)%10; //십의자리
TxData[3] = adc_value0%10; //일의자리
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
}
HAL_Delay(100);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
3.온습도센서(DHT-11)의 측정값을 CAN통신으로 PC로 전송하기!

/* USER CODE BEGIN 0 *//* USER CODE BEGIN 2 */
Can_Set();
char str[100];
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
uint8_t error_no = DHT_read();
if(error_no == 0){ // 정상일 때 처리
float temp = 0;
float humi = 0;
temp = DHT.temp_i;
if (DHT.temp_d & 0x80) {
temp = -1 - temp;
}
temp += (DHT.temp_d & 0x0f) * 0.1;
humi = DHT.rh_i + DHT.rh_d * 0.1;
sprintf(str, "T:%.1f'C H:%.1f%c\n", temp,humi,'%');
HAL_UART_Transmit(&huart2,str,strlen(str),100);
TxMessage.DLC = 4; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x600;
TxMessage.TransmitGlobalTime = DISABLE;
TxData[0] = (uint8_t)temp; //온도의 정수부
TxData[1] = ((uint8_t)(temp*10))%10; //온도의 실수부
TxData[2] = (uint8_t)humi; //습도의 정부수
TxData[3] = ((uint8_t)(humi*10))%10; //습도의 실수부
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
}
HAL_Delay(2000);
}
#define delay_ms HAL_Delay
#define SYS_CLOCK 64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
return millis_cnt;
}
uint32_t micros() {
return (millis_cnt & 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick->VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) { // 64MHz 보정
if (us > 1) {
uint32_t count = us * 7 - 6;
while (count--);
} else {
uint32_t count = 2;
while (count--);
}
}
union {
uint32_t data;
struct {
uint8_t temp_d;
uint8_t temp_i;
uint8_t rh_d;
uint8_t rh_i;
};
} DHT;
uint8_t DHT_read () {
uint8_t i, check_sum;
uint32_t start;
check_sum = 0;
DHT.data = 0;
GPIOC->CRL = (GPIOC->CRL&0xFFFFFF0F)|(7<<(1*4)); // Output Open-drain (Master send LOW signal)
delay_ms(18);
GPIOC->CRL= (GPIOC->CRL&0xFFFFFF0F)|(4<<(1*4)); // Floating input (Master send HIGH signal & data receive)
start = micros();
while (GPIOC->IDR&(1<<1)) {
if (micros()-start > 50) return 1; // 20~40us
}
start = micros();
while (!(GPIOC->IDR&(1<<1))) {
if (micros()-start > 120) return 2; // 80us
}
start = micros();
while (GPIOC->IDR&(1<<1)) {
if (micros()-start > 120) return 3; // 80us
}
for (i = 0; i < 32; i++) {
while (!(GPIOC->IDR&(1<<1))); // 50us
start = micros();
while (GPIOC->IDR&(1<<1));
if (micros()-start > 50) DHT.data |= (0x80000000 >> i); // "0"=26~28us, "1"=70us
}
for (i = 0; i < 8; i++) {
while (!(GPIOC->IDR&(1<<1))); // 50us
start = micros();
while (GPIOC->IDR&(1<<1));
if (micros()-start > 50) check_sum |= (0x80 >> i);
}
if ((DHT.rh_i + DHT.rh_d + DHT.temp_i + DHT.temp_d) == check_sum) return 0;
else return 4;
}
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//main에서 1회 호출
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();
char str[100];
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
uint8_t error_no = DHT_read();
if(error_no == 0){ // 정상일 때 처리
float temp = 0;
float humi = 0;
temp = DHT.temp_i;
if (DHT.temp_d & 0x80) {
temp = -1 - temp;
}
temp += (DHT.temp_d & 0x0f) * 0.1;
humi = DHT.rh_i + DHT.rh_d * 0.1;
sprintf(str, "T:%.1f'C H:%.1f%c\n", temp,humi,'%');
HAL_UART_Transmit(&huart2,str,strlen(str),100);
TxMessage.DLC = 4; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x600;
TxMessage.TransmitGlobalTime = DISABLE;
TxData[0] = (uint8_t)temp; //온도의 정수부
TxData[1] = ((uint8_t)(temp*10))%10; //온도의 실수부
TxData[2] = (uint8_t)humi; //습도의 정부수
TxData[3] = ((uint8_t)(humi*10))%10; //습도의 실수부
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
}
HAL_Delay(2000);
}
4.PC프로그램에 0x7DF와 데이터 8byte를 stm32로 전송하면 STM32는 0x7E0이라는 ID와 PC가 보낸 데이터를 그대로 ECHO하도록 하시오!

/* USER CODE BEGIN 0 */
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//main에서 1회 호출
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);
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
if(RxMessage.StdId == 0x7DF){
TxMessage.DLC = 8; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x7E0;
TxMessage.TransmitGlobalTime = DISABLE;
for(int i = 0;i<8;i++){
TxData[i] = RxData[i];
}
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
Can_Set();
/* USER CODE END 2 */
5.PC프로그램이 현재 자동차의 속도를 물어보는 PID를 전송하면 STM32는 속도를 255(0xFF)로 고정해서 응답하도록 하시오!

/* USER CODE BEGIN 0 */
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//main에서 1회 호출
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);
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
if(RxMessage.StdId == 0x7DF){
TxMessage.DLC = 8; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x7E0;
TxMessage.TransmitGlobalTime = DISABLE;
uint8_t length = RxData[0];
uint8_t service_id = RxData[1];
uint8_t p_id = RxData[2];
//Vehicle speed
if(service_id == 0x01 && p_id == 0x0D){
TxData[0] = 3;
TxData[1] = service_id;
TxData[2] = p_id;
TxData[3] = 255;
TxData[4] = 0;
TxData[5] = 0;
TxData[6] = 0;
TxData[7] = 0;
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
}
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
Can_Set();
/* USER CODE END 2 */
6.예제5에서 가변저항을 돌리면 속도가 0~255사이로 변화하도록 하시오!

/* USER CODE BEGIN 0 */
//이 변수가 인터럽트를 포함한 여기저기서 사용할 경우 이 키워드를 붙혀야한다!
volatile uint16_t adc_value0 = 0;
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//main에서 1회 호출
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);
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
if(RxMessage.StdId == 0x7DF){
TxMessage.DLC = 8; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x7E0;
TxMessage.TransmitGlobalTime = DISABLE;
uint8_t length = RxData[0];
uint8_t service_id = RxData[1];
uint8_t p_id = RxData[2];
//Vehicle speed
if(service_id == 0x01 && p_id == 0x0D){
TxData[0] = 3;
TxData[1] = service_id;
TxData[2] = p_id;
TxData[3] = (uint8_t)(adc_value0/4095.0*255);
TxData[4] = 0;
TxData[5] = 0;
TxData[6] = 0;
TxData[7] = 0;
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
}
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
Can_Set();
HAL_ADC_Start(&hadc1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)
{
// 값 처리
adc_value0 = HAL_ADC_GetValue(&hadc1);
}
HAL_Delay(100);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
7.PC프로그램에서 자동차의 엔진RPM을 물어보는 PID를 전송하면 가변저항을 돌려서 엔진 RPM이 최소값에서 최대값 사이로 변화도록 하시오!

/* USER CODE BEGIN 0 */
//이 변수가 인터럽트를 포함한 여기저기서 사용할 경우 이 키워드를 붙혀야한다!
volatile uint16_t adc_value0 = 0;
char tx_buff[50];
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//main에서 1회 호출
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);
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
if(RxMessage.StdId == 0x7DF){
TxMessage.DLC = 8; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x7E0;
TxMessage.TransmitGlobalTime = DISABLE;
uint8_t length = RxData[0];
uint8_t service_id = RxData[1];
uint8_t p_id = RxData[2];
//Engine speed
if(service_id == 0x01 && p_id == 0x0C){
TxData[0] = 4;
TxData[1] = service_id;
TxData[2] = p_id;
uint16_t rpm = (uint16_t)(adc_value0/4095.0*16383.75);
TxData[3] = (rpm*4)/256; //A
TxData[4] = (rpm*4)%256; //B
TxData[5] = 0;
TxData[6] = 0;
TxData[7] = 0;
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
sprintf(tx_buff,"RPM=%d, A=%02X, B=%02X, C_RPM=%d\n",rpm,TxData[3],TxData[4],(TxData[3]*256+TxData[4])/4);
HAL_UART_Transmit(&huart2,tx_buff,strlen(tx_buff),100);
}
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
Can_Set();
HAL_ADC_Start(&hadc1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)
{
// 값 처리
adc_value0 = HAL_ADC_GetValue(&hadc1);
}
HAL_Delay(100);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
8.동일한 방식으로 자동차의 냉각수 온도를 조회하시오!

/* USER CODE BEGIN 0 */
//이 변수가 인터럽트를 포함한 여기저기서 사용할 경우 이 키워드를 붙혀야한다!
volatile uint16_t adc_value0 = 0;
char tx_buff[50];
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
//main에서 1회 호출
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);
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
if(RxMessage.StdId == 0x7DF){
TxMessage.DLC = 8; //데이터길이
TxMessage.ExtId = 0;
TxMessage.IDE = CAN_ID_STD;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.StdId = 0x7E0;
TxMessage.TransmitGlobalTime = DISABLE;
uint8_t length = RxData[0];
uint8_t service_id = RxData[1];
uint8_t p_id = RxData[2];
//Engine coolant temperature
if(service_id == 0x01 && p_id == 0x05){
TxData[0] = 4;
TxData[1] = service_id;
TxData[2] = p_id;
int16_t temp = (uint16_t)(adc_value0/4095.0*255) -40;
TxData[3] = temp + 40;
TxData[4] = 0;
TxData[5] = 0;
TxData[6] = 0;
TxData[7] = 0;
HAL_CAN_AddTxMessage(&hcan, &TxMessage, TxData, &TxMailbox);
sprintf(tx_buff,"temp=%d, A=%02X, c_temp=%d\n",temp,TxData[3],TxData[3]-40);
HAL_UART_Transmit(&huart2,tx_buff,strlen(tx_buff),100);
}
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
Can_Set();
HAL_ADC_Start(&hadc1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)
{
// 값 처리
adc_value0 = HAL_ADC_GetValue(&hadc1);
}
HAL_Delay(100);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}


