概述
本文档是在AT91SAM9X25平台上进行SylixOS CAN总线驱动开发时,对CAN总线初始化流程的分析。
适用于正在学习CAN总线开发的技术工程师。
技术实现
CAN总线的初始化流程可以分成两个部分:
一部分是CAN总线通道资源初始化,主要工作是对通道相关的管脚和中断以及总线编程时需要的时钟等资源的初始化;另一部分是CAN总线的硬件初始化,主要工作是对总线的波特率的设置、接收和发送数据邮箱(相当于缓存区)的初始化以及接收中断和错误中断的使能。
CAN总线通道资源初始化
在AT91SAM9X25平台上,CAN总线通道资源初始化如图 21所示。CAN总线的TX管脚、RX管脚和时钟的使能以及中断服务函数的绑定是CAN总线在初始化时必须做的工作。CAN总线的通信需要绑定CAN总线上层回调函数,这些上层回调函数由开发者实现,用做应用层和底层的通信。时钟的获取是总线工作需要用到的数据,我们在总线初始化时先将其获取存在全局结构体变量中。
图 21 CAN总线通道资源初始化流程图
具体的代码实现如程序清单 21所示。
程序清单 21 CAN总线通道资源初始化
/*********************************************************************************************************
** 函数名称: __canChanDataInit
** 功能描述: 初始化通道数据(资源)相关
** 输 入 : uiChannel :通道号
** 输 出 : ERROR_CODE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT __canChanDataInit (UINT uiChannel)
{
__PCAN_CHANNEL pChannel;
ULONG ulVector;
UINT uiInputClock;
INT iRet;
static CPCHAR pcCanIsrName[] = {"can_isr0", "can_isr1"}; /* const char类型的can中断名称 */
if (uiChannel >= CAN_CHAN_NUMS) {
printk("channel invalid.n");
return PX_ERROR;
}
pChannel = &__GCanChannels[uiChannel]; /* 定义一个全局通道类型结构体 */
__canIomuxConfig(uiChannel); /* 管脚复用 */
uiInputClock = __at91sam9X25SysClkGet(MCK); /* 获取系统时钟 */
pChannel->CANCH_uiInputClock = uiInputClock;
pChannel->CANCH_canchan.pDrvFuncs = &__GCanDrvFuncs; /* 绑定CAN 总线上层回调函数 */
pChannel->CANCH_uiMb0Id = 0x7FF;
API_AtomicSet(0, &pChannel->CANCH_atomicRef); /* 原子赋值操作 */
ulVector = pChannel->CANCH_ulVector; /* 中断号 */
iRet = (INT)API_InterVectorConnect(ulVector, /* 绑定中断服务函数 */
(PINT_SVR_ROUTINE)__canIrq,
(PVOID)pChannel,
pcCanIsrName[uiChannel]);
if (iRet != ERROR_NONE) {
printk("interrupt vector connect error.n");
return PX_ERROR;
}
API_InterVectorEnable(pChannel->CANCH_ulVector); /* 使能对应中断 */
return ERROR_NONE;
}
CAN总线硬件初始化
在AT91SAM9X25平台上,CAN总线硬件初始化如图 22所示。中断使能和波特率设置是每个CAN总线都需要做的工作。CAN总线波特率是根据具体使用情况和芯片的硬件特性决定的,需要配置相关寄存器来实现。消息邮箱是AT91SAM9X25平台特有的用来接收和发送消息的一组寄存器,相当于发送和接收缓存区。这些邮箱可以根据开发者的需求来配置成接收或者发送模式。
图 22 CAN总线硬件初始化流程图
具体代码实现如程序清单 22所示。
程序清单 22 CAN总线硬件初始化
/*********************************************************************************************************
** 函数名称: __canChanHwInit
** 功能描述: 硬件初始化
** 输 入 : pChannel :通道对象
** 输 出 : ERROR_CODE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT __canChanHwInit (__PCAN_CHANNEL pChannel)
{
UINT uiRegIer;
writel(AT91_IRQ_ALL, REG_CAN_IDR(CHANNEL)); /* 禁用所有中断 */
writel(readl(REG_CAN_MR(CHANNEL)) & ~AT91_MR_CANEN, /* CAN 总线失能 */
REG_CAN_MR(CHANNEL));
__canSetBaudRate(pChannel, CAN_MAX_BAUDRATE); /* 设置CAN波特率 */
__canSetMailboxes(pChannel); /* 配置消息邮箱 */
writel(AT91_MR_CANEN, REG_CAN_MR(CHANNEL)); /* CAN 总线使能 */
uiRegIer = (AT91_MB_MASK(TX_FIRST) & (~AT91_MB_MASK(TX_FIRST))) /* 0-5邮箱中断位 */
| AT91_IRQ_ERRP /* 被动错误中断使能 */
| AT91_IRQ_ERR_FRAME; /* 帧错误中断使能 */
writel(AT91_IRQ_ALL, REG_CAN_IDR(CHANNEL)); /* 禁用所有中断 */
writel(uiRegIer, REG_CAN_IER(CHANNEL)); /* 使能错误中断和0-5邮箱中断 */
return ERROR_NONE;
}
上一篇:arm9x25交叉编译IPTABLES问题与解决
下一篇:rootfs根文件系统创建脚本
推荐阅读最新更新时间:2024-11-10 16:31
设计资源 培训 开发板 精华推荐
- EVAL-AD7730EBZ,用于 AD7730、24 位、1.2 KSPS、2 通道模数转换器的评估板
- NCP81239LOADGEVK:USB 供电 4 开关降压升压控制器评估套件
- LTM4608AIY 2.7V 至 5.5Vin、1.2V 输出 DC/DC 稳压器在扩频操作中的典型应用电路
- DKDEV-5CSXC6N、Cyclone V SoC 开发套件和 SoC 嵌入式设计套件提供了一种快速简单的方法来开发基于 ARM 处理器的定制 SOC 设计
- LTC2908IDDB-B1、3.3V 和 2.5V 双电源监视器的典型应用电路,未来可能扩展至多达六个电源
- TLV431A 低压精密可调并联稳压器的典型应用
- PIC16 工厂自动化 MCU 开发系统
- LTM4620IY 26A、1.2V 输出 DC/DC 模块稳压器的典型应用电路
- 使用外部基准电流的 LT3089EDF 线性稳压器的典型应用电路
- TL494脉宽调制推挽转换器的典型应用