#include "stm32f10x.h"
#include "stm32f10x_can.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_spi.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_tim.h"
#include "stdio.h"
#define CANSpeed 500000 // CAN波特率
// CAN配置结构体
typedef struct {
uint8_t ID;
uint8_t FIFO;
uint8_t Data[8];
}CanMsg, *pCanMsg;
CanMsg RxMsg, TxMsg;
// CAN中断处理函数
void CAN_IRQ(void)
{
if (CAN_GetITStatus(CAN_IT_RXOK)) { // 接收OK中断
uint32_t RxMail;
CAN_GetRxMessage(CAN1, 0, &RxMsg.ID, &RxMsg.FIFO, RxMsg.Data);
switch (RxMsg.ID) {
case 0x5301: // FIFO0接收成功
printf("FIFO0 receive success:\n");
printf("Data: ");
for (int i = 0; i < 8; i++) {
printf("%02X ", RxMsg.Data[i]);
}
printf("\n");
break;
case 0x5201: // FIFO1接收成功
printf("FIFO1 receive success:\n");
printf("Data: ");
for (int i = 0; i < 8; i++) {
printf("%02X ", RxMsg.Data[i]);
}
printf("\n");
break;
case 0x5300: // FIFO0或FIFO1接收成功
printf("FIFO0 or FIFO1 receive success:\n");
printf("Data: ");
for (int i = 0; i < 8; i++) {
printf("%02X ", RxMsg.Data[i]);
}
printf("\n");
break;
}
}
}
int main(void)
{
// 时钟配置
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
// GPIO配置CAN收发器使能引脚
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// CAN配置
CAN_InitTypeDef CAN_InitStructure;
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TDLAR = DISable;
CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
CAN_InitStructure.CAN_SJW = CAN_SJW_1sample;
CAN_InitStructure.CAN_BS1 = CAN_BS1_4sample;
CAN_InitStructure.CAN_BS2 = CAN_BS2_3sample;
CAN_InitStructure.CAN_Prescaler = SystemCoreClock / (2 * (16 + CANSpeed / 50)); // 根据系统时钟和要求波特率计算出Prescaler