目次

STM8SDiscovary

 mugen2010では、STMicoElectoronicsの
 STM8SDiscovaryを使うことを考えていました。

 このマイコン基板は安価かつソフトウエアと
 ハードウエアのデバッガがUSBで使えるのが
 魅力です。

 大阪に移動するとき、荷物は極力減らしたいので
 USBでファームウエアをダウンロードできるのは
 ケーブルの用意だけで都合がよかったのです。



 開発環境のダウンロードとインストールが面倒
 なので、放置状態でした。2012年の大型連休を
 利用して、環境を整備しました。
 移動メカテストの環境として使えるかを調べたい
 ので、重い腰を上げて作業にかかります。



 ダウンロードに3時間、インストールに40分
 ライブラリの環境整備に20分ほどかかって
 環境が完成しました。

 ボード上のLEDを点滅させるファームウエアを
 入れた後、通信やモータ制御のためのI/Oボード
 を半田付けです。



 通信には、RS232Cを利用しますが、MAX232Cの
 手持ちがなかったので、74HC04を使った簡易
 インタフェースを入れました。



 このインタフェースボードの回路図は以下です。



 動作テストに、2つのLEDを接続して、点滅周期を
 2秒、3秒にしてみました。単純な処理ですが
 タイマー割込みとRTOS(Real Time Operating System)を
 使ってみます。RTOSには、USO2を使います。

  Raisonance CとSTMicroのライブラリを利用して
 作成したファームウエアのソースコードは、以下。

#include "stm8s.h"

#define OFF 0
#define ON  OFF+1

#define NO  0
#define YES NO+1

#define CLKF 16000000
#define ARR4 256

/* define data type */
typedef unsigned char  UBYTE ;
typedef   signed char  SBYTE ;
typedef unsigned short UWORD ;
typedef   signed short SWORD ;
typedef unsigned long  ULONG ;

typedef struct {
  void  (*tsk)(void);
  UWORD wcount ;
} TCBP ;

#define TSK_ID_MAX 4

#define TSK_ID0 0
#define TSK_ID1 1
#define TSK_ID2 2
#define TSK_ID3 3

TCBP tcb[TSK_ID_MAX];

#define TTS_SUSPEND 0
#define TTS_WAIT    TTS_SUSPEND+1
#define TTS_READY   TTS_SUSPEND+2

UWORD ready  ;
UWORD suspend;
UWORD waitq ;
UBYTE run_tsk;

UBYTE os_cnt ;

#define TSK0_INTERVAL 5
#define TSK1_INTERVAL 200
#define TSK2_INTERVAL 300
#define TSK3_INTERVAL 100

/*------------------*/
/* system call body */
/*------------------*/
void init_os(void)
{
  ready   = 0 ;
  suspend = 0 ;
  waitq   = 0 ;
}

void cre_tsk(UBYTE tid,void (*tsk)(void))
{
  tcb[tid].tsk    = tsk;
  tcb[tid].wcount = 0;
}

void sta_tsk(UBYTE tid,UBYTE sta)
{
  UWORD tmp ;
  tmp = (1 << tid);
  if ( sta == TTS_READY   ) { ready   |= tmp; }
  if ( sta == TTS_SUSPEND ) { suspend |= tmp; }
  if ( sta == TTS_WAIT    ) { waitq   |= tmp; }
}

void rsm_tsk(UBYTE tid)
{
  UWORD tmp ;
  tmp = (1 << tid);
  ready   |=  tmp;
  suspend &= ~tmp;
  waitq   &= ~tmp;
}

void sus_tsk(UBYTE tid)
{
  UWORD tmp ;
  tmp = (1 << tid);
  ready   &= ~tmp;
  suspend |=  tmp;
  waitq   &= ~tmp;
}

void slp_tsk(void)
{
  sus_tsk(run_tsk);
}

void wai_tsk(UWORD x)
{
  UWORD tmp ;
  tmp = (1 << run_tsk);
  ready   &= ~tmp;
  suspend &= ~tmp;
  waitq   |=  tmp;
  tcb[run_tsk].wcount = x ;
}

UBYTE is_tsk_ready(UBYTE tid)
{
  return( (ready >> tid) & 1 ) ;
}

void timer_handler(void)
{
  UWORD xtmp ;
  UBYTE loop ;
  xtmp = waitq ;
  for ( loop = 0 ; loop < TSK_ID_MAX ; loop++ ) {
    if ( xtmp & 1 ) {
      tcb[loop].wcount-- ;
      if ( tcb[loop].wcount == 0 ) { rsm_tsk(loop); }
    }
    xtmp >>= 1 ;
  }
}

#define IDLE_STATE 0
#define RUN_STATE  1

UBYTE istate ;
UBYTE itrg   ;

/*------------------------*/
/* task function protoype */
/*------------------------*/
void tsk0_proc(void)
{
  UBYTE tmp ;
  /* get switch state and inverse */
  tmp = (GPIO_ReadInputPin(GPIOE,GPIO_PIN_1) ^ 1);
  /* shift register */
  itrg <<= 1 ;
  itrg |= tmp ;
  /* masking */
  itrg &= 7 ;
  /* judge */
  if ( itrg == 0x03 || itrg == 0x01 ) {
    if ( istate == RUN_STATE ) {
      /* change state */
      istate = IDLE_STATE ;
      /* suspend */
      sus_tsk(TSK_ID1);
      sus_tsk(TSK_ID2);
      /* turn off LEDs */
      GPIO_WriteHigh(GPIOE,GPIO_PIN_2 | GPIO_PIN_3);
    } else {
      /* change state */
      istate = RUN_STATE ;
      /* suspend */
      rsm_tsk(TSK_ID1);
      rsm_tsk(TSK_ID2);
    }
  }
  /* 50ms = 5 * 10ms */
  wai_tsk(TSK0_INTERVAL);
}

void tsk1_proc(void)
{
  /* invert */
  GPIO_WriteReverse(GPIOE,GPIO_PIN_2);
  /* 2 * 1000 ms = 200 * 10ms */
  wai_tsk(TSK1_INTERVAL);
}

void tsk2_proc(void)
{
  /* invert */
  GPIO_WriteReverse(GPIOE,GPIO_PIN_3);
  /* 3 * 1000 ms = 300 * 10ms */
  wai_tsk(TSK2_INTERVAL);
}

void tsk3_proc(void)
{
  /* invert */
  GPIO_WriteReverse(GPIOD,GPIO_PIN_0);
  /* 1 * 1000 ms = 100 * 10ms */
  wai_tsk(TSK3_INTERVAL);
}

void main(void)
{
  TCBP  pcur_tsk ;
  /* initialize */
  {
    CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO,CLK_SOURCE_HSE,DISABLE,CLK_CURRENTCLOCKSTATE_DISABLE);
    CLK_HSIPrescalerConfig( CLK_PRESCALER_HSIDIV1 );
    CLK_SYSCLKConfig( CLK_PRESCALER_CPUDIV1 );
    /* set I/O */
    GPIO_Init(GPIOE,GPIO_PIN_1,GPIO_MODE_IN_PU_NO_IT);
    GPIO_Init(GPIOE,GPIO_PIN_2 | GPIO_PIN_3,GPIO_MODE_OUT_PP_HIGH_FAST);
    GPIO_WriteHigh(GPIOE,GPIO_PIN_2 | GPIO_PIN_3);
    /* (debug) set I/O */
    GPIO_Init(GPIOD,GPIO_PIN_0,GPIO_MODE_OUT_PP_HIGH_FAST);
    /* initialize timer 4 */
    TIM4_DeInit();
    /* initialize counter 250 */
    TIM4_SetCounter(6);
    /* 16MHz / 128 / 250 = 2ms */
    TIM4_TimeBaseInit(TIM4_PRESCALER_128,ARR4-1);
    /* configure */		
    TIM4_ITConfig(TIM4_IT_UPDATE,ENABLE);
    /* enable timer 4 */
    TIM4_Cmd(ENABLE);
  }
  /* initialize monitor */
  init_os();
  /* regist task */
  cre_tsk(TSK_ID0,tsk0_proc);
  cre_tsk(TSK_ID1,tsk1_proc);
  cre_tsk(TSK_ID2,tsk2_proc);
  cre_tsk(TSK_ID3,tsk3_proc);
  /* initialize task states */
  sta_tsk(TSK_ID0,TTS_READY);
  sta_tsk(TSK_ID1,TTS_SUSPEND);
  sta_tsk(TSK_ID2,TTS_SUSPEND);
  sta_tsk(TSK_ID3,TTS_READY);
  istate = IDLE_STATE ;
  os_cnt = 0 ;
  /* enable interruption */
  enableInterrupts();
  run_tsk = TSK_ID0 ;
  /* endless loop */
  while ( ON ) {
    /* task dispacher */
    pcur_tsk = tcb[run_tsk] ;
    if ( is_tsk_ready( run_tsk ) == YES ) {
      (*(pcur_tsk.tsk))();
    }
    run_tsk++;
    if ( run_tsk == TSK_ID_MAX ) {
      run_tsk = TSK_ID0 ;
    }
  }
}

void TIM4_interrupt(void) interrupt 23
{
  /* clear interrupt flag */
  TIM4_ClearFlag(TIM4_FLAG_UPDATE);
  /* initialize counter 250 */
  TIM4_SetCounter(6);
  /* counter increment */
  os_cnt++ ;
  /* judge */
  if ( os_cnt == 5 ) {
    /* clear counter */
    os_cnt = 0 ;
    /* update */
    timer_handler();
  }
}

#ifdef USE_FULL_ASSERT
void assert_failed(UBYTE* file,ULONG line)
{
  while (ON)  {  }
}
#endif

 PE2、PE3に、2つのLEDを接続し、2つのタスクに点滅を
 任せています。

 各タスクが担当する処理は、次のようにしました。

 PE1には、スイッチを接続し、スイッチを
 押す度に、消灯と点滅動作を切替えます。

---------------------------------------------------
 この後は、ある程度ファームウエア、デジタル回路の
 テストが済むまで、塩漬け(冬眠状態)に。
---------------------------------------------------

目次

inserted by FC2 system