SSブログ

100円マイコン到着 [HCS08]

なんか作った!とか、プログラム組んでみた!とか、実験してみた!とかの話ではなく、買った!とか、行ってみた!とか、もらった!の類の話で申し訳ない。

k_tさんの所(http://6811.teacup.com/miconfan/shop)から例の100円マイコンと、開発ツールが届きました。

マイコンの価格が安いので、取り合えず20個程買ってしまった。
これで「あ!それ!だったらマイコンでやっちまえ!」的大人の選択が余裕でできます。


HCS08でもキャラクタLCD 5 AGAIN [HCS08]

省電力になっていないと言う指摘と、温度の計測が出鱈目だったので、再び登場です。
ここからアップデート版が落とせます。同じファイル名なので気を付けてね。

具体的にどれ位省電力になったのかは計測していないので言えませんが、同じ電池を使い続けながら前回の写真よりも電源電圧が上がっているのが判ります。つまり回路電流が小さくなったので、電池の電圧降下が小さくなった物と思われます。

ただスイッチに対するレスポンスが悪くなったのと、これはむしろ良い方向かもしれませんが、音が単なるピー、ピーって音からビブラートが掛かった事が気になります。

まだまだ続くのか?。

※(☆゜o゜)そうか!、アラーム鳴らしている間はSTOPモードではなくWAITモードでやればいいのか。


HCS08でもキャラクタLCD 4 FINAL [HCS08]

お子様向け電子工作キットとしてもう一台製作。
勿論半田付けは難しい所を除いて自分でやらせました。

※精度の問題は、スタンドアローンで動かしている以上必ずずれるので、ソフトウエア的に調整できるようにしました。
要するに50ppmならば100万クロックに50回、進むか、遅れるかしているので、2万クロック数える度に1個余計にカウントするとか、減じるとかすれば良い事になりますね。
実際には15.6msの割り込みでこの処理を行っていますので、この15.6msの割り込みが2万回数えたら1秒のカウンタを操作しています。
この2万回と言うパラメータはユーザーインタフェースで調整できるようにし、調整後はFLASH ROM領域に書き込まれますので、電源が落ちてしまっても内容を記憶しています。(時間とかアラームは再設定になってしまいますが。)

※電池の持ちはどうかなぁ、実際にやってみるしかないけれど1週間や2週間で落ちると言う事は無さそうだな。もう少し省電力については研究が必要だと思うけれど。

ただ電池電圧が落ちてくると、LCDコントラストの再調整が必要になるので、つまみの有るタイプの可変抵抗にすれば良かった。


HCS08でもキャラクタLCD 3 暫定リリース [HCS08]

まあこんな所かなあ。
プロジェクトファイルはここから。あっ!操作方法等はソースコードをご覧になって下さいね。
今日はもう寝ます。


HCS08でもキャラクタLCD 2 [HCS08]

一応表示内容とか、ユーザーインタフェースとか、アラーム音も鳴るようになったし、時計らしくなってきました。
表示領域が余っているので、電源電圧と温度の表示も追加しようかと思っています。

後はあれ、精度と電池でどこまでもつか?なんだよね~~~。

一応EAGLEの基板の資料
結局の所プリント基板さえできれば良い程度でEAGLE使っていますので、回路図のシンボルはすげー適当です。あまり信じない様に。

アラームはプッシュ/プル回路でスピーカーを駆動できるようにしていますが、適当なサイズのスピーカーが無かったので圧電スピーカーでやってみたらそれなりに鳴っていますので、圧電スピーカーでもOKかな?。勿論圧電スピーカーを選びますが。

コッククロフト・ウオルトン回路の出力にツェナーダイオード(RD4.7)が有りますが、これで定電圧にするつもりでしたが、流す電流が小さ過ぎて上手く行きません。素直に可変抵抗でやっています。

電池は単三だけでなく単四でも試すつもりでしたが、もう単四の事はどうでもいいや。単三の方が安いし。

※今の所12時間経過した辺りで3秒位進んでいる模様(目視での確認)。だから一日で6秒、約70ppm位か。なんの特性データも無い片面エッチング基板でやっている割りには良いのかも知れないけれど、時計としてはもっと精度を上げたい所だよね。
ついついネットワーク時計(http://blog.so-net.ne.jp/hamayan/2005-03-12)とか、電波時計(http://blog.so-net.ne.jp/hamayan/2007-03-23)辺りから同期を取る事を考えがちですが、取り合えず負荷コンデンサとか、フィードバック抵抗とか、ソフトで補正とか考えてみます。


HCS08でもキャラクタLCD [HCS08]

今まで色々なマイコンでこのキャラクタLCDを動かして来ましたので、いよいよHCS08マイコンでも動かしてみました。

但しHCS08 QG8マイコンの電源は最大でも3.6Vまでなので5V掛ける訳に行かず、SC1602の動作保証外の3V(単三電池二本)で動かしています。
まあこのページではMSP430で動かしていますが、なんとなく動いちゃうんですね。

ただ問題はコントラスト用電源で、MSP430マイコンの時は市販の電圧コンバーターICを使ってコントラスト電源を生成していましたが、今回は同じ事をやってもつまらないので、コッククロフト・ウオルトン回路で負電圧を生成し、それを分圧してコントラスト用に使用しています。
写真の青いスイッチの上にあるコンデンサとダイオードがそれです。
専用のコンバータICを使えば確実ですが、折角HCS08マイコンにはタイマー出力が有りますし、この出力を利用してみました。

電池で動かしているので電圧が落ちるとコントラストが変っちゃうのが課題ですが、これで時計でも作ろうかと計画しています。

※A/Dで電源電圧をモニターして、電圧が下がるとタイマーの周波数を上げるとか!でコントラストの変化に対応できないかなぁ。ただこのタイマーでアラーム音も生成するので、そうなると音も変っちゃうし、、、。

※外部xtal端子に時計用クリスタルを接続しまして、それで時を刻む予定です。
HCS08マイコンの省電力とクロック関係は未だに良く判っていないので、これを機に覚えてしまおうと思っています。
別にHCS08マイコンだけがクロックや省電力関係が難しいのではなく、大概のマイコンはその機能が判り難いですけれどね。


HC08 QY4マイコン 100円 [HCS08]

http://6811.teacup.com/miconfan/shop/01_01_01/M-004/

4Kbyte ROM、128byte RAM、16pin DIP、オンチップデバック機能、ISP機能、16bitタイマー2ch、4本の8bit A/D、13本のI/Oと1本の入力専用ポート、1本の専用割り込み入力と6本のキーボード割り込み入力、大電流 sink/source、動作電圧2.2V~3.6V。

安過ぎでしょう。


HCS08 FLASH書き込み 地獄のリベンジ編 [HCS08]

#259
ならばこれでどうだ!
HCS08のアセンブラの出来に関しては、もう知らんよ!。

/****************************************************************/
/* FLASH ROM書き換え処理                                        */
/* ポインタ型を無理やり整数型で扱って気持ちの悪いところを修正   */
/* アセンブラで記述し直し                                           */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/

#include "derivative.h" /* include peripheral declarations */
#include <string.h>
#define Page_Erase   ((unsigned char(*)(volatile unsigned char *, unsigned char))(pgm))
#define Program_Byte ((unsigned char(*)(volatile unsigned char *, unsigned char))(pgm))

/****************************************************************/
/* 特定のFLASH領域に書き込み/消去を行う                         */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/
volatile static unsigned char flash_era_wrt( volatile unsigned char *adr, unsigned char data )
{
#asm
  PSHA ; 

  LDA #0x10  ; FACCERRが立っているかチェックする
  BIT _FSTAT ; FACCERRが立っているかチェックする
  BEQ _NEXT_01 ; 立っていない時は_NEXT_01にブランチ
  ORA _FSTAT ; FACCERRが立っているならクリアして置く
  STA _FSTAT ; 書き戻し

_NEXT_01:  ; 該当する領域にデータを代入する。
  PULA
  STA ,X

  ; コマンド書き込み。最初はERASEコマンド
  LDA #0x40
  STA _FCMD

  ; FCFBEFに1を書き込み
  LDHX @_FSTAT ;

  LDA ,X     ; FCFBEFを1にする
  ORA #0x80  ; FCFBEFを1にする
  STA ,X     ; 書き戻し


  BRN _NEXT_02 ; 4バスサイクル消費する※修正
_NEXT_02 :
  NOP

  ; FACCERRとFVIOLがエラーでない事を確認する
  LDA ,X
  AND #0x30    ; FACCERRとFVIOLの該当bit
  BEQ _NEXT_03 ; 立っていない時は_NEXT_03にブランチ
  LDA #0xff    ; 戻り値を0xffにする※修正
  RTS


  ; FCCFが0の間はコマンド処理中
_NEXT_03 :
  LDA ,X
  AND #0x40    ; FCCFの該当bit
  BEQ _NEXT_03 ; 0の間は_NEXT_03にブランチ
#endasm

  return 0;
}

/****************************************************************/
/* 文字列をFLASH領域に書き込む                                  */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/
int FlashCopy( void *adr, void *data, unsigned short size )
{
  unsigned char temp;
  char *ptr = (char *)data;
  volatile unsigned char pgm[ 46 ];

  /*フラッシュ書き込みコードのコピー*/
  (void)memcpy( pgm, flash_era_wrt, sizeof(pgm) );
  pgm[ 0x11 ] = 0x20;  /*コマンドをbyte writeコマンドに変更する*/

  /*フラッシュ書き込み*/
  for( ; size > 0; size-- )
  {
    if( *ptr != 0xff )
    {
      temp = Program_Byte( (volatile unsigned char *)adr, *ptr );
      if( temp == 0xff ) return (-1);
    }

    ((char *)adr)++;
    ptr++;
  }
  return 0;
}

/****************************************************************/
/* 引数のアドレスが存在するブロックを消去する                   */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/
int FlashErase( void *adr )
{
  unsigned char temp;
  volatile unsigned char pgm[ 46 ];

  /*フラッシュ消去コードのコピー*/
  (void)memcpy( pgm, flash_era_wrt, sizeof(pgm) );

  /*フラッシュ消去*/
  temp = Page_Erase( (volatile unsigned char *)adr, 0x00 );

  if( temp == 0xff ) return (-1);
  return 0;
}

/****************************************************************/
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/


HCS08 FLASH書き込み リターンズ [HCS08]

よし、ならばこれでどうだ!ってもねえ、FLASH書き換えのアルゴリズムはデータシートに掲載されていて、この手順通りにやれよ!って書いてある以上、あのサンプルと殆ど変らん!ってな事にならざるを得ないんだけれど。

一応概要!
FLASH ROMに書き込みを行う場合、同一ブロックの領域からの読み出しが出来なくなる為、FLASH書き換えプログラムは一旦RAM上に引っ越した上で、そこで実行される事となります。

そこでFLASHの消去、書き込みプログラムであるflash_era_wrtをmemcpyでスタック(RAM)に転送し、そこで実行する事で消去したい領域(ページ)の消去を行います。

次に書き込みを行う為に、再びスタックに転送し、0x15番目の値に0x20を代入します。これでflash_era_wrtはFLASH書き込みプログラムに変身しました。
あとはもう、ドカドカとデータを転送するだけです。

/****************************************************************/
/* FLASH ROM書き換え処理                                        */
/* ポインタ型を無理やり整数型で扱って気持ちの悪いところを修正   */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/

#include "derivative.h" /* include peripheral declarations */
#include <string.h>
#define Page_Erase   ((unsigned char(*)(volatile unsigned char *, unsigned char))(pgm))
#define Program_Byte ((unsigned char(*)(volatile unsigned char *, unsigned char))(pgm))

/****************************************************************/
/* 特定のFLASH領域に書き込み/消去を行う                         */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/
volatile static int flash_era_wrt( volatile unsigned char *adr, unsigned char data )
{
  if( FSTAT_FACCERR == 1 )  /*FACCERRが立っているなら、クリアして置く*/
  {
    FSTAT_FACCERR = 1;  /*1を書いてクリア*/
  }

  *adr = data;  /*該当する領域にデータを代入する。*/

  FCMD = 0x40;  /*コマンド書き込み。最初はERASEコマンド*/

  FSTAT_FCBEF = 1;  /*FCFBEFに1を書き込み*/
  __asm NOP;  /*4バスサイクルの待ちを入れる*/
  __asm NOP;
  __asm NOP;
  __asm NOP;

  if( FSTAT & 0x30 )  /*FACCERRとFVIOLがエラーでない事を確認する*/
  {
    return 0xFF;  /*エラーで返る*/
  }

  while( FSTAT_FCCF == 0 ) ;  /*FCCFが0の間はコマンド処理中*/

  return 0;
}

/****************************************************************/
/* 文字列をFLASH領域に書き込む                                  */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/
int FlashCopy( void *adr, void *data, unsigned short size )
{
  unsigned char temp;
  char *ptr = (char *)data;
  volatile unsigned char pgm[ 59 ];

  /*フラッシュ書き込みコードのコピー*/
  (void)memcpy( pgm, flash_era_wrt, sizeof(pgm) );
  pgm[ 0x15 ] = 0x20;  /*コマンドをbyte writeコマンドに変更する*/

  /*フラッシュ書き込み*/
  for( ; size > 0; size-- )
  {
    if( *ptr != 0xff )
    {
      temp = Program_Byte( (volatile unsigned char *)adr, *ptr );
      if( temp == 0xff ) return (-1);
    }

    ((char *)adr)++;
    ptr++;
  }
  return 0;
}

/****************************************************************/
/* 引数のアドレスが存在するブロックを消去する                   */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/
int FlashErase( void *adr )
{
  unsigned char temp;
  volatile unsigned char pgm[ 59 ];

  /*フラッシュ消去コードのコピー*/
  (void)memcpy( pgm, flash_era_wrt, sizeof(pgm) );

  /*フラッシュ消去*/
  temp = Page_Erase( (volatile unsigned char *)adr, 0x00 );

  if( temp == 0xff ) return (-1);
  return 0;
}

/****************************************************************/
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/


HCS08コンパイラ 自分の為のメモ [HCS08]

いやもう嵌った、嵌った。半日は嵌った。
いやねえ、以下の様なREAD ONLYな配列を、ユーザー独自のセクションに置きたかった訳ですよ。

/*	parameter width = 2 height = 16 line = 4*/
const unsigned short Arrow1PixWidth = 16;
const unsigned short Arrow1PixHeight = 16;
const unsigned char Arrow1GraphicBMPTable[] = 
{
	0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,
	0x03,0x03,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x03,0x03,
};

多分#pragmaでセクションを設定してリンカーファイルで割り付けを定義するだろうとは想像していましたが、英文のHELPを読んで方法を解読せねばならず、しかし英文は物凄く苦手としているので、適当に読んでは記述を変更して、コンパイルして、mapを確認して、、、ってこのループが延々と続いて、やんなっちゃった。

で取りあえず見つけた方法は、まず元のソースファイルに#pragmaを以下の様に記述します。
#pragma CONST_SEG BMP_DATA
そうすると、この行以下のソース上でCONSTな変数は、BMP_DATAってユーザーセクションにグループされます。
元の標準のセクションに戻すには、
#pragma CONST_SEG DEFAULT
でOK。

こんな感じです。

#pragma CONST_SEG BMP_DATA

/*	parameter width = 2 height = 16 line = 4*/
const unsigned char Arrow1GraphicBMPTable[] = 
{
	0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,
	0x03,0x03,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x03,0x03,
};

#pragma CONST_SEG DEFAULT
const unsigned short Arrow1PixWidth = 16;
const unsigned short Arrow1PixHeight = 16;

リンカーファイル(Project.prm)は以下の記述をPLACEMENTの所に追加します。

    BMP_DATA    INTO READ_ONLY    0xE100 TO 0xE1FF;

これでコンパイル、リンクしてmapを確認すると、

MODULE:                 -- arrow1.c.o --
- PROCEDURES:
- VARIABLES:
     Arrow1PixWidth                            F551       2       2       2   .rodata     
     Arrow1PixHeight                           F553       2       2       2   .rodata     
     Arrow1GraphicBMPTable                     E100      20      32       2   BMP_DATA    

と無事に配置されていますね。

フリスクの人!、やっぱりコンパイラマニュアルは日本語が欲しいよ!。


この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。