📄 can_2110_fifo.c
字号:
//*****************************************************************************
//
// can_device_fifo.c - CAN设备在FIFO的模式下进行数据收发
// 本例程将若干报文对象配置成接收FIFO,已在EK-LM3S2110板上演示
// 先复位2110板,再启动发送设备(8962板)
//
// This is part of revision 6852 of the EK-LM3S8962 Firmware Package.
//
//*****************************************************************************
#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_sysctl.h"
#include "hw_can.h"
#include "hw_types.h"
#include "can.h"
#include "debug.h"
#include "gpio.h"
#include "interrupt.h"
#include "sysctl.h"
#include "systick.h"
//分配给CAN控制器的FIFO的大小
#define CAN_FIFO_SIZE (8 * 8)
tCANMsgObject MsgObjectRx;
//定义一接收缓冲区
unsigned char pucBuffer[CAN_FIFO_SIZE];
//定义接收字节数变量
unsigned long ulBytesRemaining;
//*****************************************************************************
//
// CAN的中断处理
//
//*****************************************************************************
void
CANIntHandler(void)
{
unsigned long ulStatus;
//读取中断原因
ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
if((ulStatus >= 1) && (ulStatus <= 8))
{
//读取报文,并清除中断
CANMessageGet(CAN0_BASE, ulStatus, &MsgObjectRx, 1);
//增大读取指针
MsgObjectRx.pucMsgData += 8;
//将待接收字节数自减8
ulBytesRemaining -= 8;
}
else if(ulStatus == CAN_INT_INTID_STATUS)
{
//清除状态中断
CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
}
//
// Acknowledge the CAN controller interrupt has been handled.
//
CANIntClear(CAN0_BASE, ulStatus);
}
//*****************************************************************************
//
// 该函数配置接收FIFO, 且该函数只会被调用一次
//
//*****************************************************************************
int
CANReceiveFIFO(unsigned char *pucData, unsigned long ulSize)
{
int iIdx;
// 配置接收报文FIFO,标识符 8,报文滤波 无,使能接收中断
MsgObjectRx.ulMsgID = 8;
MsgObjectRx.ulMsgIDMask = 0;
MsgObjectRx.ulFlags = MSG_OBJ_RX_INT_ENABLE;
MsgObjectRx.pucMsgData = pucData;
// 将1~8号报文对象构成一个接受FIFO
for(iIdx=0; iIdx < (CAN_FIFO_SIZE / 8); iIdx++)
{
//若待接收字节数超过8,则将一次接收字节数设置为8
if(ulSize > 8)
{
MsgObjectRx.ulMsgLen = 8;
//待接收字节数自减8
ulSize -=8;
//设置标志 MSG_OBJ_FIFO 来表明这个报文对象为FIFO结构中的一部分,且不是FIFO的最后一个报文对象
MsgObjectRx.ulFlags |= MSG_OBJ_FIFO;
//启动报文接收
CANMessageSet(CAN0_BASE, iIdx + 1, &MsgObjectRx, MSG_OBJ_TYPE_RX);
}
else
{
// Get the remaining bytes.
MsgObjectRx.ulMsgLen = ulSize;
// 这里不设置标志 MSG_OBJ_FIFO,表明这是最后一个在FIFO中的报文对象
CANMessageSet(CAN0_BASE, iIdx + 1, &MsgObjectRx, MSG_OBJ_TYPE_RX);
}
}
return(0);
}
//*****************************************************************************
//
// 主程序
//
//*****************************************************************************
int
main(void)
{
//
// LDO的输出电压必须在启用PLL之前设置为2.75V
if(REVISION_IS_A2)
{
SysCtlLDOSet(SYSCTL_LDO_2_75V);
}
//时钟配置 为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);
//CAN0端口配置
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
GPIOPinTypeCAN(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//配置LED所在I/O口
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
//关闭LED
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
//使能CAN控制器
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
//复位后初始化CAN控制器
CANInit(CAN0_BASE);
//CAN的操作速率配置,配置为250k
CANBitRateSet(CAN0_BASE, 8000000, 250000);
//CAN0使能
CANEnable(CAN0_BASE);
//使能CAN 相关中断
CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
IntEnable(INT_CAN0);
IntMasterEnable();
//复位缓冲区指针
MsgObjectRx.pucMsgData = pucBuffer;
//将待接收的数据字节总数赋给该变量
ulBytesRemaining = CAN_FIFO_SIZE;
//配置接收FIFO,并启动报文接收
CANReceiveFIFO(pucBuffer, CAN_FIFO_SIZE);
//
// Loop forever.
//
while(1)
{
//等待所用的数据接收完毕
if(ulBytesRemaining == 0)
{
// 复位缓冲区指针
MsgObjectRx.pucMsgData = pucBuffer;
//复位该变量
ulBytesRemaining = CAN_FIFO_SIZE;
//LED指示
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x04); //在这里需注意:这里启动报文接收必须要在
//8962板启动报文发送之前,所以这里的延时
SysCtlDelay(16000000 / 6); //必须小于发送FIFO例程中的延时时间(16000000/3)
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
SysCtlDelay(16000000 / 6);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -