⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can_2110_fifo.c

📁 CAN_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 + -