[作业]嵌入式第10章:CAN总线

对于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

    }

FilterModeCAN总线过滤器模式,分别为掩码模式(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)

结果截图:

连线照片:

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值