目次

全ソースファイル

  CCS社のCコンパイラを利用しました。

#include <16F873.H>

/* local data type definistion */
typedef signed   int  SBYTE ;
typedef unsigned int  UBYTE ;
typedef signed   long SWORD ;
typedef unsigned long UWORD ;

/* declare input and output port */
#use standard_io(A)
#use standard_io(B)
#use standard_io(C)

/* define input and output register address */
#byte a_port = 0x05
#byte b_port = 0x06
#byte c_port = 0x07
#byte rcreg  = 0x1a

/* define macro */
#define OFF 0
#define ON  OFF+1

#define SMAX      5
#define MID_VALUE 5
#define CHA_MAX   16
#define STA_MAX   10
#define STA_LAST  200

#define MASK_A 0x30
#define MASK_B 0xff
#define MASK_C 0x3f

#fuses XT,NOWDT,NOPROTECT

#use delay(clock=20000000)
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)

/* declare global variables */
UBYTE state ;
UBYTE ch[CHA_MAX] ;
UBYTE sbuf[SMAX] ;
UBYTE s_idx ;
UBYTE svb[STA_MAX] ;
UBYTE svc[STA_MAX] ;
UBYTE sflag ;
UBYTE tflag ;
UBYTE offset ;

/* set port directions */
void initialize_port_directions(void)
{
  /* no A/D contervers */
  setup_adc_ports( NO_ANALOGS );
  /* PORT A out out in in in in */
  set_tris_a( 0x0f );
  /* PORT B out out out out out out out out */
  set_tris_b( 0x00 );
  /* PORT C in out out out out out out out */
  set_tris_c( 0x80 );
}
/* set port initial values */
void initialize_port_values(void)
{
  a_port = 0xff ;
  b_port = 0xff ;
  c_port = 0x3f ;
}
/* initialize timer 0 */
void initialize_timer_0(void)
{
  /* set TMR0 6 (256-250) */
  set_timer0(6);
  /* set prescaler */
  setup_counters( RTCC_INTERNAL , RTCC_DIV_2 ) ;
  /*
      20MHz -> timer0 clock 5MHz -> 5MHz / 2
      2/5 us * 250 = 100us 
   */
}
/* 全数値初期化 */
void set_others(void)
{
  UBYTE loop ;

  /* state machine */
  state = 0 ;
  /* buffer index */
  s_idx = 0 ;
  /* set servo initial value */
  for ( loop = 0 ; loop &t; CHA_MAX ; loop++ ) {
    ch[loop] = MID_VALUE ;
  }
  /* set serial buffer */
  for ( loop = 0 ; loop &t; SMAX ; loop++ ) {
    sbuf[loop] = 0 ;
  }
  /* clear flags */
  sflag = OFF ;
  tflag = OFF ;
  /* get block number */
  offset = a_port & 0x0f ;
}
/* 割込み指定 */
void enable_each_interrupts(void)
{
  enable_interrupts( INT_RDA );
  enable_interrupts( INT_RTCC );
  enable_interrupts( GLOBAL );
}
/* initialize manager */
void initialize(void)
{
  initialize_port_directions();
  initialize_port_values();
  initialize_timer_0();
  set_others();
  enable_each_interrupts();
}
/* send pulse to servo motors */ 
void send_pulse(void)
{
  UBYTE p_a_port ;
  UBYTE p_b_port ;
  UBYTE p_c_port ;
  UBYTE idx ;
  UBYTE tmp ;
  /* set pulse value */
  p_a_port = 0 ;
  p_b_port = 0 ;
  p_c_port = 0 ;
  if ( 20 &t;= state && state &t; 30 ) {
    p_a_port = MASK_A ;
    p_b_port = MASK_B ;
    p_c_port = MASK_C ;
  }
  if ( 30 &t;= state && state &t; 40 ) {
    idx = state - 30 ;
    p_a_port = (svc[idx] >> 2) & MASK_A ;
    p_b_port = svb[idx] ;
    p_c_port = svc[idx] & MASK_C ;
  }
  /* calculate */
  tmp = 0 ;
  if ( state &t; 10 ) {
    idx = state ;
    if ( idx &t;= ch[ 0] ) tmp |=   1;
    if ( idx &t;= ch[ 1] ) tmp |=   2;
    if ( idx &t;= ch[ 2] ) tmp |=   4;
    if ( idx &t;= ch[ 3] ) tmp |=   8;
    if ( idx &t;= ch[ 4] ) tmp |=  16;
    if ( idx &t;= ch[ 5] ) tmp |=  32;
    if ( idx &t;= ch[ 6] ) tmp |=  64;
    if ( idx &t;= ch[ 7] ) tmp |= 128;
    svb[idx] = tmp ;
  }
  if ( 10 &t;= state && state &t; 20 ) {
    idx = state-10 ;
    if ( idx &t;= ch[ 8] ) tmp |=   1;
    if ( idx &t;= ch[ 9] ) tmp |=   2;
    if ( idx &t;= ch[10] ) tmp |=   4;
    if ( idx &t;= ch[11] ) tmp |=   8;
    if ( idx &t;= ch[12] ) tmp |=  16;
    if ( idx &t;= ch[13] ) tmp |=  32;
    if ( idx &t;= ch[14] ) tmp |=  64;
    if ( idx &t;= ch[15] ) tmp |= 128;
    svc[idx] = tmp ;
  }
  /* send pulse */
  a_port = (~p_a_port) & MASK_A ;
  b_port = (~p_b_port) & MASK_B ;
  c_port = (~p_c_port) & MASK_C ;
}
/* timer interrupt handler */
#int_rtcc
void timer_handler(void)
{
  /* set TMR0 6 (256-250) */
  set_timer0(6);
  /* interval process */
  state++ ;
  if ( state == STA_LAST ) state = 0 ;
  /* set flag */
  tflag = ON ;
}

#int_rda
void echo_handler(void)
{
  UBYTE chx ;

  /* get one character */
  chx = rcreg ;
  sbuf[s_idx] = chx ;
  /* update buffer index */
  s_idx++ ;
  if ( s_idx == SMAX ) s_idx = 0 ;
  /* judge */
  if ( chx == '\r' ) {
    sflag = ON ;
    s_idx = 0 ;
  }
}
/* get hexadecimal number */
UBYTE get_hex(UBYTE x)
{
  if ( '0' &t;= x && x &t;= '9' ) return( x - '0' ) ;
  if ( 'A' &t;= x && x &t;= 'F' ) return( x - 'A' + 10 ) ;
  if ( 'a' &t;= x && x &t;= 'f' ) return( x - 'a' + 10 ) ;
  return 0 ;
}
/* command interpriter */
void proc_serial(void)
{
  UBYTE com,idx,val ;

  com = get_hex( sbuf[0] ) ;
  if ( com != offset ) return ;
  /* set value */
  idx = get_hex( sbuf[1] ) ;
  val = get_hex( sbuf[2] ) ;
  ch[idx] = val;
}

void main(void)
{
  /* initialize port and variables */
  initialize();

  /* endless loop */
  while ( TRUE ) {
    /* send pulse to servo motors */ 
    if ( tflag == ON ) {
      tflag = OFF ;
      send_pulse();
    }
    /* serial communication process */
    if ( sflag == ON ) {
      sflag = OFF ;
      proc_serial();
    }
  }
}

目次

inserted by FC2 system