目次
前
次
内蔵モジュール操作
ADuC7026内には、次の内蔵モジュールが含まれています。
- GPIO(General Purpose Input and Output)
- Timer/Counter
- A/D converter
- D/A converter
- UART
- IIC bus interface
- PLA(Programmable Logic Array)
- SPI bus interface
- IRQ(Interrupt ReQuest)
- PLL
これらの内蔵モジュールを扱うには、MMR(Memory Mapped Register)
を介した、CPUとのやりとりが必要です。
内蔵モジュールを扱うことは、ラベル定義された各モジュール
のレジスタへのパラメータ設定、レジスタの情報取得の2点に
まとめられます。
内蔵モジュール操作に必要となるレジスタに関して説明します。
MMR(Memory Mapped Register)
ADuC7026は、メモリマップドI/Oで設計されています。
内蔵モジュールをアクセスするためには、メモリ
アドレスを知らなければなりません。
メモリ空間の仕様は、以下です。
メモリ空間の図からわかることは、内蔵SRAMが8kbyte、プログラム
フラッシュメモリが64kbyte、MMRは0xFFFF0000より上に配置。
リマップメモリがあることが、メモリ空間の図に
さりげなく示されています。
MMRの詳細を見ていきます。
GPIO(General Purpose Input and Output)
ADuC7026には、5ポートありますが、内蔵モジュール
との兼用ピンになっていることが多いので、GPIO関係
のレジスタで、GPIOにするか、他の内蔵モジュールの
入出力ピンに切替えます。
GPに続く番号に連ねて、CONというラベルがある
MMRにGPIOで使うのか、内蔵モジュールを使うか
を記述します。(CONはCONFIGUREの略)
GPIOとして利用するには、CONレジスタに2進数で00
を設定します。
GPIOのCONレジスタは、32ビットなので4ビットごとに
対応する1ピンのモードを設定できます。
ピンは0〜7の合計8ピンなので、4ビットごとに
指定すると、32ビットになります。
16進で指定すると、1けたごとに0、1、2、3のいずれかを
指定すれば充分です。
GPIO0でピンのモードを指定してみます。
P0.1、P0.2をPWMのピンに設定するとき、次のように
レジスタに32ビット値を保存します。
GP0CON = (1 << 4*2) | (1 << 4*1) ;
or
GP0CON = 0x00000110 ;
P1.0、P1.1には、シリアルインタフェースを
P1.2、P1.3には、IICバス処理をアサインする
ときは、以下のマップを参照します。
ビット番号を使い、シフトにより2ビットを設定
するコードを記述すれば、モード設定が可能です。
GP1CON = (1 << 4*1) | (1 << 4*0) ;
GP1CON |= (2 << 4*3) | (2 << 4*2) ;
or
GP1CON = 0x00002211 ;
このコードでは、上位4ビットは、GPIOになります。
ポート2では、PWM出力を割り当てられるので
0ビットと3ビットをGPIOにするすれば、
コードは以下とします。
GP2CON = 0x11110110 ;
ポート3では、PWM出力を割り当てられるので
全ビットをPWM関連に割当てるならば、以下。
GP3CON = 0x11111111 ;
ポート3では、A/Dコンバータの入力にも
割り当てられるので、上位4ビットをA/D
コンバータにわりあてると、CONレジスタ
への書込みは、次のようになります。
GP3CON = 0x22220000 ;
ポート4をすべて、GPIOで利用する場合
レジスタへは、次のように設定します。
GP4CON = 0x00000000 ;
GPIOで利用する場合、各ポートの入出力方向と
入力値の取り出し、出力値の設定が必要です。
この操作は、DATレジスタに値を設定します。
DATレジスタは、32ビットで、次のフォーマット
で利用します。
ポート4の上位4ビットを出力として、1010を
出力する場合、GP4DATに次のように設定します。
GP4CON = 0x00000000 ;
GP4DAT = 0xf0a00000 ;
該当ポートを出力に設定し、指定ビットに1か0
を設定したいなら、SETかCLRレジスタを使います。
SETレジスタ、CLRレジスタは8ビットを次のビット
番号の領域に設定します。
ポート0、ポート1を出力に設定し、ポート0
はすべて1、ポート1はすべて0に設定する
場合、レジスタには次のように記述します。
GP0CON = 0x00000000 ;
GP1CON = 0x00000000 ;
GP0SET = (0xff << 16) ;
GP1CLR = (0xff << 16) ;
ポート0、1、3にはプルアップレジスタ
PARがあります。入力での利用で、外部の
抵抗をなくすことで、部品点数を削減する
ことができます。
ビット単位でプルアップあり、なしを1ビット
で指定可能です。
ポート3の上位4ビットに、プルアップを
設定するときは、次のようにします。
GP3CON = 0x0f000000 ;
GP3PAR = 0x11110000 ;
Timer/Counter
Timerに割当てられているレジスタの
ラベルとアドレスを見ます。
図から、4つのTimerがあると読めます。
更に、どんな情報があるのかを見ます。
タイマーの番号を示すT0、T1、T2、T3に
続いて、次の文字列がついています。
各文字列は、レジスタの特徴を込めている
はずなので、動作がわかるよう文字を加え
てみます。
- LD LOAD
- VAL VALUE
- CON CONFIGURE
- CLRI CLEAR INTERRUPT
- CAP CAPTURE
CONFIGUREに設定するパラメータで
動作を指定する方式と推定できます。
CLRIが、CLEAR INTERRUPTなので
割込みで、タイマーを使いたい
処理に通知できる機能も持って
いるのでしょう。
timer1だけは、CAPTUREレジスタを
もち、イベントが発生したときの
タイマーカウント値を記憶できる
仕様になっています。
動作の詳細は、別のページで説明します。
A/D converter
12ビットA/D変換器に関連するレジスタは、次の
ようにアドレスが割当てられています。
この他に、A/D変換器の使う参照電圧を指定する
レジスタのREFCONがあります。
A/D変換器のブロック図は、以下です。
基本は、差動動作であると判断できます。
D/Aコンバータを2つ利用した、逐次比較
処理でA/D変換を実現します。
OPアンプの非反転と反転入力にキャパシタ
を接続して、電荷をチャージします。
ブロック図から、逐次比較処理の動作を
判断できます。
入力端子からの電荷チャージにはSW1の
サンプリングが担当します。また、OP
アンプは、コンパレータとして使って
電圧の取得には、SW3のサンプリングが
担当します。
擬似差動動作の場合は、以下のように使います。
擬似差動動作は、OPアンプによるコンパレータ
の反転入力を、VrefかVIN-に固定します。
シングル動作の場合は、以下です。
シングル動作は、OPアンプによるコンパレータ
の反転入力を、GNDに固定します。
完全差動、擬似差動、シングル動作のブロック図
を見ると、各レジスタの各ビットに割当てられた
機能が理解できます。
ADCCONを見ていきます。
入力端子からの電荷チャージを、サンプリングする
ためのクロック指定は、ビット10〜12で指定します。
電圧取得サンプリングは、ビット9、10で指定です。
A/D変換器には、通常電源が接続されていないので
使う場合、電源を接続します。これは、ビット5で
指定となります。
完全差動、擬似差動、シングル動作のどのモードで
動かすのかは、ビット3、4で指定します。
A/D変換のタイミングを、プログラムで実現するか
タイマー0、1の割込み、あるいは、コンパレータ
を利用するのかを指定できます。
変換タイミングは、ビット7かビット0から2の
どちらかで指定します。
他には、A/D変換中か否かを外部に示すための
処理をビット6で指定します。GPIOの設定で
フラグ出力で指定しないと、反映されません。
完全差動、擬似差動、シングル動作では、どのピンに
A/D変換器を接続するかをADCCP、ADCCNで指定します。
ADCCPは、コンパレータの非反転入力の接続ピンを
指定します。ADCCNは、反転入力の接続ピンを指定
となっています。
ADCCPには、キャリブレーションのための電圧
指定もできるようになっています。
プログラムでA/D変換処理を実現するために
レジスタADCSTAを利用します。変換中か否か
をフラグで示します。
A/D変換の精度を上げるために、オフセットを
指定できます。レジスタADCOFにオフセット値
を格納できます。
A/D変換した内容は、レジスタADCDATに含まれます。
12ビットの値は、32ビット中の上位16ビットに
含まれます。上位4ビットは、符号ビットです。
リファレンス電圧をどうするかを、レジスタ
REFCONで指定します。
Vrefを利用するか、内部の2.5Vを使うか等
いろいろと変更できます。
各レジスタの使い方詳細は、別の説明ページに
記述します。
D/A converter
12ビットD/A変換器に関連するレジスタは、次の
ようにアドレスが割当てられています。
ポート4の上位4ビットに、D/Aコンバータの出力が
アサインされているので、GP4CONでD/Aコンバータ
利用を指定しなければなりません。
DACCONには、次の内容を指定します。
- D/A値出力タイミング
- D/A変換に利用するカウンタ
- リファレンス電圧
12ビットの設定は、次のように4本の32ビット
レジスタの上位16ビットに12ビットを格納する
仕様です。
詳細は、別のページで説明します。
UART
UARTは、1チャネルのみ用意されています。
関連するレジスタは、以下。
調歩同期ならば、設定するレジスタは
4個だけです。
- COMCON0
- COMDIV0
- COMDIV1
- COMIEN0
レジスタマップを見るとわかりますが
複数レジスタが、同一アドレスに割当
になっています。
送信、受信のレジスタが同一アドレスという
周辺ICはよくありますが、他のレジスタにも
同一アドレスがあり、最初は戸惑いました。
レジスタを切替えるには、COMCON0のMSBを
使ったセレクタを使います。
ボーレートを決めるCOMDIV0、COMDIV1の設定値は
POWCONに設定する内部分周器の値と関係します。
POWCONの下位3ビットの設定値で、UARTブロックに
与えられるクロックは、次のようになります。
- 000 41.78MHz
- 001 20.89MHz
- 010 10.44MHz
- 011 5.22MHz
- 100 2.61MHz
- 101 1.31MHz
- 110 653kHz
- 111 326kHz
ボーレート計算には、リスト中のひとつの
周波数からしか、分周比を計算する分子を
選べないことになっています。
ボーレートの値をBPS、リストの周波数をfsclkに
すると、COMDIV1、COMDIV0の設定値は、次の計算
で求められます。
COMDIV1 = {fsclk/(16x2xBPS)} / 256
COMDIV0 = {fsclk/(16x2xBPS)} % 256
UARTに関連する割込みを使う場合、レジスタCOMIEN0
で、利用する割込みを指定できます。
- 3ビット モデム信号に関連する割込み
- 2ビット 受信関係エラーに関する割込み
- 1ビット 送信バッファエンプティ
- 0ビット 受信バッファフル
どの割込みが発生したか、現状態がどうかは
レジスタCOMSTA0の該当ビットで判断できます。
各レジスタの詳細情報は、別の説明ページに
記述します。
物理ピンは、UARTで使うために、GPxCONの
設定値で変更します。
IIC bus interface
最初これらのレジスタ類を見ると、驚きました。
しかし、IICバスの仕様を考えると各レジスタの
意味がわかってきます。
ADuC7026には、2つのIICバスモジュールが内蔵
されているので、左右それぞれのレジスタに関し
理解する必要はなく、左だけで充分です。
IICバスは、マスターとスレーブでデータ交換する
のが基本。マスターとスレーブに分け、レジスタの
もっている機能を理解します。
マスターに関連するレジスタは、以下。
- I2C0MSTA
- I2C0DIV
- I2C0MRX
- I2C0MTX
- I2C0ADR
- I2C0CCNT
- I2C0CNT
ステータスを保持しているのがI2C0MSTAです。
マスターの場合、SCLから100kHzか400kHzのクロック
を出力しなければなりません。どちらの周波数にする
かを、I2C0DIVの設定値で変更します。
データの送受信に関しては、I2C0MRX、I2C0MTXが
関わります。MRXはマスターの受信レジスタ、MTX
はマスターの送信レジスタです。
マスターから、相手を特定するためには、相手の
デバイスIDが必要です。デバイスIDを、I2C0ADRに
格納します。上位7ビットが有効で、LSBを0か1
にするかで、リードかライトを指定します。
IICバスでは、スタート、ストップの状態設定が
必要です。SCLをHに保持したまま、SDAをHからL
あるいはLからHに変化させます。その操作を簡単
にするため、レジスタI2C0CCNTを利用します。
データ受信の場合、I2C0CNTにより受信するバイト
数を設定して処理します。
スレーブに関連するレジスタは、以下。
- I2C0SSTA
- I2C0SRX
- I2C0STX
- I2C0ID0
- I2C0ID1
- I2C0ID2
- I2C0ID3
ステータスを保持しているのがI2C0SSTAです。
スレーブの場合、ひとつのIICバスモジュールで
4つのアドレスを利用できるようにしています。
I2C0ID0からI2C0ID3に、そのアドレスを格納して
おきます。
IICバスのマスターからみると、ADuC7026は4つの
スレーブに見えます。4つのスレーブで機能を変え
動作をエミュレーションできます。
データの送受信に関しては、I2C0SRX、I2C0STXが
関わります。SRXはマスターの受信レジスタ、STX
はマスターの送信レジスタです。
IICバスモジュールとして、どう動くのかをレジスタ
I2C0CFGに設定したパラメータで確定します。
動作の詳細は、別のページで説明します。
PLA(Programmable Logic Array)
PLAに関係するレジスタは、以下となっています。
レジスタのマップを眺めると、PELEMENTだけが0〜15と
多数あることがわかりますが、PELEMENTは、次の回路構成
をとります。
CPLD、FPGAに触れた経験があれば、一度くらいは
目にする図です。
PELEMENTは、0〜7をBLOCK0、他をBLOCK1として
構成されています。
0〜4の番号がついたブロックは、データセレクタで
LUT(LookUp Table)の入力と、レジスタあるいはLUTの
出力を転送します。
レジスタPELEMENTは、上図の16個の回路動作を個別に
指定するために利用します。
LUT(LookUp Table)は、2入力1出力の論理演算回路
で、一般にはPLA(Programmable Logic Array)と呼び
ます。PLAをLUTと表現するのは、XilinxのCPLD、FPGA
のデータシート内で、よく見られます。
PLAに入力するデータを指定するために、0〜3の
データセレクタで、スイッチングします。
PLAの出力を直接転送するか、レジスタを介してから
転送するかを、データセレクタ4を使います。
PLAで実現する演算機能は、4ビットで指定します。
PLAの入力は、ELEMENT0、ELEMENT8が特別で
他は、共通仕様になっています。
2入力1出力のデータセレクタは、上が1
下が0となるように配置されています。
各ELEMENTからの出力は、次のようになっています。
ここでも、2入力1出力のデータセレクタは、上が
1で、下が0となるように配置されています。
各ELEMENTの入力と出力を指定するには、PLA_TOOLが
ありますが、簡単なスクリプトでPELEMENTに設定する
パラメータを生成することにしました。
AWKのスクリプトは、以下です。
{
result = 0 ;
# MUX4
result += $6 ;
# LUT
result += $5 * 2 ;
# MUX3
result += $4 * 32 ;
# MUX2
result += $3 * 64 ;
# MUX1
result += $2 * 128 ;
# MUX0
result += $1 * 512 ;
# show
printf("%s => 0x%08x \n",$0,result);
}
テキストファイルに、パラメータを6個指定して
AWKを動かすと、16進8桁のコードを生成します。
パラメータは、MUX0、MUX1、MUX2、MUX3、LUT、MUX4の
順に指定していきます。MUX0、MUX1、LUTは10進数で
指定します。
例として使ったファイルの内容は、以下。
2 2 1 0 2 0
0 0 0 1 10 0
2 0 1 0 12 0
スクリプトでPLEMENTに指定するパラメータを
生成すると、次のようになります。
2 2 1 0 2 0 => 0x00000544
0 0 0 1 10 0 => 0x00000034
2 0 1 0 12 0 => 0x00000458
使い方は、単純です。
gawk -f mkpla.awk txt2.txt > res2.txt{enter}
レジスタに入れるクロックは、BLOCK0、BLOCK1で
個別に指定できます。
PLAからの割込みを使えるようになっていますが
IRQ信号を生成するのは、BLOCKひとつにつき、
3つあり、ひとつだけ選択できます。
IRQ信号を利用する場合、レジスタPLAIRQを使います。
PLAを利用するのは、外部割込みをエッジで処理する
とき、A/D変換器の変換割込みで動かすとき等です。
SPI bus interface
SPIバスは、入力と出力の8ビットシフトレジスタを
利用した、データ交換ハードウエアとプロトコルを
指します。
ADcU7026内部のレジスタは、以下です。
SPIバスは、入力と出力の信号は決めてあり
シフトレジスタを利用するので、クロックを
出す側をマスター、クロックを受取る側を
スレーブと呼んで区別します。
マスターは、クロックを与えると同時に、どの
スレーブを選択するかを信号SSを使います。
SPIRX、SPITXは、シフトレジスタなので、どの
レジスタと関連するのかは、すぐわかります。
SPICONで、マスター、スレーブの指定および
動作モードを選択します。
シフトレジスタを使うには、クロックが必要なので
SPIDIVにクロックソースと分周比を指定します。
SPISTAには、各状態値が格納されるので、その値
を使い、2つのシフトレジスタへのデータ設定や
取得等に利用します。
IRQ(Interrupt ReQuest)
割込みを利用するには、IRQモジュールにある
レジスタを操作します。
メモリマップを見ると、IRQとFIRQがあります。
FIRQはFirstIRQと呼ばれており、自分の場合
マイコン6809で初めて使いました。2000年以後
のマイコンでも用意されているのは、不思議な
印象があります。
割込みを使うには、IRQEN(FIRQEN)と
IRQCLR(FIRQCLR)を利用するのが基本
でした。
ADcU7026には、内蔵モジュールがあります。
ヘッダファイルから抽出してみると、以下。
- SWI_BIT
- RTOS_TIMER_BIT(timer0)
- GP_TIMER_BIT(timer1)
- WAKEUP_TIMER_BIT(timer2)
- WATCHDOG_TIMER_BIT(timer3)
- FLASHCON_BIT
- ADC_BIT
- PLL_LOCK_BIT
- SM_SLAVE_BIT(IIC bus Slave)
- SM_MASTER0_BIT(IIC0 bus Master)
- SM_MASTER1_BIT(IIC0 bus Master)
- SPI_SLAVE_BIT
- SPI_MASTER_BIT
- UART_BIT
- XIRQ0_BIT
- MONITOR_BIT
- PSM_BIT
- XIRQ1_BIT
- PLA_IRQ0_BIT
- PLA_IRQ1_BIT
- SPM4_IO_BIT
- SPM5_IO_BIT
- PWM_BIT
割込みで使いたい内蔵モジュールがあるとき
IRQENの該当ビットをセットします。
該当の割込みが発生した場合、IRQSTAの該当ビット
がセットされるので、唯一の割込み対応ルーチン内
にて、どの割込みが発生したのかを判定します。
ADcU7026のファームウエア開発環境では、割込み
関連の関数は、IRQ_Handlerにまとめられています。
該当モジュールの割込みフラグは、IRQ_Handler
関数の内部でクリアします。
PLL
PLLに関係するブロック図は、以下。
PLLで、外付け水晶の周波数32.768kHzを逓倍して
次の周波数を生成できます。
- 41.78MHz
- 20.89MHz
- 10.44MHz
- 5.22MHz
- 2.61MHz
- 1.31MHz
- 653kHz
- 326kHz
HCLKをCOREに供給する前に、プリスケーラが存在
しているので、PLLが生成した41.78MHzをCD値変更
で、上のリストにある周波数に変えられます。
外付け水晶の周波数32.768kHzを利用するか、内蔵
の発振器を利用するのかを指定できます。
POWCON、PLLCONレジスタにより、これらの設定を
変更できます。
POWCON、PLLCONのパラメータ設定には手順があり
これをスタートアップルーチンの中で指定できる
ようにして、ユーザーの負担を軽減するよう開発
環境が設定されています。
startup.sを選択して、Configuration Wizardの
チェックをいれると、アセンブリ言語で次コード
が作成されます。
// <e> PLL Setup
// <o1.0..2> CD: CPU Clock Divider
// <0-7>
// <i> CD Value Selection
// <i> Clock Divider = 2^CD
// <o1.3> FINT: Fast Interrupt
// <0-1>
// <i> Switches to CD0 for FIQ
// </e>
PLL_SETUP EQU 1
PLLCFG_Val EQU 0x00000001
// Setup PLL
IF (PLL_SETUP != 0)
LDR R0, =MMR_BASE
MOV R1, #0x01
STR R1, [R0,#POWKEY1_OFFSET]
MOV R1, #PLLCFG_Val
STR R1, [R0,#POWCON_OFFSET]
MOV R1, #0xF4
STR R1, [R0,#POWKEY2_OFFSET]
ENDIF ; PLL_SETUP
POWCONのデフォルト値は、0x03でシステムクロックに
5.22MHzを利用します。(電源を入れたとき、リセット
したとき、5.22MHzが選択されます。)
main関数内部で、設定を変更するには
次のステートメントを記述します。
- PLLKEY1に 0xAA 設定
- PLLCON にパラメータ設定
- PLLKEY2に 0x55 設定
- POWKEY1に 0x01 設定
- POWCON にパラメータ設定
- POWKEY2に 0xF4 設定
PLLCONについては、スタートアップルーチンで指定
しているので、POWCONの値を設定するルーチンを
付加して、システムクロックを変更します。
目次
前
次