📄 can_fifo.c
字号:
//*****************************************************************************
//
// can_fifo.c - CAN设备在CAN的FIFO模式下进行数据收发
// 本例程将若干报文对象配置为发送FIFO,在EK-LM3S8962板上演示
// 在启动该程序前复位2110板
//
// 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 "gpio.h"
#include "interrupt.h"
#include "sysctl.h"
#include "systick.h"
//#include "drivers/rit128x96x4.h"
// 为CAN控制器配置的FIFO的大小
#define CAN_FIFO_SIZE (8 * 8)
// 发送字节数
unsigned long ulBytesTransmitted;
tCANMsgObject MsgObjectTx;
//定义缓冲区
unsigned char pucBufferTx[CAN_FIFO_SIZE];
//*****************************************************************************
//
// CAN控制器的中断处理
//
//*****************************************************************************
void
CANIntHandler(void)
{
unsigned long ulStatus;
//读取你中断原因
ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
if(ulStatus <= 8)
{
//字节发送数自加 8
ulBytesTransmitted += 8;
}
else
{
//清除状态中断
CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
}
//
// Acknowledge the CAN controller interrupt has been handled.
//
CANIntClear(CAN0_BASE, ulStatus); //清除中断
}
//*****************************************************************************
//
// 该函数配置了发送FIFO并将数据拷贝到FIFO中
//
//*****************************************************************************
int
CANTransmitFIFO(unsigned char *pucData, unsigned long ulSize)
{
int iIdx;
//配置发送报文对象
MsgObjectTx.ulMsgID = 8;
MsgObjectTx.ulMsgIDMask = 0;
MsgObjectTx.ulFlags = MSG_OBJ_TX_INT_ENABLE;
// 将8个报文对象构成一个发送FIFO
for(iIdx = 0; iIdx < 8; iIdx++)
{
//如果还有多于8字节的数据待发送,则用满报文形式发送8字节
if(ulSize > 8)
{
MsgObjectTx.ulMsgLen = 8;
MsgObjectTx.pucMsgData = &pucData[iIdx * 8];
// 设置标志 MSG_OBJ_FIFO 来表明这个报文对象为FIFO结构中的一部分,且不是FIFO的最后一个报文对象
MsgObjectTx.ulFlags |= MSG_OBJ_FIFO;
//将待发送字节数变量减8
ulSize -= 8;
//启动报文对象发送
CANMessageSet(CAN0_BASE, iIdx + 1, &MsgObjectTx, MSG_OBJ_TYPE_TX);
}
// 如果还是有少于8字节待发送数据,则发送剩余数据,
// 且清除标志 MSG_OBJ_FIFO 以表明这是最后一个在FIFO中的报文对象
else
{
MsgObjectTx.ulMsgLen = ulSize;
MsgObjectTx.pucMsgData = &pucData[iIdx * 8];
CANMessageSet(CAN0_BASE, iIdx + 1, &MsgObjectTx, MSG_OBJ_TYPE_TX);
}
}
return(0);
}
//*****************************************************************************
//
// 主程序
//
//*****************************************************************************
int
main(void)
{
int iIdx;
//
// 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_0);
//关闭LED
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 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();
//初始化数据缓冲区
for(iIdx = 0; iIdx < CAN_FIFO_SIZE; iIdx++)
{
pucBufferTx[iIdx] = iIdx + 0x1;
}
//为已发送字节数变量赋初值
ulBytesTransmitted = 0;
//配置发送FIFO,并启动发送
CANTransmitFIFO(pucBufferTx, CAN_FIFO_SIZE);
//
// Loop forever.
//
while(1)
{
//等待所有的数据发送完毕
if(ulBytesTransmitted == CAN_FIFO_SIZE)
{
//复位该变量
ulBytesTransmitted = 0;
//LED指示
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 1); // 这里需要注意的是:在启动报文发送前,
// 接收FIFO已经将前次数据接收完毕,因此
SysCtlDelay(16000000 / 3); // 这里的延时时间必须大于接收FIFO的(16000000/6)
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 0);
SysCtlDelay(16000000 / 3);
//更改缓冲区中的数据
for(iIdx = 0; iIdx < CAN_FIFO_SIZE; iIdx++)
{
pucBufferTx[iIdx] += 0xB;
}
//配置发送FIFO,并启动发送
CANTransmitFIFO(pucBufferTx, CAN_FIFO_SIZE);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -