脱公務員電子回路設計エンジニア

SCTに挑戦

State Configurable timerに挑戦

 SCTは単純にはタイマである。しかし設定を見ると非常に複雑に見えます。テキストでは、開発環境がLPC Xpressoの時に書かれた
ものなので テキスト中にSCTの設定をRed State Machineとやらを使用して、設定することが紹介されていました。
 私も、このRed State Machineを現在使用している開発環境において探しましたがどうもない。ネットにて調べてみると、Commnityサイトにつながり、どうもMCU Xpresso IDEにはRed State Machineのようなツールはないようです。
NXPのエンジニアからすると、SCTの設定を効率的に行うのに、Red State Machineは効率的ではないという判断になって様子です。
そのため、MCU Xpresso IDEには付属しておらず、代わりにSCTクックブックに移行した模様です。
これは、ネット上でPDFで見ることができました。AN11538_SCTimer_PWM_Cookbook v5.0.pdfの名称で
検索して頂くとPDFを見つけることができます。

SCT概要

SCTのクックブックをミルとまず、概要の以下のような表が最初のほうに出てきます。 クックブックには、Red Stateのような設計ツールを使用しなくても、実査に使用すrのはそれほど難しくありません。的なことが1.2用語解説の十頃に書いてありました(本当か?)。
 SCTには、独特な用語がたくさん出てくるのでここで整理です。以下はクックブックから書き出したものです。

機能について

 とにかくできることが多いのでその副作用として、設定するレジスタが多くこれは混乱します。
特に便利だと思った機能が、デッドタイムを仕込んだPWM波形を出力できるようです(今最近のマイコンは当たり前の機能なのか分かりませんが)。
昔のマイコンにはそのような機能がなかったので、モータなどをブリッジ回路を組んでPWMで制御する場合、ハード側でこのデッドタイムが自動的に入るように回路組まなければならなかったのが、ソフトウェアでできるとは驚きです。まぁ考えてみればMOSFETなども半導体なので当たり前といえば当たり前ですが。

プログラム

 以下に作成したプログラムを知るします。テキストではRed Stateなるツールを使用しているので、参考になったのは、掲載されていたsct_fsm.cを元に作成しました。

/*
* Copyright 2022 NXP
* NXP confidential.
* This software is owned or controlled by NXP and may only be used strictly
* in accordance with the applicable license terms.  By expressly accepting
* such terms or by downloading, installing, activating and/or otherwise using
* the software, you are agreeing that you have read, and that you agree to
* comply with and are bound by, such license terms.  If you do not agree to
* be bound by the applicable license terms, then you may not retain, install,
* activate or otherwise use the software.
*/

#ifdef __USE_CMSIS
#include "LPC8xx.h"
#endif

#include <cr_section_macros.h>

#define offVal	(4096)
#define onVal	(2048)
// TODO: insert other include files here
void SCT_Init();
void SwitchMatrix_Init();
// TODO: insert other definitions and declarations here

//SCT のPWM変化を見るための待ち
volatile static  int waiting=0;
void SysTick_Handler(void){
 if(waiting){
 	waiting--;
 }
}

void wait_ms(uint32_t ms){
 waiting=ms;
 while(waiting);
}
//

int main(void) {

 SwitchMatrix_Init();
 SCT_Init();
 SysTick_Config(SystemCoreClock/1000);

 // SCT Enable
 LPC_SCT->CTRL_U &=~(1<<2);

 while(1) {
 	int i =0;
 	for(i=0;i<offVal-onVal-100; i=i+10){
 		LPC_SCT->MATCHREL[1].U=onVal+i;
 		wait_ms(10);
 	}

 }
 return 0 ;
}




void SwitchMatrix_Init()
{
 /* Enable SWM clock */
 LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7)|(1<<8);		//SWM SCT ClockEnable

 /* Pin Assign 8 bit Configuration */
 /* CTOUT_0 */
 LPC_SWM->PINASSIGN6 = 0x01ffffffUL;

 /* Pin Assign 1 bit Configuration */
 /* SWCLK */
 /* SWDIO */
 /* RESET */
 LPC_SWM->PINENABLE0 = 0xffffffb3UL;
}


void SCT_Init(){

 LPC_SCT->CONFIG = 0x00000001;	//SCT 32bit counter UNIFY=1
 LPC_SCT->REGMODE_L=0x00;		//resistor operate match registor

 LPC_SCT->MATCH[0].U=offVal;			// SCTMATCH[0].U  Unified 32-bit register
 LPC_SCT->MATCHREL[0].U=offVal;

 LPC_SCT->MATCH[1].U=onVal;
 LPC_SCT->MATCHREL[1].U=onVal;

 LPC_SCT->OUT[0].SET=0x01;
 LPC_SCT->OUT[0].CLR=0x02;

 LPC_SCT->OUT[1].SET=0x00;
 LPC_SCT->OUT[1].CLR=0x00;
 LPC_SCT->OUT[2].SET=0x00;
 LPC_SCT->OUT[2].CLR=0x00;
 LPC_SCT->OUT[3].SET=0x00;
 LPC_SCT->OUT[3].CLR=0x00;

 //EVENT Resistor
 LPC_SCT->EVENT[0].CTRL =0x00005001;
 LPC_SCT->EVENT[0].STATE=0x00000001;
 LPC_SCT->EVENT[1].CTRL =0x00005000;
 LPC_SCT->EVENT[1].STATE=0x00000001;
 //unUsed
 LPC_SCT->EVENT[2].CTRL =0x0;
 LPC_SCT->EVENT[2].STATE=0x0;
 LPC_SCT->EVENT[3].CTRL =0x0;
 LPC_SCT->EVENT[3].STATE=0x0;
 LPC_SCT->EVENT[4].CTRL =0x0;
 LPC_SCT->EVENT[4].STATE=0x0;

 LPC_SCT->STATE_L=0x0;
 LPC_SCT->STOP_L=0x0;
 LPC_SCT->HALT_L=0x0;
 LPC_SCT->LIMIT_L=0x00000002;
 LPC_SCT->EVEN=0x00;
 }
解説します。  
まず、offVal,onValはいいかと思います。SCT_Initは、sct_fsm.cを参考しており、ほとんどそのままです。テキストだとRed Stateを使用して3つのファイルを吐き出して利用しておりますが、どうも使用しているのは、onValとoffValの定義くらいでした。  
 テキストでは、疑似乱数の発生のためxor128やらxs[4]なる関数を定義して、main巻子内のfor分内で使用しているので、なんだか込み入っててわかりにくいのでなるべくシンプルにすべく使用しておりません。  
 Switch Matrixの初期化部分では、前回のこともあり、Switch Matrix Toolを使用して初期化部分のコードを見ると、やはり、SYSAHBCLKCTRLがbit7(SWM)の(1<<7)のみであったため、SCTがおそらくイネーブルにならないと思い、(1<<8)とORをしてSCTにもクロックが供給されるように変更しております。  
for分ないでは、offValとonValの差分(これを増加させてパルス幅の増加を見たい)から安全のためoffValから100小さくした値の範囲でデューティ比が変化するようにしております。
 wait_msについては、使用しなくてもパルスを単に出すだけなら必要ありません、したがってSystick_Handlar周りの関数も記載する必要がありません。ところがこの待ちを設けずにリロードレジスタの値を増加させると変化が速すぎて、スピーカから変な和音のような音が聞こえてしまいます。  
 デューティ比だけ変化させているので、音はあまり変化しません。音量が小さくなっていくのが確認できました。
### LPC_SCT->CONFIG
 UNIFYビットを1にしています。これによりSCTは32ビットカウンターとして動作します。  
### LPC_SCT->REGMODE_L
 SCT match/capture registers mode registerは、UNIFY=1の場合は、このレジスタの_Lだけが使用されるようです。このレジスタのDescriptionには、各ビットは**1組**のマッチ/キャプチャレジスタを制御するとマニュアルに記載されています。
### LPC_SCT->MATCH[0]
 マッチレジスタはカウンタと比較されます。UNIFYビットが1の場合、LおよびHレジスタは32ビット値を保持し、ユニファイド・カウンタと比較される。

オシロスコープ 的なものがないと確認ができないので私はリンクに示したもの(メーカは違います。)を使用して観察しました。
 いよいよ次はパソコンとスマートフォンとの連携の章に入ります。