一 . 最近接到一个案子,需要用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; }//清空读取fifovoid 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
可以使用这些寄存器名称来读取数据。
|