PIC18F,ECAN例程,支持CAN总线活动唤醒
来源:互联网 发布:ubuntu安装py模块 编辑:程序博客网 时间:2024/06/07 07:33
程序说明:
处理器:PIC18F66K80系列
系统频率:32M (外部晶振8M,4倍频得到)
缓冲器:接收缓冲器0,接受滤波器0,发送缓冲器0
源文件
/*********************************************************************** Includes **********************************************************************/#include "bsp.h"/*********************************************************************** Defines **********************************************************************/ // ECAN bitrate define, only can choose one rate#define F_ECAN_100 0 // 1 set ECAN module on 100Kbps#define F_ECAN_125 0 // 1 set ECAN module on 125Kbps#define F_ECAN_500 1 // 1 set ECAN module on 500Kbps#define F_ECAN_1000 0 // 1 set ECAN module on 1Mbps/*********************************************************************** Global Variables **********************************************************************//* 定义全局变量 */CanTxMsg g_tCanTxMsg;/* 用于发送 */CanRxMsg g_tCanRxMsg;/* 用于接收 *//*********************************************************************** Function: Initialize the CAN Module**********************************************************************/void ECAN_Init(void){ CAN_STB_SetDigitalOutput();//CAN收发器待机模式端配置为输出 CAN_TX_SetDigitalOutput(); CAN_RX_SetDigitalInput(); // Place CAN module in configuration mode, see CANCON register data CANCON = 0x80; //REQOP bits <2:0> = 0b100// while(!(CANSTATbits.OPMODE ==0x04)); //Wait for op-mode bits in the while(CANSTAT != 0X80); //CANSTAT register to = 0b100 //to indicate config mode OK // Enter CAN module into Mode 0, standard legacy mode; see ECANCON register ECANCON = 0x00; // See Microchip application note AN754, Understanding Microchip's // CAN Module Bit Timing." See also: Microchip Controller Area Network //(CAN) Bit Timing Calculator, available at Intrepid Control Systems: //www.intrepidcs.com/support/mbtime.htm. // Initialize CAN Bus bit rate timing. Assumes only four standard rates. // Initialize CAN Timing if (F_ECAN_100==1) { // 100 Kbps @ 32MHz BRGCON1 = 0x13; //SJW=1TQ BRP 19 BRGCON2 = 0x90; //SEG2PHTS 1 sampled once PS1=3TQ PropagationT 1TQ BRGCON3 = 0x02; //PS2 3TQ } else if (F_ECAN_125==1) { // 125 Kbps @ 32MHz BRGCON1 = 0x0F; //SJW=1TQ BRP 15 BRGCON2 = 0x90; //SEG2PHTS 1 sampled once PS1=3TQ PropagationT 1TQ BRGCON3 = 0x02; //PS2 3TQ } else if (F_ECAN_500==1) { // 125 Kbps @ 32MHz BRGCON1 = 0x03; //SJW=1TQ BRP 3 BRGCON2 = 0x90; //SEG2PHTS 1 sampled once PS1=3TQ PropagationT 1TQ BRGCON3 = 0x02; //PS2 3TQ } else if (F_ECAN_1000==1) { // 1000 Kbps @ 32MHz BRGCON1 = 0x01; //SJW=1TQ BRP 1 BRGCON2 = 0x90; //SEG2PHTS 1 sampled once PS1=3TQ PropagationT 1TQ BRGCON3 = 0x02; //PS2 3TQ } // Initialize Receive Masks, see registers RXMxEIDH, RXMxEIDL, etc... // Mask 0 (M0) will accept NO extended addresses, but any standard address RXM0EIDH = 0x00; // Extended Address receive acceptance mask, high byte RXM0EIDL = 0x00; // Extended Address receive acceptance mask, low byte RXM0SIDH = 0xFF; // Standard Address receive acceptance mask, high byte RXM0SIDL = 0xE0; // Standard Address receive acceptance mask, low byte // Mode 0 allows use of receiver filters RXF0 through RXF5. Enable filters // RXF0 and RXF1, all others disabled. See register RXFCONn. // Only using two filters RXFCON0 = 0x01; //Enable Filter-0; disable others RXFCON1 = 0x00; //Disable Filters 8 through 15 // Initialize Receive Filters // Filter 0 = 0x312 RXF0EIDH = 0x00; //Extended Address Filter-0 unused, set high byte to 0 RXF0EIDL = 0x00; //Extended Address Filter-0 unused, set low byte to 0 RXF0SIDH = (uint8_t)(0x312>>3); //Standard Address Filter-0 high byte set to xx RXF0SIDL = (uint8_t)(0x312<<5)&0xE0; //Standard Address Filter-0 low byte set to xx TXB0CON=0X03;//TXB0为最高优先级3 // After configuring CAN module with above settings, return it // to Normal mode CANCON = 0x00;// while(CANSTATbits.OPMODE!=0x00); //Wait for op-mode bits in the while(CANSTAT != 0X00); //CANSTAT register to = 0b000 //to indicate Normal mode OK RXB0CON = 0x20;//只接收有效的标准标识符信息 /* 初始化CAN的中断,PIR5为CAN的外围中断标志寄存器 */ PIR5=0X00; // 清所有CAN中断标志 PIE5bits.RXB0IE = 1; //使能接收缓冲器0的接收中断 IPR5bits.RXB0IP = 1; // 接收缓冲器0的接收中断为高优先级 // PIR5bits.WAKIF = 0; //清除CAN总线活动唤醒中断标志// PIE5bits.WAKIE = 1; //允许CAN总线活动唤醒中断// IPR5bits.WAKIP = 1; //CAN总线活动唤醒中断为高优先级}/***********************************************************************************************************函 数 名: CAN_SetMode*功能说明: 配置CAN收发器模式*形 参:mode 0,正常模式 1,待机模式*返 回 值: 无**********************************************************************************************************/void CAN_SetMode(uint8_t mode){ if(mode == 0) { CAN_STB_SetLow(); } else { CAN_STB_SetHigh(); }}/*********************************************************************** Function: Check the buffers to determine if they have messages* if so, transfer the info to the temporary-storage* variables. Note: Messages to receiver 0 or 1 get saved in* the same variables. This id done for simplicity in* this example. You could save messages to separate* variables, or in separate arrays, if you wish. **********************************************************************/void ECAN_Receive(CanRxMsg* RxMessage){ if (RXB0CONbits.RXFUL) // Check RXB0CON bit RXFUL to see if RX Buffer 0 // has received a message, if so, get the // associated data from the buffer and save it. { /* Get the Id */ RxMessage->IDE = RXB0SIDLbits.EXID; if (RxMessage->IDE == CAN_Id_Standard) { RxMessage->StdId = (uint16_t)RXB0SIDH<<3 | (RXB0SIDL>>5); } else { } RxMessage->RTR = RXB0DLCbits.RXRTR; /* Get the DLC */ RxMessage->DLC = RXB0DLC&0x0F; /* Get the FMI */// RxMessage->FMI = 0x00; /* Get the data field */ RxMessage->Data[0] = RXB0D0; RxMessage->Data[1] = RXB0D1; RxMessage->Data[2] = RXB0D2; RxMessage->Data[3] = RXB0D3; RxMessage->Data[4] = RXB0D4; RxMessage->Data[5] = RXB0D5; RxMessage->Data[6] = RXB0D6; RxMessage->Data[7] = RXB0D7; RXB0CONbits.RXFUL = 0; // Reset buffer-0-full bit to show "empty" } }/***********************************************************************************************************函 数 名: ECAN_Transmit*功能说明: CAN发送报文消息*形 参: 无*返 回 值: 无**********************************************************************************************************/void ECAN_Transmit(CanTxMsg* TxMessage){ TXB0CONbits.TXREQ = 0; /* 关发送 ,该位发送成功则自动清零*/ if (TxMessage->IDE == CAN_Id_Standard) { TXB0SIDH = (uint8_t)(TxMessage->StdId>>3); TXB0SIDL = (uint8_t)(TxMessage->StdId<<5)&0xE0; TXB0SIDLbits.EXIDE = TxMessage->IDE; TXB0DLCbits.TXRTR = TxMessage->RTR; } else {// TXB0EIDH = TxMessage->ExtId>>8;// TXB0EIDL = TxMessage->ExtId; } TXB0DLC = TxMessage->DLC; TXB0D0 = TxMessage->Data[0]; TXB0D1 = TxMessage->Data[1]; TXB0D2 = TxMessage->Data[2]; TXB0D3 = TxMessage->Data[3]; TXB0D4 = TxMessage->Data[4]; TXB0D5 = TxMessage->Data[5]; TXB0D6 = TxMessage->Data[6]; TXB0D7 = TxMessage->Data[7]; TXB0CONbits.TXREQ = 1; //Set the buffer to transmit //while(TXB0CONbits.TXREQ==1); //等待发送 完成 }void interrupt high_priority High_ISR(void){ if(PIR5bits.WAKIF==1)//CAN总线活动唤醒中断 { PIR5bits.WAKIF = 0; } if(PIR5bits.RXB0IF==1)//接收缓冲区0接收到报文 { PIR5bits.RXB0IF=0; // 清接收中断标志 ECAN_Receive(&g_tCanRxMsg); if ((g_tCanRxMsg.StdId == 0x312) && (g_tCanRxMsg.IDE == CAN_ID_STD) && (g_tCanRxMsg.DLC == 0x08)) { //用户自定义 } }}头文件
/* * File: eacn.h * Author: Administrator * * Created on 2017年7月11日, 下午4:33 */#ifndef ECAN_H#defineECAN_H#ifdef__cplusplusextern "C" {#endif/** * @brief CAN Tx message structure definition */#define CAN_Id_Standard 0X00 /*!< Standard Id */#define CAN_Id_Extended 0X01 /*!< Extended Id */ #define CAN_RTR_Data 0X00 /*!< Data frame */#define CAN_RTR_Remote 0X01 /*!< Remote frame */ #define CAN_ID_STD CAN_Id_Standard #define CAN_ID_EXT CAN_Id_Extended#define CAN_RTR_DATA CAN_RTR_Data #define CAN_RTR_REMOTE CAN_RTR_Remote #define CAN_MODE_NORMAL 0 //CAN收发器正常模式#define CAN_MODE_STANDBY 1 //CAN收发器待机模式typedef struct{ uint16_t StdId; /*!< Specifies the standard identifier. This parameter can be a value between 0 to 0x7FF. */ uint16_t ExtId; /*!< Specifies the extended identifier. This parameter can be a value between 0 to 0x1FFFFFFF. */ uint8_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted. This parameter can be a value of @ref CAN_identifier_type */ uint8_t RTR; /*!< Specifies the type of frame for the message that will be transmitted. This parameter can be a value of @ref CAN_remote_transmission_request */ uint8_t DLC; /*!< Specifies the length of the frame that will be transmitted. This parameter can be a value between 0 to 8 */ uint8_t Data[8]; /*!< Contains the data to be transmitted. It ranges from 0 to 0xFF. */} CanTxMsg;/** * @brief CAN Rx message structure definition */typedef struct{ uint16_t StdId; /*!< Specifies the standard identifier. This parameter can be a value between 0 to 0x7FF. */ uint16_t ExtId; /*!< Specifies the extended identifier. This parameter can be a value between 0 to 0x1FFFFFFF. */ uint8_t IDE; /*!< Specifies the type of identifier for the message that will be received. This parameter can be a value of @ref CAN_identifier_type */ uint8_t RTR; /*!< Specifies the type of frame for the received message. This parameter can be a value of @ref CAN_remote_transmission_request */ uint8_t DLC; /*!< Specifies the length of the frame that will be received. This parameter can be a value between 0 to 8 */ uint8_t Data[8]; /*!< Contains the data to be received. It ranges from 0 to 0xFF. */ uint8_t FMI; /*!< Specifies the index of the filter the message stored in the mailbox passes through. This parameter can be a value between 0 to 0xFF */} CanRxMsg;/*********************************************************************** Function Prototypes **********************************************************************/void ECAN_Init(void);void CAN_SetMode(uint8_t mode);#ifdef__cplusplus}#endif#endif/* ECAN_H */系统进入休眠
#define WAKEUP_US_DELAY 200
唤醒后振荡器起振定时时间要大于1024TOSC,TOSC = OSC1周期
/***********************************************************************************************************函 数 名: SysEnterSleep*功能说明: 系统进入休眠模式*形 参: 无*返 回 值: 无**********************************************************************************************************/ void SysEnterSleep(void){ CAN_SetMode(CAN_MODE_STANDBY);//CAN收发器进入待机模式 PIR5bits.WAKIF = 0; //清除CAN总线活动唤醒中断标志 PIE5bits.WAKIE = 1; //允许CAN总线活动唤醒中断 IPR5bits.WAKIP = 1; //CAN总线活动唤醒中断为高优先级 CANCON = 0x20;//禁止/休眠模式 while(CANSTATbits.OPMODE !=0x01); OSCCONbits.IDLEN = 0;//配置休眠模式 Sleep();//进入休眠模式 __delay_us(WAKEUP_US_DELAY);}
阅读全文
0 0
- PIC18F,ECAN例程,支持CAN总线活动唤醒
- stm32 can总线参考例程
- eCAN总线模块的位时间(Bit-Timing)配置
- CAN总线
- can总线
- CAN总线
- CAN总线
- CAN总线
- CAN 总线
- can总线
- can总线
- CAN总线
- can总线
- CAN总线
- CAN总线
- CAN总线
- CAN总线
- CAN总线
- [LeetCode]1. Two Sum
- git subtree有效管理公共第三方lib
- B和B+树
- 如何将开源项目部分代码作为private放在github上?
- Oracle 12c 数据库监听程序消失解决方法
- PIC18F,ECAN例程,支持CAN总线活动唤醒
- Phar文件
- git cheatsheet小抄本
- linux下gitflow辅助工具安装和使用
- maven常见命令
- iMindMap:写作文真的就那么难?
- how to check unsolved conflicts file list in git merge?
- UICollectionView的使用
- springboot listener使用配置