📄 app.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 + -