トラブルシュートメモ

このページは、体験したトラブルをランダムに書き留めてゆくページです.


トラブル:   2012.3.25
TLI割り込みをOFFにできない.なんでだろ???

トラブル現象:
下記のコードでやりたいことは、TLIを一発だけ受けつけることでした.
そのために、@のところでEXTI_DeInit()をコールすることで、2発目以後のTLIをdisableしようとしました.
ところが、@の操作では、TLIをdisableできませんでした.2発目以後のTLIも受け付けてしまいました.
main()
{
  GPIO_Init(GPIOD, GPIO_PIN_7, GPIO_MODE_IN_PU_IT);
  EXTI_DeInit();
  EXTI_SetTLISensitivity( EXTI_TLISENSITIVITY_FALL_ONLY );
  while(1);
}

void TLI_interrupt(void) interrupt 0
{
  なんか処理........
  @EXTI_DeInit();
}

原因:
EXTI_DeInit(); をコールすると、その時点でTLIがenableになるみたいです.
なので、
EXTI_DeInit(); をコールしてもdisableできません.

対処:
GPIO_Init()でTLIピンを非割り込みピンに変更します.NO_ITのところがそれです.
void TLI_interrupt(void) interrupt 0
{
  なんか処理........
  GPIO_Init(GPIOD, GPIO_PIN_7, GPIO_MODE_IN_PU_NO_IT);
}




トラブル:     2012.3.22
clockがHSEだと、UARTのbaudrateがなぜかめちゃくちゃで通信できない.
ところが、clockをHSIにすると正常に動く.これはオカルトだ.
HSE=外部clock
HSI=内部clock

真の原因:
なんでかわからないけど、XTALが16MHzを発振していないので、HSEがダメになっている.

副次的な原因:
XTALが死んでいる状況でHSEと設定したのに、UART以外の部分はそれとなく動いているのはなぜか?
それは、STM8Sのclock切替の仕組みによります.
STM8Sはreset直後はHSIになっています.
HSEに切り替えるのは、走り始めたプログラムが自分で自分をHSEに切り替えるんですが、HSEにしろという関数をコールした瞬間にHSEに切り替わるわけではありません.
clockに限らず信号を無造作にガキッと切り替えるとグリッジが生じる危険があります.
そしてclockにグリッジが生じるということは、回路の動作速度的に許容できないような高周波数のclockが1発だけ注入されたことと同義です.
すると、digital回路が動作不全になり、resetするまで復帰しないことがままあります.
これを避けるために、HSI→HSEへスムーズに自動切替えする回路がSTM8Sには内蔵されています.
ところが、故障しててHSEが待てども来ませんので、HSIのまま留まり続けるという帰結を招きます.
つまり、HSEが発振してないSTM8SでHSEに切り替えたつもりになっていても、実態はHSIのままそれとなく動き続けるのです.
だから、HSIなら完璧に動くけど、HSEだと不完全に動くというオカルト現象を体験することになってしまうんです.

蛇足:
clockが切り替わったことを確証するにはどうしたらいいか?
概要だけ書きますと、stm8s_clk.cというライブラリファイルのなかのCLK_GetClockFreq(void)という関数が参考になります.
この関数では、CLK_CMSRというレジスタを参照します.このレジスタをreadすれば、clockが切り替えられた結果を観測できます
データシートから抜粋した文言がつぎです.
要するに、0xE1ならHSI、0xD2ならLSI、0xB4ならHSEに今なっているとわかります.
Bits 7:0 CKM[7:0]: Clock master status bits
These bits are set and cleared by hardware. They indicate the currently selected master clock
source. An invalid value occurring in this register will automatically generate an MCU reset.
0xE1: HSI selected as master clock source (reset value)
0xD2: LSI selected as master clock source (only if LSI_EN option bit is set)
0xB4: HSE selected as master clock source


トラブル:     2012.1.23
ヘッダファイル.hが見つかりません系のビルドエラーがダーッと出る.


原因:
実例01に従ってSTVDのインストールをしたつもりが、どこかで間違えてライブラリファイルの存在するパスを指定できてないことが原因ぽいです.

対処:
なので、次のように設定することで回避できるんじゃないかと思います.
@ビルドエラーが出るprojectを開いている状態で、STVDのメニューの、Tools→Options... をクリック.
AOptionsウインドウが開きます.Directoriesタグをクリック.
キモは下記のところです.あなたの環境におけるライブラリの置き場じゃないところを指定してしまっているんじゃないかと?

B上図のNewボタンをクリック.
C別のフォルダを追加できるようになりますので、
「あなたのライブラリフォルダ\STM8S_StdPeriph_Lib_V2.0.0\Libraries\STM8S_StdPeriph_Driver\inc」
「あなたのライブラリフォルダ\STM8S_StdPeriph_Lib_V2.0.0\Project\Template」
の2つを追加します.
蛇足ながら、これらのライブラリはSTMicro社のサイトからDLしたそのままではダメで、実例01に従い一部を書き替えたファイルでなくてはいけません.
残念ながらサンプルプログラムの中にわたしが入れたライブラリフォルダは、....\Template 含んでいないので役にたたないことに気づきました.これはいずれ修正します.orz
DOKをクリック.



トラブル:
心当たりのない動作不良.なぜか動かない.

推定原因:
コンパイルできてないかも.
本件は、わたしのチョンボであることに気づきました.
char str[20];のような配列変数の長さを超えて代入した結果、変数領域を破壊している、つまりプログラマであるわたしのミス.
なので、メモリモデルを変えると治ったりするということのようです.

なので、本質的には配列を正しく使いましょうというのが対処です.失礼しました・

対処:
STVDのグローバル変数とモデル設定をいじってみてください.症状が直るかも.
デフォルトでこのようになっていると思います.
赤で囲ったところを変えてみます.

グローバル変数のところは、グローバル変数を確保する量が少ないときは「in Zero Page」にして、グローバル変数を確保する量が多いときは「in Data」にします.
わたしが悩んでい
るのは、じゃあ常にin Dataにしておけばいいじゃないかと思って小さなプログラムをBuildするときにin Dataのままにしておくと、所望の動作をしてくれなくて悩むことがありました.
なにげに着目してみたらいいかもしれません.


プログラムサイズによって、Program modelも変更します.
小さなプログラムではSTM8 small modelでOK.大きなプログラムではSTM8 large modelにします.
小さいか大きいかは何をもって判断するか? よくわかってません.
ただ、原因不明の動作不良のときに、small/largeを切り替えると直ることがあります.
常にlarge modelにしておけがよいかというとそうでもなさそうです.
なにげに着目してみたらいいかもしれません.
ちなみに、STM8S105C6は、middleサイズなんです.


inserted by FC2 system