对于can的驱动函数文件加注释。在can(加注释).c中标了“//2024.6”的语句加以理解并写出注释
37 CANMode = CAN_MODE_NORMAL; //2024.6
CANMode:定义于can.h第45行,CAN总线工作模式,分别为正常模式(CAN_MODE_NORMAL)、回环模式(CAN_MODE_LOOPBACK)、静默模式(CAN_MODE_SILENT)以及回环与静默组合模式(CAN_MODE_SILENT_LOOPBACK)
被使用于第325行CAN_SWInit_BT CAN总线位时序配置函数
72 if(can_send_once(canNo,DestID,send_length,buff+len-i) == 1) //2024.6
{
return 1;
}
位于can_send CAN模块发送数据函数中
can_send_once CAN模块发送一次数据函数位于172行。
canNo:模块号,本芯片只有CAN_1;
DestID:目标CAN节点的唯一标识,例如按照CANopen协议给出;
send_length:待发送数据的字节数;
buff+len-i:待发送数据发送缓冲区首地址
如果发送失败,can_send_once将返回1 ,使can_send结束发送并返回1
94 if ((CAN_ARR[canNo-1]->RF0R & CAN_RF0R_FMP0) == 0U) //2024.6
{
return 1;
}
位于can_recv函数,它用于在CAN模块接收中断中调用本函数接收已经到达的数据
CAN_ARR定义于第9行:CAN_TypeDef *CAN_ARR[] = {(CAN_TypeDef*)CAN1_BASE};,CAN1_BASE定义于stm32|431xx.h第958行;
RF0R是是标志CAN接收状态的FIFO寄存器;
CAN_RF0R_FMP0 位于stm32|431xx.h第2310行,FIFO 0消息挂起标志
如果正在接收信号的邮箱处于挂起状态,则结束接收
107 len = (CAN_RDT0R_DLC & CAN_ARR[canNo-1]->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos; //2024.6
CAN_RDT0R是CAN接收FIFO邮箱数据长度控制和时间戳寄存器,存储接收消息的数据长度和时间戳;
CAN_RDT0R_DLC定义于stm32|431xx.h第2619行,数据长度代码,其值等于0x0000000F
CAN_FIFOMailBox_TypeDef定义于stm32|431xx.h第234行,RDTR定义于stm32|431xx.h第231行,是CAN接收FIFO邮箱数据长度控制和时间戳寄存器;
CAN_RDT0R_DLC_Pos定义于stm32|431xx.h第2617行,属于CAN_RDT0R寄存器的位定义,其值等于(0U)
获取数据长度,利用CAN_RDT0R_DLC掩码限制高位,CAN_RDT0R_DLC_Pos右移限制低位,得出RDTR寄存器所存的数据长度
120 SET_BIT(CAN_ARR[canNo-1]->RF0R, CAN_RF0R_RFOM0); //2024.6
SET_BIT定义于stm32|4xx.h第207行,用于添加到组导出的宏,SET_BIT(REG, BIT)相当于((REG) |= (BIT))
CAN_RF0R_RFOM0定义于stm32|431xx.h第2319行,其值等于0x00000020,用于释放FIFO 0输出邮箱
将RF0R CAN接收状态设为释放FIFO 0输出邮箱
140 SET_BIT(CAN_ARR[canNo-1]->IER, CAN_IER_FMPIE0); //2024.6
IER定义于stm32|431xx.h第164行,ADC中断使能寄存器;
CAN_IER_FMPIE0定义于stm32|431xx.h第2341行,其值等于0x00000002,用于启用FIFO消息挂起中断;
启用ADC中断使能的FIFO消息挂起中断
143 NVIC_EnableIRQ(table_irq_can[Can_Rx_FifoNo]); //2024.6
NVIC_EnableIRQ定义于core_cm4.h第1679行,用于短暂启用NVIC中断控制器中的设备特定中断,__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) ;
param[in]IRQn:设备特定的中断编号,注意IRQn不得为负数。
table_irq_can定义于第10行,IRQn_Type table_irq_can[2] = {CAN1_RX0_IRQn, CAN1_RX1_IRQn};;
CAN1_RX0_IRQn定义于stm32|431xx.h第99行,其值等于20,CAN1 RX0中断;
Can_Rx_FifoNo:中断使用的邮箱号,其值等于CAN_RX_FIFO0;
CAN_RX_FIFO0定义于can.h第17行,其值等于0x00000000U,标志CAN接收FIFO0;
短暂启用NVIC的CAN1接收FIFO0中断
186 transmit_mailbox = (register_tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos; //2024.6
transmit_mailbox定义于第175行;
register_tsr定义于第176行,于第179行被赋值register_tsr = READ_REG(CAN_ARR[canNo-1]->TSR);
READ_REG定义于stm32|4xx.h第217行,READ_REG (REG)相当于((REG));
TSR是CAN发送状态寄存器;
CAN_TSR_CODE定义于stm32|431xx.h第2279行,其值等于0x03000000,邮箱代码;
CAN_TSR_CODE_Pos定义于stm32|431xx.h第2277行,其值等于(24U) ;
将邮箱的发送状态寄存在transmit_mailbox中
193~200 if(DestID <= 0x7FFU) //2024.6
{
CAN_ARR[canNo-1]->sTxMailBox[transmit_mailbox].TIR = ((DestID << CAN_TI0R_STID_Pos)|CAN_ID_STD|rtr); //2024.6
}
else
{
CAN_ARR[canNo-1]->sTxMailBox[transmit_mailbox].TIR = ((DestID << CAN_TI0R_EXID_Pos)|CAN_ID_EXT|rtr); //2024.6
}
sTxMailBox定义于stm32|431xx.h第261行,CAN Tx邮箱,地址偏移0x180 - 0x1AC;
TIR定义于stm32|431xx.h第218行,CAN TX邮箱标识符寄存器;
CAN_TI0R_STID_Pos定义于stm32|431xx.h第2447行,其值等于(21U),标准标识符的偏移量;
CAN_TI0R_EXID_Pos定义于stm32|431xx.h第2444行,其值等于(3U),扩展标识符的偏移量;
CAN_ID_STD定义于can.h第89行,其值等于0x00000000U,标准标识符;
CAN_ID_EXT定义于can.h第89行,其值等于0x00000004U,扩展标识符;
rtr定义于第177行,其值等于CAN_RTR_DATA;
CAN_RTR_DATA定义于can.h第21行,其值等于0x00000000U,数据帧;
根据目标CAN节点的标识判断并设置发送帧为标准帧还是扩展帧。如果DestID <= 0x7FFU则为标准帧,将标准帧的CAN节点以数据帧形式将标识符、标识符存储在CAN TX邮箱标识符寄存器;反之为扩展帧,存储扩展帧的在CAN TX邮箱标识符寄存器
205 WRITE_REG(CAN_ARR[canNo-1]->sTxMailBox[transmit_mailbox].TDHR, //2024.6
((uint32_t)buff[7] << CAN_TDH0R_DATA7_Pos) |
((uint32_t)buff[6] << CAN_TDH0R_DATA6_Pos) |
((uint32_t)buff[5] << CAN_TDH0R_DATA5_Pos) |
((uint32_t)buff[4] << CAN_TDH0R_DATA4_Pos));
WRITE_REG定义于stm32|4xx.h第215行,WRITE_REG(REG, VAL)相当于((REG) = (VAL));
TDHR定义于stm32|431xx.h第221行,CAN邮箱数据高位寄存器;
buff:待发送数据发送缓冲区首地址;
CAN_TDH0R_DATA4_Pos定义于stm32|431xx.h第2478行,其值等于(0U),数据字节4的偏移量;
将待发送数据写入邮箱数据高位寄存器
216 SET_BIT(CAN_ARR[canNo-1]->sTxMailBox[transmit_mailbox].TIR, CAN_TI0R_TXRQ); //2024.6
CAN_TI0R_TXRQ定义于stm32|431xx.h第2279行,其值等于0x00000001,传输邮箱请求;
将传输邮箱请求写入邮箱标识符寄存器
239 RCC->APB1ENR1 |= RCC_APB1ENR1_CAN1EN; //2024.6
RCC定义于stm32|431xx.h第1092行,其值等于((RCC_TypeDef *) RCC_BASE) ,其结构体RCC_TypeDef定义于stm32|431xx.h第636行,简短的重置和时钟控制;
RCC_BASE定义于stm32|431xx.h第990行,其值等于(AHB1PERIPH_BASE + 0x1000UL);
AHB1PERIPH_BASE定义于stm32|431xx.h第939行,其值等于(PERIPH_BASE + 0x00020000UL);
PERIPH_BASE定义于stm32|431xx.h第922行,其值等于0x40000000UL,外围基本地址;
APB1ENR1定义于stm32|431xx.h第619行,RCC APB1外围时钟启用寄存器1,地址偏移0x58;
RCC_APB1ENR1_CAN1EN定义于stm32|431xx.h第9811行,其值等于(0x1UL << RCC_APB1ENR1_CAN1EN_Pos),即0x02000000;
将CAN1 Enable标志写入外围时钟启用寄存器1,启用CAN1外围时钟
242 GPIOA->MODER |= (GPIO_MODER_MODE11_1|GPIO_MODER_MODE12_1); //2024.6
GPIOA定义于stm32|431xx.h第1097行,其值等于((GPIO_TypeDef *) GPIOA_BASE) ,其实例GPIO Instances定义于stm32|431xx.h第14682行,其结构体GPIO_TypeDef定义于stm32|431xx.h第469行,简要的通用I/O;
GPIOA_BASE定义于stm32|431xx.h第1017行,其值等于(AHB2PERIPH_BASE + 0x0000UL);
AHB2PERIPH_BASE定义于stm32|431xx.h第940行,其值等于(PERIPH_BASE + 0x08000000UL);
MODER定义于stm32|431xx.h第458行,GPIO端口模式寄存器,地址偏移0x00;
GPIO_MODER寄存器的位定义从stm32|431xx.h第7040行开始;
GPIO_MODER_MODE11_1定义于stm32|431xx.h第7100行,其值等于0x00800000;
GPIO_MODER_MODE12_1定义于stm32|431xx.h第7105行,其值等于0x02000000;
对GPIOA的模式初始化
244 GPIOA->AFR[1] |= (GPIO_AFRH_AFSEL11_0|GPIO_AFRH_AFSEL11_3)|(GPIO_AFRH_AFSEL12_0|GPIO_AFRH_AFSEL12_3); //2024.6
AFR定义于stm32|431xx.h第466行,GPIO替代功能寄存器,地址偏移0x20-0x24;
GPIO_AFRH替代功能高位寄存器的位定义从stm32|431xx.h第7929行开始;
GPIO_AFRL替代功能低位寄存器的位定义从stm32|431xx.h第7861行开始;
GPIO_AFRH_AFSEL11_0定义于stm32|431xx.h第7954行,其值等于0x00001000;
GPIO_AFRH_AFSEL11_3定义于stm32|431xx.h第7957行,其值等于0x00008000;
GPIO_AFRH_AFSEL12_0定义于stm32|431xx.h第7961行,其值等于0x00010000;
GPIO_AFRH_AFSEL12_3定义于stm32|431xx.h第7964行,其值等于0x00080000;
将通用I/O的11、12引脚设置复用功能
278 CLEAR_BIT(CAN_ARR[canNo-1]->MCR, CAN_MCR_SLEEP); //2024.6
CLEAR_BIT定义于stm32|4xx.h第209行,CLEAR_BIT(REG, BIT)相当于((REG) &= ~(BIT));
MCR定义于stm32|431xx.h第252行,CAN主控制寄存器,地址偏移0x00;
CAN_MCR主控制寄存器的位定义从stm32|431xx.h第2173行开始;
CAN_MCR_SLEEP定义于stm32|431xx.h第2179行,其值等于0x00000002,睡眠模式请求;
主控制寄存器清除睡眠模式请求
280 while ((CAN_ARR[canNo-1]->MSR & CAN_MSR_SLAK) != 0U) //2024.6
{
if (i++ > 0x30000)
{
return 1;
}
}
MSR定义于stm32|431xx.h第253行,CAN主状态寄存器,地址偏移0x04;
CAN_MSR主状态寄存器的位定义从stm32|431xx.h第2202行开始;
CAN_MSR_SLAK定义于stm32|431xx.h第2208行,其值等于0x00000002,睡眠确认;
当CAN正在睡眠模式时进入循环,等待30000次循环的延迟后返回初始化出现错误
288 SET_BIT(CAN_ARR[canNo-1]->MCR, CAN_MCR_INRQ); //2024.6
CAN_MCR_INRQ定义于stm32|431xx.h第2176行,其值等于0x00000001,初始化请求;
主控制寄存器写入初始化请求
308~313 CLEAR_BIT(CAN_ARR[canNo-1]->MCR, CAN_MCR_TTCM); //2024.6
CLEAR_BIT(CAN_ARR[canNo-1]->MCR, CAN_MCR_ABOM); //2024.6
CLEAR_BIT(CAN_ARR[canNo-1]->MCR, CAN_MCR_AWUM); //2024.6
SET_BIT(CAN_ARR[canNo-1]->MCR, CAN_MCR_NART); //2024.6
CLEAR_BIT(CAN_ARR[canNo-1]->MCR, CAN_MCR_RFLM); //2024.6
CLEAR_BIT(CAN_ARR[canNo-1]->MCR, CAN_MCR_TXFP); //2024.6
CAN_MCR_TTCM定义于stm32|431xx.h第2197行,其值等于0x00000080,时间触发通信模式;
CAN_MCR_ABOM定义于stm32|431xx.h第2194行,其值等于0x00000040,自动总线断开管理;
CAN_MCR_AWUM定义于stm32|431xx.h第2191行,其值等于0x00000020,自动唤醒模式;
CAN_MCR_NART定义于stm32|431xx.h第2188行,其值等于0x00000010,无自动重新传输;
CAN_MCR_RFLM定义于stm32|431xx.h第2185行,其值等于0x00000008,接收FIFO锁定模式;
CAN_MCR_TXFP定义于stm32|431xx.h第2182行,其值等于0x00000004,传输FIFO优先级;
取消时间触发通信模式、自动总线断开管理、自动唤醒模式、接收FIFO锁定模式、传输FIFO优先级;启用无自动重新传输
324 CAN_ARR[canNo-1]->BTR |= ((uint32_t)(Prescaler-1)|CAN_SJW_1TQ|CAN_BTR_TS1_1|CAN_BTR_TS1_0|CAN_BTR_TS2_2|CANMode); //2024.6
BTR定义于stm32|431xx.h第259行,CAN位定时寄存器,地址偏移0x1C;
CAN_BTR定时寄存器的位定义从stm32|431xx.h第2404行开始;
Prescaler:预分频器,当第28行can_init函数被调用后,其参数BitRate位速率将在第49行调用函数CAN_SWInit_BT时被传入该预分频器;
CAN_SJW_1TQ定义于can.h第40行,其值等于0x00000001,是否激活过滤器选项中的1时间片;
CAN_BTR_TS1_1定义于stm32|431xx.h第2412行,其值等于0x00020000;
CAN_BTR_TS1_0定义于stm32|431xx.h第2411行,其值等于0x00010000;
CAN_BTR_TS2_2定义于stm32|431xx.h第2420行,其值等于0x00400000;
对定时寄存器写入预分频、过滤器1时间片、时间段1_1、时间段1_0、时间段2_2、CAN模式的设定数据
336 CLEAR_BIT(CAN_ARR[canNo-1]->MCR, CAN_MCR_INRQ); //2024.6
清空主控制寄存器的初始化请求
338 while ((CAN_ARR[canNo-1]->MSR & CAN_MSR_INAK) != 0U) //2024.6
{
if (i++ > 0x30000)
{
return 1;
}
}
CAN_MSR_INAK定义于stm32|431xx.h第2205行,其值等于0x00000001,初始化确认;
当主状态寄存器已得到初始化确认后进入循环,等待30000次循环的延迟后返回初始化出现错误
363 if(CanID <= 0x7FFU) CanID = CanID << CAN_TI0R_STID_Pos; //2024.6
CanID:自身CAN节点的唯一标识,例如按照CANopen协议给出
如果CAN节点标识还没有被移到最右边5位的话,将其右移到那里
365~369 FilterIdHigh = (CanID >> 16) & 0xFFFF; //2024.6
FilterIdLow = (CanID & 0xFFFF); //2024.6
FilterMaskIdHigh = 0xFFE0; //2024.6
FilterMaskIdLow = 0x0000; //2024.6
filternbrbitpos = (uint32_t)1 << (FilterBank & 0x1FU); //2024.6
FilterIdHigh:过滤器标识高字节,被使用于第382、388行;
FilterIdLow:过滤器标识低字节,被使用于第379、389行;
FilterMaskIdHigh:过滤器掩码标识高字节,被使用于第381、391行;
FilterMaskIdLow:过滤器掩码标识低字节,被使用于第378、392行;
Filternbrbitpos:过滤器组选择生成的掩码,被使用于第376、396行;
FilterBank:CAN总线过滤器组选择,共有28个,(CANFilterBank0~CANFilterBank27);
从CanID提取过滤器标识,暂存过滤器掩码,利用过滤器组选择左移1来获得一个可以选择一个过滤器进行调整的掩码
371~373 //设置过滤器初始化模式 (FINIT=1),在此模式下可以进行过滤器初始化
SET_BIT(CAN_ARR[canNo-1]->FMR, CAN_FMR_FINIT); //2024.6
CLEAR_BIT(CAN_ARR[canNo-1]->FA1R, filternbrbitpos); //2024.6
FMR定义于stm32|431xx.h第264行,CAN过滤器主寄存器,地址偏移0x200;
CAN_FMR过滤器主寄存器的位定义从stm32|431xx.h第2709行开始;
CAN_FMR_FINIT定义于stm32|431xx.h第2712行,其值等于0x00000001,过滤器初始化模式;
FA1R定义于stm32|431xx.h第271行,CAN过滤器激活寄存器,地址偏移0x21C;
CAN_FA1R过滤器激活寄存器的位定义从stm32|431xx.h第2855行开始;
过滤器启用初始化模式,取消激活FilterBank指向的过滤器
384 if (FilterScale == CAN_FILTERSCALE_32BIT) //2024.6
FilterScale:CAN总线过滤器位数,分别为32位(CAN_FILTERSCALE_32BIT)和16位(CAN_FILTERSCALE_16BIT);
CAN_FILTERSCALE_32BIT定义于can.h第30行,其值等于0x00000001U,单32位过滤器;
如果过滤器是32位的话
386~389 SET_BIT(CAN_ARR[canNo-1]->FS1R, filternbrbitpos); //2024.6
CAN_ARR[canNo-1]->sFilterRegister[FilterBank].FR1 = //2024.6
((0x0000FFFFU & (uint32_t)FilterIdHigh) << 16U) |
(0x0000FFFFU & (uint32_t)FilterIdLow);
FS1R定义于stm32|431xx.h第267行,CAN过滤器刻度寄存器,地址偏移0x20C;
CAN_FS1R过滤器刻度寄存器的位定义从stm32|431xx.h第2761行开始;
FR1定义于stm32|431xx.h第242行,CAN滤波器组寄存器1;
设置FilterBank指向的过滤器的刻度,向CAN滤波器组寄存器1写入过滤器标识
394~397 if (FilterMode == CAN_FILTERMODE_IDMASK) //2024.6
{
CLEAR_BIT(CAN_ARR[canNo-1]->FM1R, filternbrbitpos); //2024.6
}
FilterMode:CAN总线过滤器模式,分别为掩码模式(CAN_FILTERMODE_IDMASK)和列表模式(CAN_FILTERMODE_IDLIST);
CAN_FILTERMODE_IDMASK定义于can.h第25行,其值等于0x00000000U,过滤器掩码模式;
FM1R定义于stm32|431xx.h第265行,CAN过滤器模式寄存器,地址偏移0x204;
CAN_FM1R过滤器模式寄存器的位定义从stm32|431xx.h第2714行开始;
如果过滤器是掩码模式,则清除FilterBank指向的过滤器的模式寄存器
402~405 if (Can_Rx_FifoNo == CAN_FILTER_FIFO0) //2024.6
{
CLEAR_BIT(CAN_ARR[canNo-1]->FFA1R, filternbrbitpos); //2024.6
}
Can_Rx_FifoNo:中断使用的邮箱号;
CAN_FILTER_FIFO0定义于can.h第33行,其值等于0x00000000U,过滤器FIFO邮箱0;
FFA1R定义于stm32|431xx.h第269行,CAN过滤器FIFO分配寄存器,地址偏移0x214;
CAN_FFA1R过滤器FIFO分配寄存器的位定义从stm32|431xx.h第2808行开始;
如果中断邮箱号为0,则清除FilterBank指向的过滤器的FIFO分配寄存器
410~413 if (IsActivate == 1) //2024.6
{
SET_BIT(CAN_ARR[canNo-1]->FA1R, filternbrbitpos); //2024.6
}
IsActivate:是否激活过滤器
如果过滤器已被激活,则启用FilterBank指向的过滤器的激活寄存器
415 CLEAR_BIT(CAN_ARR[canNo-1]->FMR, CAN_FMR_FINIT); //2024.6
退出过滤器初始化模式 (FINIT=0)
结果截图:
连线照片: