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

📄 digio.c

📁 AVR平台下的CanOpen协议桟源码包括应用
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ------------------------------------------------------------------------
File   : digio.c

Descr  : Functions for Digital-input and -output handling.

History: 21JUL.00; Henk B&B; Definition; for the time being a single 8-bit
                             in- and two 8-bit output ports are defined.
	 21AUG.00; Henk B&B; Add a polling counter for the change-of-state
	                     of inputs in order to implement 'debouncing'.
         30NOV.00; Henk B&B; Added interrupt enable: DigInIntrptEna.
	 19MAR.01; Henk B&B; Added storage of digital output setting(s)
	                     for restore after reset/power-up.
	 18JUL.01; Henk B&B; Changed output-at-reset policy:
	                     keep settings at soft-reset (= NMT-Reset).
	 23JUL.01; Henk B&B; Share 2nd Port between in- and outputs
	                     (configurable);
			     add interrupt masks for both 8-bit input ports.
	 04FEB.02; Henk B&B; Digital Outputs set to high, by default.
	 16JAN.03; Henk B&B; Ported to ATmega128.
--------------------------------------------------------------------------- */

#include "general.h"
#include "can.h"
#include "digio.h"
#include "eeprom.h"
#include "store.h"

/* After a hard reset Digital Outputs are initialized to either low or high;
   after a soft reset (= NMT Reset-Node) existing settings are kept */

/* ------------------------------------------------------------------------ */
/* Globals */

static BYTE DigInDebouncePolls; /* (stored in EEPROM) */
static BOOL DigInIntrptEna;     /* (stored in EEPROM) */
static BOOL DigOutInitHi;       /* (stored in EEPROM) */

static BYTE DigOutMask2;        /* (stored in EEPROM) */
static BYTE DigInMask2;

static BYTE DigInIntrptMask1;   /* (stored in EEPROM) */
static BYTE DigInIntrptMask2;   /* (stored in EEPROM) */

static BYTE DigInStateOld1;
static BYTE DigInStateOld2;
static BYTE DigInStatePolls;

/* ------------------------------------------------------------------------ */
/* Local prototypes */

static void digio_load_config( void );

/* ------------------------------------------------------------------------ */

void digio_init( BOOL hard_reset )
{
  /* Initialise Digital-I/O configuration parameters */
  digio_load_config();

  DigInStatePolls = 0;

  /* Digital input port 1
     ATmega103: PORTF cannot be initialized (no pull-ups present) */
#ifndef __ELMB103__
  DIGIN1_PORT = 0xFF; /* Use pull-ups */
  DIGIN1_DDR  = 0x00;
#endif /* __ELMB103__ */
  DigInStateOld1 = DIGIN1_PIN & DigInIntrptMask1;

  /* Digital input port 2:  is shared between inputs and outputs !
     set DDRA/PORTA: use pull-ups (=1) */
  DigInMask2   = ~DigOutMask2;
  DIGIN2_PORT |= DigInMask2;
  DIGIN2_DDR   = ~DigInMask2;
  DigInStateOld2 = (DIGIN2_PIN & DigInMask2) & DigInIntrptMask2;

  /* Digital output port 1: set PORTC (output only on ATmega103);
     keep old setting at soft-reset (NMT Reset-Node) */
#ifndef __ELMB103__
  DIGOUT1_DDR = 0xFF;
#endif /* __ELMB103__ */
  if( (hard_reset & TRUE) == TRUE )
    {
      /* Initialize to required setting */
      if( DigOutInitHi )
	DIGOUT1_PORT = 0xFF;
      else
	DIGOUT1_PORT = 0x00;
    }

  /* Digital output port 2: set DDRA/PORTA;
     keep old setting at soft-reset (NMT Reset-Node) */
  DIGOUT2_DDR = DigOutMask2;
  if( (hard_reset & TRUE) == TRUE )
    {
      /* Initialize to required setting */
      if( DigOutInitHi )
	DIGOUT2_PORT |= DigOutMask2;
      else
	DIGOUT2_PORT &= (~DigOutMask2);
    }
}

/* ------------------------------------------------------------------------ */

BYTE digin_port_cnt( void )
{
  return DIGIO_INPORT_CNT;
}

/* ------------------------------------------------------------------------ */

BYTE digin_get_port( BYTE port_no )
{
  if( port_no == 1 )
    {
#ifndef __ELMB103__
      /* Refresh the DDR and pull-up setting */
      DIGIN1_DDR  = 0x00;
      DIGIN1_PORT = 0xFF; /* Use pull-ups */
#endif /* __ELMB103__ */
      return DIGIN1_PIN;
    }
  if( port_no == 2 )
    {
#ifdef __VARS_IN_EEPROM__
      DigInMask2  = ~eeprom_read( EE_DIGOUTMASK2 );
#endif /* __VARS_IN_EEPROM__ */

      /* Refresh the DDR and pull-up setting */
      DIGIN2_DDR  &= (~DigInMask2);
      DIGIN2_PORT |= DigInMask2;

      return (DIGIN2_PIN & DigInMask2);
    }
  return 0x00;
}

/* ------------------------------------------------------------------------ */

void digin_pdo( void )
{
  BYTE pdo_data[DIGIO_INPORT_CNT];

  /* Read the digital-inputs and put in the message */
  pdo_data[0] = digin_get_port( 1 );
  pdo_data[1] = digin_get_port( 2 );

  /* Send as a Transmit-PDO1 CAN-message */
  can_write( C91_TPDO1, DIGIO_INPORT_CNT, pdo_data );
}

/* ------------------------------------------------------------------------ */

void digin_pdo_on_cos( void )
{
  /* Send a PDO on change-of-state of the digital inputs;
     a simple debounce-mechanism is implemented */

  BYTE current_state1, current_state2;

#ifdef __VARS_IN_EEPROM__
  DigInIntrptEna = eeprom_read( EE_DIGININTRPTENA );
#endif /* __VARS_IN_EEPROM__ */

  if( !DigInIntrptEna ) return;

#ifdef __VARS_IN_EEPROM__
  DigInIntrptMask1 = eeprom_read( EE_DIGININTRPTMASK1 );
  DigInIntrptMask2 = eeprom_read( EE_DIGININTRPTMASK2 );
  DigInMask2       = ~eeprom_read( EE_DIGOUTMASK2 );
#endif /* __VARS_IN_EEPROM__ */

  /* Read current state of (interrupt-enabled) digital inputs */
  current_state1 = DIGIN1_PIN & DigInIntrptMask1;
  current_state2 = (DIGIN2_PIN & DigInMask2) & DigInIntrptMask2;

  if( current_state1 != DigInStateOld1 || current_state2 != DigInStateOld2 )
    {
#ifdef __VARS_IN_EEPROM__
      DigInDebouncePolls = eeprom_read( EE_DIGINDEBOUNCEPOLLS );
#endif /* __VARS_IN_EEPROM__ */

      /* Assuming that a 'bouncing' switch causes the input to go
	 from a new state to the old state and back, we just wait
	 until we have seen a new state a number of times in a row */
      ++DigInStatePolls;
      if( DigInStatePolls > DigInDebouncePolls )
	{
	  /* Assume changed state of digital inputs now stable: send the PDO;
	     if this is not possible don't 'discard' this change:
	     we'll miss it if this is the last change that occurs */

	  if( can_transmitting(C91_TPDO1) ) return;

	  digin_pdo();

	  /* Remember the current state */
	  DigInStateOld1 = current_state1;
	  DigInStateOld2 = current_state2;
	}
    }
  else
    {
      DigInStatePolls = 0;
    }
}

/* ------------------------------------------------------------------------ */

BYTE digout_port_cnt( void )
{
  return DIGIO_OUTPORT_CNT;
}

/* ------------------------------------------------------------------------ */

void digout_set_port( BYTE port_no, BYTE digout_data )
{
  /* Set digital outputs according to databyte */
  if( port_no == 1 )
    {
#ifndef __ELMB103__
      /* Refresh the DDR */
      DIGOUT1_DDR = 0xFF;
#endif /* __ELMB103__ */
      DIGOUT1_PORT = digout_data;
    }
  if( port_no == 2 )
    {
      BYTE out_curr;

#ifdef __VARS_IN_EEPROM__
      DigOutMask2 = eeprom_read( EE_DIGOUTMASK2 );
#endif /* __VARS_IN_EEPROM__ */

      /* Refresh the (output-part of the) DDR */
      DIGOUT2_DDR |= DigOutMask2;

      /* Get setting of non-output pins (pull-ups) */
      out_curr = DIGOUT2_PORT & (~DigOutMask2);

      /* Combine this setting with the new output setting */
      DIGOUT2_PORT = out_curr | (digout_data & DigOutMask2);
    }
}

/* ------------------------------------------------------------------------ */

BYTE digout_get_port( BYTE port_no )
{
  BYTE portdata = 0x00;
  if( port_no == 1 )
    {
#ifndef __ELMB103__
      /* Refresh the DDR */
      DIGOUT1_DDR = 0xFF;
#endif /* __ELMB103__ */
      portdata = DIGOUT1_PORT;
    }
  if( port_no == 2 )
    {
#ifdef __VARS_IN_EEPROM__
      DigOutMask2 = eeprom_read( EE_DIGOUTMASK2 );
#endif /* __VARS_IN_EEPROM__ */

⌨️ 快捷键说明

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