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

📄 app.c

📁 This library is Copyright (c) Raphael Zulliger <zulli@gmx.net>. It is licensed under the GNU L
💻 C
字号:
/***************************************************************************
                         app.c  -  description
                             -------------------
    begin                : Fri May 17 2002
    copyright            : (C) 2002 by Raphael Zulliger
    email                : zulli@hsr.ch
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This library is Copyright (c) Raphael Zulliger <zulli@gmx.net>.       *
 *   It is licensed under the GNU Library General Public License (LGPL).   *
 *                                                                         *
 ***************************************************************************/


// CANopen related
#include <app.h>
#include <def.h>
#include <init.h>
#include <objacces.h>
#include <lifegrd.h>
#include <pdo.h>
#include <nmt.h>
#include <general.h>
#include <timer.h>

// PIC18c658 related
#include <p18c658.h>
#include <delays.h>


//----------------------------------------------------------------------------
// global vars...

BYTE bSend;
BYTE bRecv;

BYTE* pbSend;
BYTE* pbRecv;


void initialisation( void )
{
	// variable declaration --------------------------------------------------
	BYTE B;
	DWORD DW;
	WORD W;

	pbSend = &bSend;
	pbRecv = &bRecv;
	

	// setting digital outputs (values that are receivced by this device)
    setVariable( (WORD)0x6200, (BYTE)1, (void XHUGE* XDATA*)&pbRecv );
    B = (BYTE)1;
    setODEntry( (WORD)0x6200, (BYTE)0, (void XHUGE*)&B, (DWORD)1 );

    
	// setting digital inputs (values that are sent by this device)
    setVariable( (WORD)0x6000, (BYTE)1, (void XHUGE* XDATA*)&pbSend );
    B = (BYTE)1;
    setODEntry( (WORD)0x6000, (BYTE)0, (void XHUGE*)&B, (DWORD)1 );


	// setting up the communication parameter for the rx/tx pdos...
    W = (WORD)0x200 + (WORD)bDeviceNodeId;
    setODEntry( (WORD)0x1400, (BYTE)1, (void XHUGE*)&W, (DWORD)2 );
    B = (BYTE)0xFF;
    setODEntry( (WORD)0x1400, (BYTE)2, (void XHUGE*)&B, (DWORD)1 );
	// therefore, we must set count of entries to 2
    B = (BYTE)2;
    setODEntry( (WORD)0x1400, (BYTE)0, (void XHUGE*)&B, (DWORD)1 );


    W = (WORD)0x180 + (WORD)bDeviceNodeId;
    setODEntry( (WORD)0x1800, (BYTE)1, (void XHUGE*)&W, (DWORD)2 );
    B = (BYTE)0xFF;
    setODEntry( (WORD)0x1800, (BYTE)2, (void XHUGE*)&B, (DWORD)1 );
	// therefore, we must set count of entries to 2
    B = (BYTE)2;
    setODEntry( (WORD)0x1800, (BYTE)0, (void XHUGE*)&B, (DWORD)1 );


	// Die PDO-Mapping Eintraege erfolgen hier: Bitte lesen Sie im CANopen 
	// Standard nach, was die Werte zu bedeuten haben
    DW = (DWORD)0x62000108;
    setODEntry( (WORD)0x1600, (BYTE)1, (void XHUGE*)&DW, (DWORD)4 );
	// Anzahl gueltiger Eintraege festlegen
    B=(BYTE)1;
    setODEntry( (WORD)0x1600, (BYTE)0, (void XHUGE*)&B, (DWORD)1 );

	
	// Die PDO-Mapping Eintraege erfolgen hier: Bitte lesen Sie im CANopen 
	// Standard nach, was die Werte zu bedeuten haben
    DW = (DWORD)0x60000108;
    setODEntry( (WORD)0x1A00, (BYTE)1, (void XHUGE*)&DW, (DWORD)4 );
	// Anzahl gueltiger Eintraege festlegen
    B=(BYTE)1;
    setODEntry( (WORD)0x1A00, (BYTE)0, (void XHUGE*)&B, (DWORD)1 );

    
	// Heartbeat konfiguration erfolgt hier
	DW = (DWORD)0x000007D0;	// 07D0 -> check about every 2 Seconds if the server (id 0) has sent its heartbeat.
	//            -- 		: reserved
	//              -- 		: node-id
	//                ----  : heartbeat-time in [ms]
	setODEntry( (WORD)0x1016, (BYTE)1, (void XHUGE*)&DW, (DWORD)4 );

	// count of valid heartbeat consumers
	B = (BYTE)1;
	setODEntry( (WORD)0x1016, (BYTE)0, (void XHUGE*)&B, (DWORD)1 );
	
	// the time within  this device has to send a heartbeat message
	W = (WORD)0x0100; 		// Heartbeat every 256 ms 
	setODEntry( (WORD)0x1017, (BYTE)0, (void XHUGE*)&W, (DWORD)2 );


	//************************************************************************
    // place user defined code here:
	//************************************************************************

	// init I/O-Ports, interrupts, ...
	Setup();	
}



void preOperational( void )
{
	while( bStateMachineState == PRE_OPERATIONAL )
	{
		// because sending of heartbeat must start just after bootup, lets do that...
		ClrWdt( );						// zuruecksetzen des Watchdog-Timers
		processLifeGuard( );
        proccessRxCanMessages( );
	}
}


void operational( void )
{
	while( bStateMachineState == OPERATIONAL )
	{
		ClrWdt( );						// zuruecksetzen des Watchdog-Timers
        proccessRxCanMessages( );
        processLifeGuard( );

        // increase value to send
        bSend++;
        processSendPDO( );
	}
}


void stopped( void )
{
	while( bStateMachineState == STOPPED )
	{
		ClrWdt( );						// zuruecksetzen des Watchdog-Timers
		// sending of heartbeat has to be performed in STOPPED state too.
		processLifeGuard( );
        proccessRxCanMessages( );
	}
}










/***************************************************************************
 ***************************************************************************
 * USER DEFINED FUNCTIONS                                                  *
 ***************************************************************************
 ***************************************************************************/


//----------------------------------------------------------------------------
//    Setup() Inizialisiert unter anderem alle Register des Mikroprozessors
//----------------------------------------------------------------------------
void Setup(void)
{
	TRISA = 0xf0;							// PORTA RA0 to RA3 are outputs
	TRISB = 0xfe;							// PORTB inputs except RB0

	SILENT_MODE = 0;						// Setze den CAN-Transceiver auf High-Speed Mode

	INTCON2bits.RBPU = 0;					// Pull Up's on PORTB are enabled

	INTCON3 = 0;							// External interrupts disable
	RCONbits.IPEN = 1;						// Enable priority levels on interrupts
	INTCONbits.GIEL = 0;					// Disables all peripheral interrupts
	INTCONbits.GIEH = 1;					// Enable all high priority interrupts
}




//----------------------------------------------------------------------------
// Interrupt Code
//----------------------------------------------------------------------------
// High priority interrupt vector
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh(void)
{
	_asm 
		goto	InterruptHandlerHigh		//jump to interrupt routine
	_endasm
}


//----------------------------------------------------------------------------
// High priority interrupt routine

#pragma code
#pragma interrupt InterruptHandlerHigh save=section(".tmpdata"), PROD, TBLPTR, TABLAT
void InterruptHandlerHigh(void)
{
	BYTE isr_i;

/************************************************************************************
 * CANopen SlaveLib related!                                                        *
 ***********************************************************************************/
	// heartbeat related. provided by CANopen SlaveLib
	if( PIR1bits.TMR1IF == (BYTE)0x01 )
	{
		resetTimer( );
		// immediately restart the timer to avoid big faults...
		// set the timer to 64536(decimal)=0xfc18, so it dures 1ms until the next
		// overflow occurs...
		// formula: time of interrupt occurence: t = (Fosc/4)(0xFFFF-x) where x is the
		// value in TMR1H/TMR1L

		// update all heartbeat-realted things...
		for( isr_i=(BYTE)0x00; isr_i<(BYTE)COUNT_OF_HEARTBEAT_CONSUMER; isr_i++ )
		{
			// this increaes the time var. +1 means +1ms
			if( heartBeatTable[isr_i].should_time > (WORD)0x0000 )
				heartBeatTable[isr_i].time++;
		}
		// increase time of "our" heartbeat...
		if( ourHeartBeatValues.ourShouldTime > (WORD)0x0000 )
			ourHeartBeatValues.ourTime++;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -