2006年05月

作業日記トップへ

05月26日(金) 

2006年05月26日(金)

掲示板1へ

AX-12のLEDを点灯

OAKS-miniでAX-12のLEDを点灯してみました。

シリアルの部分は、宮田さんが公開してくれているプログラムをもとにしています。 というか、ほとんどそのまま・・・

sect30.inc
	.lword	dummy_int		; A-D(for user)(vector 14)
	.lword	dummy_int		; uart2 transmit(for user)(vector 15)
	.lword	dummy_int		; uart2 receive(for user)(vector 16)
	.lword	dummy_int		; uart0 transmit(for user)(vector 17)
	.glb	_int_rec_uart0		;
	.lword	_int_rec_uart0		; uart0 receive(for user)(vector 18)
	.lword	dummy_int		; uart1 transmit(for user)(vector 19)
	.glb	_int_rec_uart1		;
	.lword	_int_rec_uart1		; uart1 receive(for user)(vector 20)
	.lword	dummy_int		; timer A0(for user)(vector 21)
sci.h
#ifndef _SCI_H_
#define _SCI_H_

/**************************************************************************
*    ボーレート設定リスト : BaudRate
*    転送速度:b pbs
*     (設定値は20M/b/16-1)近い値をとるために四捨五入
**************************************************************************/
typedef enum {
  br9600  = 129,   /* 129.208 */
  br14400 =  86,   /*  85.806 */
  br19200 =  64,   /*  64.104 */
  br28800 =  42,   /*  42.403 */
  br31250 =  39,   /*  39     */
  br38400 =  32,   /*  31.552 */
  br57600 =  21,   /*  20.701 */
  br115200 = 10,   /*   9.851 */
  br1000000 = 0    /*   0.25  */
} BaudRate;

void UART0_ini(BaudRate b);
void int_rec_uart0(void);
int UART0_read(unsigned char *c);
int UART0_write(unsigned char c);

void UART1_ini(BaudRate b);
void int_rec_uart1(void);
int UART1_read(unsigned char *c);
int UART1_write(unsigned char c);

int SCI_putchar(unsigned char c, int port);
int printStr(unsigned char *str, int port);
int SCI_getchar(int port);
int UART0_getchar(void);

#endif
sci.c
/****************************************************/
/*      ファイル名:    sci.c                       */
/*      内容:          シリアル通信用関数          */
/*      日付:          2006.05.05                  */
/*      作成者:        ono                         */
/****************************************************/

/* インクルードファイル */
#include "sfr26.h"       /* OAKSmini用定義ファイル */
#include "sci.h"

#pragma INTERRUPT   int_rec_uart0
#pragma INTERRUPT   int_rec_uart1

#define SCI_RX_BUF_SIZE 16
#define SCI_RX_BUF_MASK (SCI_RX_BUF_SIZE-1)

struct tdSCI_RX{
  unsigned short stIdx;   /* データ開始位置 */
  unsigned short edIdx;   /* データ終了位置 */
  unsigned short dataNum; /* データ数 */
  unsigned char buf[SCI_RX_BUF_SIZE];  /* データ格納 */
};

volatile static struct tdSCI_RX SCI_RX0, SCI_RX1;

/**************************************************************************
*    uart0初期設定関数 : UART0_ini()
**************************************************************************/
void UART0_ini(BaudRate b)
{
  u0mr = 0x05;       /* 送受信モ−ドレジスタ 内部クロック */
                     /* 非同期、8ビット、パリティなし、*/
                     /* スリープなし */

  u0c0 = 0x10;       /* 送受信制御レジスタ0 クロックf1選択 */
  u0brg = b;         /* 転送速度レジスタ */

  s0ric = 0x06;      /* 割込みレベルの設定(レベル6) */
  u0c1 = 0x05;       /* 送受信制御レジスタ1 送受信許可 */
  ucon = 0x00;       /* 送受信制御レジスタ2 */
}

/**************************************************************************
*    受信割り込み : int_rec_uart0()
**************************************************************************/
void int_rec_uart0(void)
{
  unsigned char c;

  /* 受信バッファに空きがあれば受信 */
  if(ri_u0c1){
    c=u0rbl;
    if(SCI_RX0.dataNum != SCI_RX_BUF_SIZE){
      SCI_RX0.buf[SCI_RX0.edIdx]=c;
      SCI_RX0.edIdx=(SCI_RX0.edIdx+1) & SCI_RX_BUF_MASK;
      SCI_RX0.dataNum++;
    }
  }
}

/**************************************************************************
*    1バイト受信 : UART0_read()
**************************************************************************/
int UART0_read(unsigned char *c)
{
  /* 受信バッファにデータがあれば取り出す */
  if(SCI_RX0.dataNum != 0){
    *c=SCI_RX0.buf[SCI_RX0.stIdx];
    SCI_RX0.stIdx=(SCI_RX0.stIdx+1) & SCI_RX_BUF_MASK;
    SCI_RX0.dataNum--;
    return(1);
  }

  /* 受信バッファが空なら何もしないで終了 */
  *c=0;
  return(0);
}

/**************************************************************************
*    1バイト送信 : UART0_write()
**************************************************************************/
int UART0_write(unsigned char c)
{
  unsigned long i;
  unsigned short f;
  
  /* 送信レジスタが空くまでポーリングで待つ */
  f=0;
  for(i=0; i<0x200000; i++){
    if(ti_u0c1){
      f=1;
      break;
    }
  }

  if(f){
    u0tb=c;
    return(1);
  }
  return(0);
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

/**************************************************************************
*    uart1初期設定関数 : UART1_ini()
**************************************************************************/
void UART1_ini(BaudRate b)
{
  u1mr = 0x05;       /* 送受信モ−ドレジスタ 内部クロック */
                     /* 非同期、8ビット、パリティなし、*/
                     /* スリープなし */

  u1c0 = 0x10;       /* 送受信制御レジスタ0 クロックf1選択 */
  u1brg = b;         /* 転送速度レジスタ */

  s1ric = 0x06;      /* 割込みレベルの設定(レベル6) */
  u1c1 = 0x05;       /* 送受信制御レジスタ1 送受信許可 */
  ucon = 0x00;       /* 送受信制御レジスタ2 */
}

/**************************************************************************
*    受信割り込み : int_rec_uart1()
**************************************************************************/
void int_rec_uart1(void)
{
  unsigned char int_flag, c;

  int_flag=ri_u1c1;

  /* 受信バッファに空きがあれば受信 */
  if(int_flag){
    c=u1rbl;
    if(SCI_RX1.dataNum != SCI_RX_BUF_SIZE){
      SCI_RX1.buf[SCI_RX1.edIdx]=c;
      SCI_RX1.edIdx=(SCI_RX1.edIdx+1) & SCI_RX_BUF_MASK;
      SCI_RX1.dataNum++;
    }
  }
}

/**************************************************************************
*    1バイト受信 : UART1_read()
**************************************************************************/
int UART1_read(unsigned char *c)
{
  /* 受信バッファにデータがあれば取り出す */
  if(SCI_RX1.dataNum != 0){
    *c=SCI_RX1.buf[SCI_RX1.stIdx];
    SCI_RX1.stIdx=(SCI_RX1.stIdx+1) & SCI_RX_BUF_MASK;
    SCI_RX1.dataNum--;
    return(1);
  }

  /* 受信バッファが空なら何もしないで終了 */
  *c=0;
  return(0);
}

/**************************************************************************
*    1バイト送信 : UART1_write()
**************************************************************************/
int UART1_write(unsigned char c)
{
  unsigned long i;
  unsigned short f;
  
  /* 送信レジスタが空くまでポーリングで待つ */
  f=0;
  for(i=0; i<0x200000; i++){
    if(ti_u1c1){
      f=1;
      break;
    }
  }

  if(f){
    u1tb=c;
    return(1);
  }
  return(0);
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   汎用関数
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

/**************************************************************************
*    1文字送信 : SCI_putchar()
**************************************************************************/
int SCI_putchar(unsigned char c, int port)
{
  int (* myfunc)(unsigned char);

  if(port==0){
    myfunc = UART0_write;
  }else if(port==1){
    myfunc = UART1_write;
  }else{
    return(0);
  }

  /* 改行はCR+LFに変換して送信 */
  if(c=='\n'){
    if(!(*myfunc)(0x0D)){
      return(0);
    }
    if(!(*myfunc)(0x0A)){
      return(0);
    }
  }else{  /* それ以外はそのまま送信 */
    if(!(*myfunc)(c)){
      return(0);
    }
  }
  return(1);
}

/**************************************************************************
*    文字列送信 : printStr()
**************************************************************************/
int printStr(unsigned char *str, int port)
{
  unsigned char *s;

  /* 終端文字まで1文字ずつ表示 */
  for(s=str; *s!='\0'; s++){
    if(!SCI_putchar(*s, port)){
      return(0);
    }
  }
  return(s-str);
}

/**************************************************************************
*    1文字受信 : SCI_getchar()
**************************************************************************/
int SCI_getchar(int port)
{
  int (* myfunc)(unsigned char *);
  unsigned char c;

  if(port==0){
    myfunc = UART0_read;
  }else if(port==1){
    myfunc = UART1_read;
  }else{
    return(-1);
  }

  /* データを受信するまで待つ */
  while(!(*myfunc)(&c)){
    ;
  }

  /* 改行文字変換 */
  if(c==0x0D){
    c='\n';
  }
  return(c);
}

/**************************************************************************
*    1文字受信 : UART0_getchar()
**************************************************************************/
int UART0_getchar(void)
{
  unsigned char c;

  /* データを受信するまで待つ */
  while(!UART0_read(&c)){
    ;
  }

  /* 改行文字変換 */
  if(c==0x0D){
    c='\n';
  }
  return(c);
}
util.h
#ifndef _UTIL_H_
#define _UTIL_H_

void uint2Hex(unsigned char n, unsigned char upper, unsigned char *buf);
void uchar2Hex(unsigned char n, unsigned char upper, unsigned char *buf);

#endif
util.c
#include "sci.h"
#include "util.h"

/**********************************
  数値を16進数文字変換
 **********************************/
void uint2Hex(unsigned char n, unsigned char upper, unsigned char *buf)
{
  unsigned char c;
  unsigned char a = 'a';
  unsigned int len = 0;
  int i, half;

  /* 大文字/小文字の設定 */
  if (upper){
    a = 'A';
  }

  /* 16進文字列へ変換し文字数をカウント */
  do{
    i = n & 0x0F;
    if(i > 9){
      buf[len] = (unsigned char)(i + a - 10);
    }else{
      buf[len] = (unsigned char)(i + '0');
    }
    len++;
    n >>= 4;
  }while(n != 0);

  /* 文字の並び順を直す */
  half = len >> 1;
  for(i=0; i < half; i++){
    c = buf[i];
    buf[i] = buf[(len-1)-i];
    buf[(len-1)-i] = c;
  }

  /* 終端文字列の挿入 */
  buf[len]='\0';
}


/**********************************
  unsigned charを16進数文字変換
 **********************************/
unsigned char uc2Hex(int i, unsigned char a)
{
  if(i > 9){
    return((unsigned char)(i + a - 10));
  }else{
    return((unsigned char)(i + '0'));
  }
}

void uchar2Hex(unsigned char n, unsigned char upper, unsigned char *buf)
{
  unsigned char a = 'a';
  int i;

  /* 大文字/小文字の設定 */
  if (upper){
    a = 'A';
  }

  i = n & 0xF0;
  i>>=4;
  buf[0]=uc2Hex(i, a);

  i = n & 0x0F;
  buf[1]=uc2Hex(i, a);

  /* 終端文字列の挿入 */
  buf[2]='\0';
}

main.c
/****************************************************/
/*  プロジェクト名: sci03                           */
/*  ファイル名:    main.c                          */
/*  内容:      AX-12との通信                       */
/*  日付:      2006.05.26                          */
/*  コンパイラ: NC30WA (Ver.4.00)                   */
/*  作成者:    ono                                 */
/****************************************************/

/* インクルードファイル */
#include "sfr26.h"   /* OAKSmini用定義ファイル */
#include "sci.h"
#include "util.h"

/************************************************************
    UART1へ16進数を2桁で送信 : void SCI_putHex(int tmp)
*************************************************************/

void SCI_putHex(int tmp)
{
  unsigned char get_16[8];

  uchar2Hex((tmp & 0xFF), 1, get_16);
  printStr(get_16, 1);
  SCI_putchar(',', 1);
}

/***********************************************************
    AX-12からのSTATUS PACKETの処理 : void get_ax12(void)
************************************************************/
void get_ax12(void)
{
  int get_tmp, i, len;

  _asm( "\tFSET   I");  /* 割り込み許可  */
  u0c1 = 0x04;          /* 受信のみ許可 */
  while((get_tmp=SCI_getchar(0))!=0xFF){
    ;
  }
  SCI_putHex(get_tmp);
  for(i=1; i<=3; i++){
    get_tmp=(SCI_getchar(0));
    len=get_tmp;
    SCI_putHex(get_tmp);
  }
  for(i=0; i<len; i++){
    get_tmp=(SCI_getchar(0));
    SCI_putHex(get_tmp);
  }
}

/**********************************************************
    メイン関数 : main()
***********************************************************/
int main(void)
{
/* Broadcasting ID */
//  char send[9]={0xFF,0xFF,0xFE,0x04,0x03,0x19,0x01,0xE0,0x00};

/* ID 1 */
  char send[9]={0xFF,0xFF,0x01,0x04,0x03,0x19,0x01,0xDD,0x00};
  
  UART0_ini(br57600);
  UART1_ini(br38400);

  u0c1 = 0x01; /* 送信のみ許可 */

  printStr(send, 0);
  while(!ti_u0c1);

  get_ax12();  /* AX-12からのSTATUS PACKET */

  SCI_putchar('*', 1);

  return(0);
}

実行結果

FFデータの先頭
FF
01ID
02データの長さ
00エラー
FCチェックサム

作業日記トップページへ

トップページへ

SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送