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

📄 can_fifo.c

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