?? 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 + -