組み込みソフトウェア工学 - Signal processing ... · printf("hello, world¥n"); } ......

31
組み込みソフトウェア工学 第9回 プログラムのROM化,LCD・セン サー用関数の仕様

Transcript of 組み込みソフトウェア工学 - Signal processing ... · printf("hello, world¥n"); } ......

組み込みソフトウェア工学

第9回 プログラムのROM化,LCD・センサー用関数の仕様

本日の内容

プログラムのROM化

ROM化について

ROMのフォーマット

ROMの書き込み

LED・SW の使い方

LCD・センサー用関数の仕様

実習

プログラムのROM化

エディタ ソース

ファイル ソース

ファイル ソース

ファイル

コンパイラ

リンカ

オブジェクト

ファイル

ライブラリ

書込用

ファイル

変換

プログラム

エラー

リスト

エラー

リスト

実行モジュール

(ロードモジュール)

インテルHex

モトローラS

など

書き込みツール ターゲットシステム

ターゲットシステムのROMへ書き込む

プログラムのROM化

• コンパイル

– ソースプログラムをCPU(MPU)の命令に翻訳して,機械語(オブジェクトプログラム)を生成する

– コンパイラはプログラムの各部分を属性により,コード部,データ部,スタック部などに分ける

– コンパイルした時,命令のアドレスは仮のアドレスが振られている

• リンカ

–複数のオブジェクトやライブラリを結合して,実行モジュールを生成する

–各モジュールにおける命令のアドレスはリンク作業によりアドレスの調整が行われ,アドレスの再配置(リロケーション)が行われる

プログラムのROM化

#include <stdio.h>

main()

{

printf("hello, world¥n");

}

CGROUP GROUP TEXT

DGROUP GROUP DATA,BSS

TEXT CSEG

0000

0000 DATA DSEG

0000

0000 BSS DSEG

0000

0000

0000 TEXT CSEG

0000 ; #include <stdio.h>

0000 ; main()

0000

0000 main_::

0000 ; {

0000 ; printf("hello, world¥n");

0000 B80000 MOV AX,Z1

0003 50 PUSH AX

0004 E80000 CALL printf_

0007 83C402 ADD SP,2

000A ; }

000A C3 RET

000B

000B

000B DATA DSEG

0000 EVEN

0000 68 Z1: DB 104 (h)

0001 65 DB 101 (e)

0002 6C DB 108 (l)

0003 6C DB 108 (l)

0004 6F DB 111 (o)

0005 2C DB 44 (,)

0006 20 DB 32 ( )

0007 77 DB 119 (w)

0008 6F DB 111 (o)

0009 72 DB 114 (r)

000A 6C DB 108 (l)

000B 64 DB 100 (d)

000C 0A DB 10 (¥n)

000D 00 DB 0

000E

000E EXTRN printf_

000E

000E

000E ;core used: 1123/35648

000E

000E END

Z1のアドレスは0000.つまりまだ確定してない

printfのアドレスは0000.つまりまだ確定してない リンクによりアドレスを再配置(確定)させる

プログラムのROM化

00000000 : 4D 5A C1 01 02 00 00 00 20 00 01 00 FF FF 00 00 : MZ...... ....... 00000010 : 00 00 65 7D 00 00 00 00 1E 00 00 00 01 00 00 00 : ..e}............ 00000020 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................ 000001F0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................ 00000200 : B8 96 03 50 E8 F9 FF 83 C4 02 C3 51 52 56 8B C8 : ...P顋.ζ..QRV曲 00000210 : BA 20 00 EB 13 8B DA D1 E3 83 BF 00 00 00 74 08 : . ...芹.繝....t. 00000220 : 8B DA D1 E3 FF 97 00 00 4A 83 FA 00 7D E7 BE 00 : 芹......J・.}鄒. 00000380 : C6 8D 5E 80 8B 0E 32 00 E8 75 FE E8 7D FE 5F 5E : .洪...2.鑾.閘._^ 00000390 : 5A 59 8B E5 5D C3 68 65 6C 6C 6F 2C 20 77 6F 72 : ZY句].hello, wor 000003A0 : 6C 64 0A 00 6F 75 74 20 6F 66 20 6D 65 6D 6F 72 : ld..out of memor 000003B0 : 79 00 00 00 72 00 77 00 77 00 77 2B 62 00 77 62 : y...r.w.w.w+b.wb 000003C0 : 00 : .

printf のアドレスを呼び出し

main 関数

このデータをターゲットシステムに書き込む

どうやって書き込むのか?

アドレスがリンクにより確定している

プログラムのROM化

• ROM化とは

–一般的に組み込みシステムを動作させるプログラムはファームウェアと呼ばれる

– ファームウェアは最終的に ROM 書かれる

– ROM にデータを書く(ROM化)には 専用の装置(ROM ライタ)を用いる

– ROM ライタは指定したROMのアドレスに指定データを書き込む作業を行う

–指定データに指定アドレスを定義しているファイルは特殊な形式となっており,大体2種類に分類される • モトローラSフォーマット形式

• インテルHEXフォーマット形式

プログラムのROM化

code

data

stack

ロードモジュール

code

data

ROM

code

data

stack

stackには実体がない

ロードモジュールをROMに書き込む

命令コード

初期値のある変数

data’

copy

初期値のない変数

スタック領域

実行

高速化のためメモリにコピーして実行する場合もある

RAM

実行した段階で実体が生成される

ROMに書かれたファームウェア

プログラムのROM化

モトローラSフォーマット

– 複数のレコード形式

– ファイルはプレーンテキスト

– 1レコード 1行

S0 0E 0000 73616D706C652020202020 CF S2 14 000000 92ED73CEE943A2EFB87E3B89FEB2D26D 85 S2 14 000010 965AC3175EF077E199BBE27692E95088 6C S2 14 000020 83DD62C6B4CA5308E78180CDF48728E8 2A S2 14 000030 B16B70761456AA139CE4D64EEC32695A 0D S2 14 000040 BA394E06E75A2BEEEF39E5F384CF66EA 67 S2 14 000050 76BB9E91D6D9C7C75B16EEFC0483AFE6 87 S2 14 000060 FFA84075CA1AB10A985071E4F6B215DA BC S2 14 000070 AEF35550ECA157649FFA31682202A995 59 S2 14 000080 1CD23EFDA5336DC2AA6B2D869257BC22 AC S2 14 000090 21BA9D9B9DD5E2523038A77A8ED7DFCF 06 S2 14 0000A0 D7605385BFCCE77FEC351FC2A0E7E329 B6 S2 14 0000B0 97B97F5A339EEEF8D677581B8F2BD9FD 0B S2 14 0000C0 FAFA84F6610EA8AA2753518167891257 57 S2 14 0000D0 D8980275F42305C0595F4D316F262085 E8 S2 14 0000E0 4B47DB36D32137A92370CBA93066D214 11 S2 14 0000F0 ABFE2FD4298DAE1180998DA574EF3BD1 20 S8 04 000000 FB

レコード形式 バイト数 ロードアドレス

データ

チェックサム

S1 : 2バイトアドレス

S2 : 3バイトアドレス

S3 : 4バイトアドレス

S8 : 終了レコード

書き込み対象となる先頭アドレス

バイトカウントおよびデータの加算した結果の1の補数

スペースを入れて区切りを分かり易くしていますが,本来はスペースはありません

プログラムのROM化

インテル・HEXフォーマット

– 複数のレコード形式

– ファイルはプレーンテキスト

– 1レコード 1行

:10 0000 00 92ED73CEE943A2EFB87E3B89FEB2D26D 8A :10 0010 00 965AC3175EF077E199BBE27692E95088 71 :10 0020 00 83DD62C6B4CA5308E78180CDF48728E8 2F :10 0030 00 B16B70761456AA139CE4D64EEC32695A 12 :10 0040 00 BA394E06E75A2BEEEF39E5F384CF66EA 6C :10 0050 00 76BB9E91D6D9C7C75B16EEFC0483AFE6 8C :10 0060 00 FFA84075CA1AB10A985071E4F6B215DA C1 :10 0070 00 AEF35550ECA157649FFA31682202A995 5E :10 0080 00 1CD23EFDA5336DC2AA6B2D869257BC22 B1 :10 0090 00 21BA9D9B9DD5E2523038A77A8ED7DFCF 0B :10 00A0 00 D7605385BFCCE77FEC351FC2A0E7E329 BB :10 00B0 00 97B97F5A339EEEF8D677581B8F2BD9FD 10 :10 00C0 00 FAFA84F6610EA8AA2753518167891257 5C :10 00D0 00 D8980275F42305C0595F4D316F262085 ED :10 00E0 00 4B47DB36D32137A92370CBA93066D214 16 :10 00F0 00 ABFE2FD4298DAE1180998DA574EF3BD1 25 :00 0000 01 FF

バイト数 レコード形式 ロードアドレス

データ

チェックサム

00 : データ

01 : 終了

02 : 拡張

03 : エントリアドレス

書き込み対象となる先頭アドレス

バイトカウントからデータまでの加算した結果の2の補数

スペースを入れて区切りを分かり易くしていますが,本来はスペースはありません

レコードの開始

プログラムのROM化

• ROMデータの書き込み方法(1)

– ROMそのものにデータを書き込む

1つのROMに書き込む

(大体が実験用) 多数のROMに書き込む

(量産用途向け)

ROM

ターゲット ROMを搭載

プログラムのROM化

• ROMデータの書き込み方法(2)

–通信を通じてデータを書き込む

シリアル通信 など

CPU

ROM

RAM 周辺

内部に ROM が搭載されている

このROMにコードとデータを直接書き込む

本日の内容

プログラムのROM化

ROM化について

ROMのフォーマット

ROMの書き込み

LED・SW の使い方

LCD・センサー用関数の仕様

実習

SW と共用の LED

通常のLED

RB0 - 7

RD0 - 5 RD0 - 5 RD0 - 5

LED と PORT の関係

7 6 5 4 3 2 1 0

PORTB

7 6 5 4 3 2 1 0

PORTD

LED #1 #2 #3 #4 #5 #6 #7

LED #8 #9 #10 #11 #12 #13

bit 7 ~ 1までが LED

で使われている

なお,SW1~7と共用

bit5 ~ 0 が LED で使われている

LED の点灯

LDE は port D に接続

port D の初期化

/* Set Port D config */

TRISD = 0xC0; // bit 0-5 OUT, bit6-7 IN

port D に出力

PORTD = <DATA> & 0x3F; // output to bit 0-5

但し port D は bit 0 ~ 5 までの 6bit が LED の出力に対応しており,bit 6,7は対応していないので注意

SW の使い方

RC5

RBx

RCx

・RB1~7 および RC0~1 を in に設定

・SWx を押すと RxDATA に SW の状況が入る

実習用ボードには SW が9個存在する

SW 1~7

SW 8,9

Pull-UP 抵抗

入力した情報が 1 の時: SW OFF

入力した情報が 0 の時: SW ON

SW の使い方

SW は port B に接続,一部 port C も使用

port B および port C の初期化

/* Set Port B*/

ANSELH = 0x00; // AN Disable (RB5-RB0)

WPUB = 0x00; // Pull-up disable

INTCON = 0x00; // Intrauppt disable

IOCB = 0x00; // Intrauppt charge disable

CCP1CON = 0x00;

CM2CON1 = 0x02;

OPTION_REG = 0xFF; // Pull-up disable

TRISB = 0xFF; // IN

/* Set Port C */

RCSTA = 0x00; // Serial disable (RC7-6)

SSPCON = 0x00; // Serial disable (RC5-4)

TRISC = 0x03; // OUT(2-7), IN(0,1)

PORTC = 0x00; // Low

port B の初期化

(入力設定)

port C の初期化

(入力および出力設定)

SW の使い方

スイッチの状態の読み込み

<data> = PORTB & 0xFE;

<data> = PORTC & 0x03;

port B は bit 1~7

が SW で使われる

port C は bit 0~1

が SW で使われる

各SWの状態を調べるには

例えば SW4 の状態を調べたい

SW4 は port B の bit 4 である

このbitが 1 のとき,SW は OFF,0 のとき,SW は ON

よって bit 4 だけが 1 か 0 かを判断すれば良い

if( (PORTB & 0x10) == 0 ) { /* SW4 is ON */

7 6 5 4 3 2 1 0

SW #7 #6 #5 #4 #3 #2 #1

bit 4 以外は 0 に固定してしまう

bit 4 が 0 のとき,SWは

ON となる

LED をビット毎に制御するには

例えば 6 つある LED の 3 つ目を光らせたい!

この LED の 3 つ目は port D の bit 2 である

よって bit 2 だけを 1 にすればよい

その他の bit はそのまま変更しないようにする

LED = PORTD | 0x04; // bit 2 is 1, other is condition of Port D

PORTD = LED ;

7 6 5 4 3 2 1 0

LED --- --- #8 #9 #10 #11 #12 #13

bit 2 は 1 にして,それ以外は前のままとする

OR 演算子

LED に対して出力する

本日の内容

プログラムのROM化

ROM化について

ROMのフォーマット

ROMの書き込み

LED・SW の使い方

LCD・センサー用関数の仕様

実習

情報工学セミナー 第4回 24

LCD ・センサー 用関数

lcd_disp.c

LCD 表示関数用ファイル

lcd_disp.h

LCD 表示関数用ヘッダファイル

sensor.c

timer,ロータリーエンコーダ関数用ファイル

sensor.h timer,ロータリーエンコーダ関数用ヘッダファイル

情報工学セミナー 第4回 25

LCD 表示用関数 (lcd_disp)

void init_lcd( void ) 液晶表示器を初期化する

void disp_number( int number, int x, int y) 液晶の指定場所に数値を1文字表示させる

void write_lcd( int code, int rs ) 液晶に rs 分の文字データを表示させる

void locate( int x, int y) 液晶のカーソル位置を指定する

void write_char( char c ) 液晶に1文字表示させる

void write_str( char *s ) 液晶に文字列を表示させる

LCD の表示位置

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

0

1

2

3

X

Y

情報工学セミナー 第4回 27

センサー用関数 (sensor)

void sensor_init( void ) 各種センサーの状態の初期化

char check_Rotary( void ) ロータリーエンコーダの回転状況を読み取る

return : 回転状態の読み取り 0 : not move

1 : 時計方向に1クリック動く

2 : 反時計方向に1クリック動く

short check_Tempture( void ) 温度センサーの状態を読み取る

return : 温度(℃)

void timer0_init( void ) timer0 の初期化

Rotary Encoder の使い方

rot_dir = check_Rotary();

switch( rot_dir ) {

case CW:

<処理>

break;

case CCW:

<処理>

break;

default:

break;

}

Rotary エンコーダの状態の読み取り

rot_dir に状態が入っている

時計回りで1つ動いたときの処理を記述

反時計回りで1つ動いたときの処理を記述

特に動きが無い時は抜ける

timer0 を使った割り込み処理

static void interrupt rtcc_isr( void ) {

T0IF = 0; /* Timer Interrupt Flag CLS */

<割り込み処理の記述>

}

void main ( void ) {

:

timer0_init(); /* Timer0 Initilize */

:

/* Timer0 Interrupt */

T0IE = 1; /* Enable Interrupt */

GIE = 1; /* Enable Global Interrupt */

}

割り込み処理の記述

タイマー0 を動作させる

timer0 による割り込み処理を許可

全体の割り込みを許可

Timer による割り込みについて

16F887 にはタイマーが全部で3つある

Timer0 , Timer1 , Timer2

割り込み用許可のレジスタ : INTCON

16F887 仕様書 p.31~p.32 参照

T0IE : Timer0 Overflow Interrupt Flag

TMR1IE : Timer1 Overflow Interrupt Enable bit

TMR2IE : Timer2 to PR2 Match Interrupt Enable bit

TME1IF : Timer1 Overflow Interrupt Flag bit

TME2IF : Timer2 to PR2 Interrupt Flag bit

本日の内容・まとめ

プログラムのROM化

ROM化について

ROMのフォーマット

ROMの書き込み

LED・SW の使い方

LCD・センサー用関数の仕様

実習

実機の貸し出しについて

木曜日のみ講義後もマイコン機器とプログラム書き込み用ツールを当日限りで使うことを前提に貸し出します.

講義後に貸し出しを受けたいグループは申し出て下さい.

グループ番号と貸し出し時間を記載してください.なお貸し出し時間は18時までとします.

貸し出しは木曜日当日のみとなります.必ず返却して下さい.

もし木村が居ない場合,711室の研究生らに返却をして下さい.