自己的一点见解 希望得到坛友们指点
CAN 在FIFO模式进行报文收发时,需对FIFO结构中除了优先级最低的所有报文对象设置标志 MSG_OBJ_FIFO(MsgObjectRx.ulFlags |= MSG_OBJ_FIFO;),以表明这在调用的报文对象在FIFO结构中且不是最后一个。
程序中需考虑在运行时,接收和发送操作的时间先后顺序,发送FIFO须在接收FIFO接收完毕之后启动报文发送,两次发送之间。
在单个或多个报文对象的报文收发时,每一次报文收、发过程都是由单个报文对象完成。而FIFO模式每次的报文收、发过程是由结构中所有报文对象参与。
//************发送FIFO**********************
// 为CAN控制器配置的FIFO的大小 #define CAN_FIFO_SIZE 64
// 发送字节数 unsigned long BytesTransmit;
tCANMsgObject MsgObjectTx;
//定义缓冲区 unsigned char pucBufferTx[CAN_FIFO_SIZE];
// 该函数配置了发送FIFO并将数据拷贝到FIFO中 int CANTransmitFIFO(unsigned char *pucData, unsigned long ulSize) { int i;
//配置发送报文对象 MsgObjectTx.ulMsgID = 8; MsgObjectTx.ulMsgIDMask = 0; MsgObjectTx.ulFlags = MSG_OBJ_TX_INT_ENABLE;
// 将8个报文对象构成一个发送FIFO for(i = 0; i < 8; i++) {
//如果还有多于8字节的数据待发送,则用满报文形式发送8字节 if(ulSize > 8) {
MsgObjectTx.ulMsgLen = 8; MsgObjectTx.pucMsgData = &pucData[iIdx * 8];
// 设置标志 MSG_OBJ_FIFO 来表明这个报文对象为FIFO结构中的一部分,且不是FIFO的最后一个报文对象 MsgObjectTx.ulFlags |= MSG_OBJ_FIFO;
ulSize -= 8;
CANMessageSet(CAN0_BASE, i + 1, &MsgObjectTx, MSG_OBJ_TYPE_TX); }
// 如果还是有少于8字节待发送数据,则发送剩余数据, // 且清除标志 MSG_OBJ_FIFO 以表明这是最后一个在FIFO中的报文对象 else { MsgObjectTx.ulMsgLen = ulSize; MsgObjectTx.pucMsgData = &pucData[iIdx * 8];
CANMessageSet(CAN0_BASE, i + 1, &MsgObjectTx, MSG_OBJ_TYPE_TX); } } return(0); }
// 主程序 int main(void) {
······
//初始化数据缓冲区 for(j= 0; j< CAN_FIFO_SIZE; j++) { pucBufferTx[j] = j + 0x1; }
//为已发送字节数变量赋初值 BytesTransmit = 0;
//配置发送FIFO,并启动发送 CANTransmitFIFO(pucBufferTx, CAN_FIFO_SIZE);
// // Loop forever. // while(1) { //等待所有的数据发送完毕 if(BytesTransmit == CAN_FIFO_SIZE) { //复位该变量 BytesTransmit = 0; //LED指示 延时长以确保接收fifo接收完毕 ······
//更改缓冲区中的数据 ······
//配置发送FIFO,并启动发送 CANTransmitFIFO(pucBufferTx, CAN_FIFO_SIZE); } } }
//******************接收FIFO***************
//分配给CAN控制器的FIFO的大小 #define CAN_FIFO_SIZE 64
tCANMsgObject MsgObjectRx;
//定义一接收缓冲区 unsigned char Buffer[CAN_FIFO_SIZE];
//定义接收字节数变量 unsigned long BytesRemain;
// 该函数配置接收FIFO, 且该函数只会被调用一次 int CANReceiveFIFO(unsigned char *pucData, unsigned long ulSize) { int j;
// 配置接收报文FIFO,标识符 8,报文滤波 无,使能接收中断 MsgObjectRx.ulMsgID = 8; MsgObjectRx.ulMsgIDMask = 0; MsgObjectRx.ulFlags = MSG_OBJ_RX_INT_ENABLE; MsgObjectRx.pucMsgData = pucData;
// 将1~8号报文对象构成一个接受FIFO for(j=0; j < (CAN_FIFO_SIZE / 8); j++) { //若待接收字节数超过8,则将一次接收字节数设置为8 if(ulSize > 8) { MsgObjectRx.ulMsgLen = 8;
ulSize -=8;
//设置标志 MSG_OBJ_FIFO 来表明这个报文对象为FIFO结构中的一部分,且不是FIFO的最后一个报文对象 MsgObjectRx.ulFlags |= MSG_OBJ_FIFO;
CANMessageSet(CAN0_BASE, j + 1, &MsgObjectRx, MSG_OBJ_TYPE_RX);
} else { MsgObjectRx.ulMsgLen = ulSize;
// 这里不设置标志 MSG_OBJ_FIFO,表明这是最后一个在FIFO中的报文对象 CANMessageSet(CAN0_BASE, j + 1, &MsgObjectRx, MSG_OBJ_TYPE_RX); } } return(0); }
// 主程序 int main(void) {
······
//复位缓冲区指针 MsgObjectRx.pucMsgData = Buffer;
//将待接收的数据字节总数赋给该变量 BytesRemain = CAN_FIFO_SIZE;
//配置接收FIFO,并启动报文接收 CANReceiveFIFO(Buffer, CAN_FIFO_SIZE);
// // Loop forever. // while(1) { //等待所用的数据接收完毕 if(BytesRemain == 0) {
// 复位缓冲区指针 MsgObjectRx.pucMsgData = Buffer;
//复位该变量 BytesRemain = CAN_FIFO_SIZE;
//LED指示 延时短以确保在发送FIFO发送前接收完毕
······
} } }
基于LM3S8962 FIFO模式下报文收发例程
[ 本帖最后由 熊猫 于 2011-3-5 16:23 编辑 ]
|