一 . 最近接到一个案子,需要用PIC18F26Q84 进行CAN总线编程,进入到MCC 编程界面里面。
先梳理一下配置寄存器的流程,以前调过MCP2515的CAN总线配置。流程大概是
1. 进入允许设置寄存器模式
2. 配置CAN 总线的总线速率
3. 配置扩展帧或者标准帧的发送标识符数据(配置发送)
4. 配置扩展帧或者标准帧的接收标识符数据(配置接收)
5. 配置是标准帧格式还是扩展帧格式
6. 配置验收屏蔽寄存器
7. 进入工作模式 ,退出设置模式
8. 发送数据和根据中断接收数据
发送数据是指将数据写入发送缓冲区内
类比到PIC18 – 先确定系统频率之后,进行相关寄存器配置
额 废话不多说 程序在资源分享里面哦 PIC18F26Q84
二 . 1. 用MCC 生成一段代码,进行解读理解。 MCC 是 MICROSOFT 生成代码的一种工具,比较方便。
配置如下,时钟设置为 48M 的内部晶振。
- 可以看到生成的代码逻辑
– 进入设置模式
–设置FIFO 偏移量
–配置速率
–详细配置FIFO
–纠错判断
—设置工作模式
– 正常工作
这说明配置 CAN 总线寄存器的软件逻辑大体相似,接下来可以取几个关键点进行分析。
- 数据手册里面
由于 CXTXQCON 这个寄存器是32 位的,而PIC18F26Q84 是个8位的单片机,所以可以根据以下名字进行配置读写寄存器。
C1CONU=1; 这个寄存器说明如下
C1CONH=97; 这个寄存器说明如下
C1CONL=60; 这个寄存器说明如下 ,这个里面的设置 如果CAN 总线调通的时候是需要回过头来进行设置,以避免实际使用的时候错误干扰。
- 上面这几个寄存器已经对CAN 总线进行基本的初始化了。接下来是波特率的配置
static void CAN1_BitRateConfiguration(void)
{
// SJW 37;
C1NBTCFGL = 0x25;
// TSEG2 37;
C1NBTCFGH = 0x25;
// TSEG1 152;
C1NBTCFGU = 0x98;
// BRP 0;
C1NBTCFGT = 0x00;
}
5. 上面这几个寄存器已经对CAN 总线进行基本的初始化了。接下来是FIFO 的配置
static void CAN1_TX_FIFO_Configuration(void)
{
// TXATIE enabled; TXQEIE disabled; TXQNIE disabled;
C1TXQCONL = 0x10;
// FRESET enabled; UINC disabled;
C1TXQCONH = 0x04;
// TXAT 3; TXPRI 1;
C1TXQCONU = 0x60;
// PLSIZE 8; FSIZE 6;
C1TXQCONT = 0x05;
// TXEN enabled; RTREN disabled; RXTSEN disabled; TXATIE enabled; RXOVIE disabled; TFERFFIE disabled; TFHRFHIE disabled; TFNRFNIE disabled;
C1FIFOCON1L = 0x90;
// FRESET enabled; TXREQ disabled; UINC disabled;
C1FIFOCON1H = 0x04;
// TXAT Unlimited number of retransmission attempts; TXPRI 1;
C1FIFOCON1U = 0x60;
// PLSIZE 8; FSIZE 6;
C1FIFOCON1T = 0x05;
}
static void CAN1_RX_FIFO_Configuration(void)
{
// TXEN disabled; RTREN disabled; RXTSEN disabled; TXATIE disabled; RXOVIE enabled; TFERFFIE disabled; TFHRFHIE disabled; TFNRFNIE disabled;
C1FIFOCON2L = 0x08;
// FRESET enabled; TXREQ disabled; UINC disabled;
C1FIFOCON2H = 0x04;
// TXAT Unlimited number of retransmission attempts; TXPRI 1;
C1FIFOCON2U = 0x60;
// PLSIZE 8; FSIZE 6;
C1FIFOCON2T = 0x05;
}
//清空读取fifo
void CAN1_RX_FIFO_ResetInfo(void)
{
uint8_t index;
for (index = 0; index < NUM_OF_RX_FIFO; index++)
{
rxFifos[index].fifoHead = 0;
}
}
这段代码对应之前的两个TX FIFO 配置
6. 报错配置 – 并且已经打开中断
static void CAN1_ErrorNotificationInterruptEnable(void)
{
CAN1_SetInvalidMessageInterruptHandler(DefaultInvalidMessageHandler);
CAN1_SetBusWakeUpActivityInterruptHandler(DefaultBusWakeUpActivityHandler);
CAN1_SetBusErrorInterruptHandler(DefaultBusErrorHandler);
CAN1_SetModeChangeInterruptHandler(DefaultModeChangeHandler);
CAN1_SetSystemErrorInterruptHandler(DefaultSystemErrorHandler);
CAN1_SetTxAttemptInterruptHandler(DefaultTxAttemptHandler);
CAN1_SetRxBufferOverFlowInterruptHandler(DefaultRxBufferOverflowHandler);
PIR0bits.CANIF = 0;
// MODIF disabled; TBCIF disabled;
C1INTL = 0x00;
// IVMIF disabled; WAKIF disabled; CERRIF disabled; SERRIF disabled;
C1INTH = 0x00;
// TEFIE disabled; MODIE enabled; TBCIE disabled; RXIE disabled; TXIE disabled;
C1INTU = 0x08;
// IVMIE enabled; WAKIE enabled; CERRIE enabled; SERRIE enabled; RXOVIE enabled; TXATIE enabled;
C1INTT = 0xFC;
PIE0bits.CANIE = 1;
}
typedef enum
{
/*DLC_0 to DLC_8 for CAN 2.0 and CAN FD*/
DLC_0,
DLC_1,
DLC_2,
DLC_3,
DLC_4,
DLC_5,
DLC_6,
DLC_7,
DLC_8,
//Supported only in CAN FD mode
/*DLC_12 to DLC_64 for CAN FD*/
DLC_12,
DLC_16,
DLC_20,
DLC_24,
DLC_32,
DLC_48,
DLC_64,
} CAN_DLC;
typedef enum
{
CAN_TX_FIFO_FULL,
CAN_TX_FIFO_AVAILABLE,
} CAN_TX_FIFO_STATUS;
typedef enum
{
CAN_OP_MODE_REQUEST_SUCCESS, // Requested Operation mode set successfully
CAN_OP_MODE_REQUEST_FAIL, // Requested Operation mode set failure. Set configuration mode before setting CAN normal or debug operation mode.
CAN_OP_MODE_SYS_ERROR_OCCURED // System error occurred while setting Operation mode.
} CAN_OP_MODE_STATUS;
typedef enum
{
CAN_TX_MSG_REQUEST_SUCCESS = 0, // Transmit message object successfully placed into Transmit FIFO
CAN_TX_MSG_REQUEST_DLC_EXCEED_ERROR = 1, // Transmit message object DLC size is more than Transmit FIFO configured DLC size
CAN_TX_MSG_REQUEST_BRS_ERROR = 2, // Transmit FIFO is configured has Non BRS mode and CAN TX Message object has BRS enabled
CAN_TX_MSG_REQUEST_FIFO_FULL = 3, // Transmit FIFO is Full
}
typedef enum
{
CAN_NORMAL_FD_MODE = 0, //Supported only in CAN FD mode
CAN_DISABLE_MODE = 1,
CAN_INTERNAL_LOOPBACK_MODE = 2,
CAN_LISTEN_ONLY_MODE = 3,
CAN_CONFIGURATION_MODE = 4,
CAN_EXTERNAL_LOOPBACK_MODE = 5,
CAN_NORMAL_2_0_MODE = 6,
CAN_RESTRICTED_OPERATION_MODE =7,
} CAN_OP_MODES;
二 . 读写 FIFO
用来判断目前片子的工作状态,用以纠错。
010 = 配置状态
110 = CAN 2.0 工作状态
typedef enum
{
CAN_NORMAL_FD_MODE = 0, //Supported only in CAN FD mode
CAN_DISABLE_MODE = 1,
CAN_INTERNAL_LOOPBACK_MODE = 2,
CAN_LISTEN_ONLY_MODE = 3,
CAN_CONFIGURATION_MODE = 4,
CAN_EXTERNAL_LOOPBACK_MODE = 5,
CAN_NORMAL_2_0_MODE = 6,
CAN_RESTRICTED_OPERATION_MODE =7,
} CAN_OP_MODES;
请求操作模式
时钟配置
配置CAN 的时候需要失能 JTAG
可以使用这些寄存器名称来读取数据。