ATmega16のUMK

ネタバレ :この記事では、ノスタルジックな涙を絞りません。



(Arduinoの後の)より一般的なマイクロコントローラーをよりよく知ることをそれほど前に決定しなかった

特にATmegaマイクロコントローラーでは、MKについて読んでいるだけで、

「LEDを点滅させる」エミュレータでコードを実行します-これはどういうわけか正しくありません。 したがって、私は決めた

いくつか-役に立たない-プロジェクトを行い、すべてに対処する

すでに道に沿って。 マイクロプロセッサシステムに関する実験室の作業が思い浮かびました

そして、これらの作品が実施されたトレーニングスタンド-いわゆる教育用マイクロプロセッサ

キット(UMK)。これを単に「ウムカ」と呼びます。



UMKについて



そのため、詳細を確認しない場合(詳細を確認する場合は、以下のリンクをクリックしてください)、

UmkaはK580IK80Aマイクロプロセッサをベースにしたマイクロコンピュータで、80年代に製造されました

前世紀(私は幸運にも、それほど遠くない2009年に彼と仕事をした)

そのような重い箱です。 Umokの歴史に関する詳細情報

その他は以下の2番目のリンクにあります。 これは見た目です。





(下の最初のリンクから無邪気に撮られた写真、より多くの写真-同じから

リンク)



データバスとアドレスの表示、プロセッサステータスレジスタの表示、

メモリセルと入力データの内容を表示するディスプレイ、入力ボタン

データ。 左側の2列のボタンは、「ウムカ」に縫い付けられたいわゆるディレクティブです。

プログラムの監視-それらは私のプロジェクトの目標になりました(ボタンではなくディレクティブ)。

ディレクティブについて簡単に説明します。 ここには特別なものはありません。

「P」-メモリセルの内容を表示します。セルのアドレスを入力し、そこにあるものを確認します

必要に応じて嘘-別の値を書き込みます。

「WG」-レジスターの内容の表示:セルの内容の表示に似ています。 私の

このディレクティブの「バージョン」はありません。特に必要ありません。

ATmega RAM、汎用レジスター、周辺レジスターは

1つのアドレス空間、およびそれらは次の方法でアクセスできると想定されます

ディレクティブ「P」。

「KS」-データ配列のチェックサムの計算:配列の先頭のアドレスを入力し、

配列の終了アドレス、配列のセルの内容の合計が表示されます。

「ZK」-メモリアレイに定数を入力します。開始アドレスを入力し、終了アドレスを入力します

配列アドレス、変数を入力-配列セルはこの変数で満たされます。

「PM」-メモリアレイの移動:移動したアレイの開始アドレスを入力します

メモリ、終了アドレスを入力、配列の開始アドレスを入力-配列

入力されたロケーションアドレスから始まるメモリ領域に移動します。

ディレクティブ「ST」-ユーザープログラムの実行-私は見逃しました。それについては以下で詳しく説明します。

ボタン「VP」-ディレクティブの実装、ボタン「_」は入力時に変数を分離し、「SB」-ボタン

リセットします。 ディレクティブの導入と実装に関する詳細-ここ: ワークショップ



sfrolov.livejournal.com/136290.html-UMKの写真、思い出、印象。

www.computer-museum.ru/histussr/umk_sorucom_2011.htm-少し歴史。



計画されたもの



私のプロジェクトの目標は、これらの指令に準拠できるデバイスを作成することでした。

「Umka」の一種のライトバージョンに関する情報を表示します(まあ、とても、とてもライトです)。

プロジェクトで使用されたもの:

1.マイクロコントローラーATmega16。 プログラムは、AVRStudioのアセンブラーで記述されています。

2.値を入力するためのマトリックスキーボード。 キーボードを操作するためのコードを見つけました

ここで (著者に感謝)、アセンブラーで書き直します。 RAMはATmega16であるため

$ 045Fに制限され、最後の3桁が入力されます。 ちなみに、データ/アドレス

16進形式で入力および出力します。

3. HD44780コントローラーの16x2 LCDディスプレイ。 表示を理解するには、これら

2つの記事- あちこち (著者のおかげ)、データシートは表示を正しく初期化するのに役立ちました。

4.ディレクティブ用のシンプルなボタン。 別のボタンも追加されました-「Enter」(オン

矢印付きの写真):住所またはデータの各桁の入力を確認するために必要

-マトリックスキーボードの接触の跳ね返りに対する一種の保護(それなしではまったく不可能です

分配されたが、彼らが言うように、巧妙な思考が後に来る)。



結果は何ですか



計画されていたすべてを達成することができました。表示して変更できます

RAMおよびMKレジスタの内容、セルの配列に定数を書き込む、カウント

配列のチェックサム、セルの配列を移動します(エンターテイメント*皮肉*)。

アドレス$ 0440(およそ)のどこかに配列を書き込む/移動すると、自然な

スタック領域へのカオス。 あなたは、最初の実験室の仕事の6つのポイントを実行することができます

上記のリンクでワークショップ。

見つかった情報から判断すると、Umkaに接続されているMonitorプログラムは1KBを使用します。

タスクの1つは、プログラムを1 KBにすることでした。

在庫)、しかしLCDディスプレイおよびコードをより有益にしたいという願望のため

ほぼ倍増しました。

本物の「ウムカ」(プロフェッショナル版)を使用すると、プログラムを

アセンブラマイクロプロセッサK580IK80A、対応するコマンドのコードをメモリに書き込む、

その後、ステップごとまたは周期的に実行します。 どうだったか分からない

Umkaで実装されており、解決策は私には明らかではないようですので、そのようなオプションは

プロジェクトはありません(ただし、初心者には十分な指示がありました)、喜んで受け入れます

これを実装するための提案。 このため、私は愛情を込めて、出来上がったデバイスに「Foolish」というニックネームを付けました。







これはコードです
.include "m16def.inc"

.device ATmega16

.def count = r18; r18-カウンター

.defモード= r19; r19-モード標識

.def buf = r25; 値を入力する

.def rLCD = r22; LCDでの作業用

.def rKey = r20; キーボードとトリビアの値



; LCDコマンド

.equ off = 0b00001000;オフ

.equ clrSc = 0b00000001;クリア

.equ config = 0b00111000; 8ビット、2行

.equ incr = 0b00000110; addr +(アドレスの増加、静的画面)

.equ on = 0b00001100; on

.equ right = 0b00010100; 右シフト

.equ down = 0b11000000; 二行目に行く

.equ up = 0b10000000; 最初の行に

.equカーソル= 0b00001111; 点滅カーソル

.equ noCursor = 0b00001100

.equ left = 0b00010000; 左に



; LCDデータ(ポートD)

.equ _dp = DDRD

.equ _dpo = PORTD

.equ _dpi = PIND



; LCDコントロール(ポートC)

.equ _cp = DDRC

.equ _cpo = PORTC

.equ rs = 0

.equ rw = 1

.equ e = 7



; キーボード(ポートA)

.equ _mp = DDRA

.equ _mpi = PINA

.equ _mpo = PORTA



; ディレクティブ(ポートB)

.equ BUT = PINB

.equ BUTddr = DDRB

.equ BUTp = PORTB

.equ P = 0; Pボタン(表示/メモリモードの変更)

.equ quit = 1; 出る

.equ exe = 2; VIボタン(実行)

.equ enter = 3; 入力ボタン

.equ space = 4; _ボタン

.equ CF = 5; ZKボタン(一定の塗りつぶし)

.equ CS = 6; COPボタン(チェックサム)

.equ AM = 7; PMボタン(アレイを移動)

; フラグT-データ入力モード



; ========================マトリックスキーボードをポーリングするためのマクロ====================

.macroマトリックス

rcall _exit

ldi rKey、0

ldi r16,0xff; r16のローディングユニット

cbi _mpo、@ 0; 列に対応するビットをクリアします

out _mpo、r16; portdのユニット

r16では、_mpi; ポートDデータレジスタの読み取り

cpi r16、@ 1

ブレック・アイン

cpi r16、@ 2

ブレック・ツヴァイ

cpi r16、@ 3

ブレック・ドライ

cpi r16、@ 4

ブレック・ヴィアー

sbi _mpo、@ 0; 列に対応するビットを設定します(初期状態に戻ります)

rjmp @ 9; 列のボタンがどれも押されていない場合、

; 次にラベルに移動します-次の列のパラメーターを含むマクロ、または調査の開始時



アイン:

ldi rKey、@ 5; 押されたボタンの値をrKeyにロードする

ldi rLCD、@ 5; 表示に同じ値をロードする

rcall _BF

rcall _charInput

sbi _mpo、@ 0; 列に対応するビットを設定します(初期状態に戻ります)

rjmp _check; ラベルを見る



ツヴァイ:

ldi rKey、@ 6

ldi rLCD、@ 6

rcall _BF

rcall _charInput

sbi _mpo、@ 0

rjmp _check



ドライ:

ldi rKey、@ 7

ldi rLCD、@ 7

rcall _BF

rcall _charInput

sbi _mpo、@ 0

rjmp _check



vier:

ldi rKey、@ 8

LDI rLCD、@ 8

rcall _BF

rcall _charInput

sbi _mpo、@ 0

rjmp _check

.endmacro



.cseg



.org 0



; スタック

ldi r16、低(RAMEND)

アウトSPL、r16

ldi r16、高(RAMEND)

SPH、r16から



sbi _cp、0; rs

sbi _cp、1; rw

sbi _cp、7; e



; ポートの初期化

ldi r16、0b00001111

out _mp、r16; DDRA-入力

ldi r16、0b11110000

out _mpo、r16; サスペンダー付き



ldi r16,0x00

out BUTddr、r16; DDRB-入力

ldi r16,0xff

out BUTp、r16; サスペンダー付き



; ディスプレイの初期化

rcall altInit



; ==================================メインループ============== =================

行く:

rcall _resetLCD

ldi xl、0x00

ldi xh、0x00

ldi yl、0x00

ldi yh、0x00

ldi zl、0x00

ldi zh、0x00

clt

clc

clh

clrモード

clr buf

LDIカウント、1



; ===========================動作モードの確認===================== =========

modeCheck:

sbisしかし、P; Pモード

rjmp _P

sbis BUT、CF; ZKモード

rjmp _setConst

sbis BUT、CS; 警官モード

rjmp _setSum

sbis BUT、AM; PMモード

rjmp _setArray

rjmp modeCheck



_setConst:

sbrモード、1; ZKモードの機能を設定する

; 表示モード情報

rcall _clear

rcall _labelWrite; 書きます

rcall _labelSpace; _

rcall _labelConst; const

rcall _point;。

rcall _down

rcall _labelAddr; 住所

rcall _labelOne; 1

rcall _colon;:

rcall _labelZero; 0

rcall _cursor

rjmpスキャン



_setSum:

sbrモード、5; COPの符号を設定する

rcall _clear

rcall _labelSum; チェックサム

rcall _down

rcall _labelAddr; 住所

rcall _labelOne; 1

rcall _colon;:

rcall _labelZero; 0

rcall _cursor

rjmpスキャン



_setArray:

sbrモード、9; PMモードインジケーターの設定

rcall _clear

rcall _mArray

rcall _down

rcall _labelAddr

rcall _labelOne

rcall _colon

rcall _labelZero

rcall _cursor

rjmpスキャン



_check:; 数字を入力した後-ここに

sbrcモード、0; チェックモード

rjmp _const; ZK、KS、またはPMの場合、ここに

rjmp _view



_P:; Pモード

rcall _clear

rcall _browse

rcall _labelSpace

rcall _labelZero

rcall _cursor



スキャン:; マトリックスキーボードのポーリング

rcall _exit

rcall _cursor

マトリックス0、0b11101110、0b11011110、0b10111110、0b01111110、3、7、11、15、next



次:

マトリックス1、0b11101101、0b11011101、0b10111101、0b01111101、2、6、10、14、next1



next1:

マトリックス2、0b11101011、0b11011011、0b10111011、0b01111011、1、5、9、13、next2



next2:

マトリックス3、0b11100111、0b11010111、0b10110111、0b01110111、0、4、8、12、スキャン



rjmpスキャン

; ================================================== ==========================



; ===========================入力ボタンが押されるのを待つ================== =

_view:

brts _input; Tフラグが設定されている場合は入力に進みます(データ入力モード)

rcall _exit

sbic BUT、入力; 入力ボタンが押されていない場合、

rjmp _view; 次に、サイクルを閉じて、ボタンがEXを押す、リセットする、または入力するのを待ちます

cpiカウント、1; カウンター値の比較:1の場合

breq one; その後、最初の数字が入力されます

cpiカウント、2; 2の場合

breq 2; 次に、2番目のものが導入されます

cpiカウント、3; 3の場合

breq 3; その後、最後の桁が入力されます

rjmp _view



; 住所の最初の桁を入力してください

一つ:

mov xh、rKey

株式会社カウント

rjmpスキャン; 調査マットへの移行。 クラブ。



; 住所の2桁目を入力してください

2:

mov xl、rKey

スワップxl

株式会社カウント

rjmpスキャン



; 住所の3桁目を入力してください

3:

rcall _noCursor; カーソルは必要ありません

xl、rKeyを追加

株式会社カウント

rjmp finish; 3桁目を入力したら、最後に進みます

; ================================================= ===================================



; ===================================入力モード============= =====================

_input:

rcall _exit

sbic BUT、入力; 入力ボタンが押された場合、カウンター比較にジャンプします

rjmp _input

cpiカウント、1; カウンターが1の場合、最初の桁が入力されます

ブレクファースト

cpiカウント、2; 2の場合、2番目

ブレック秒

rjmp _input



最初:; 最初の数字を入力してください

mov buf、rKey

スワップバフ

株式会社カウント

rjmpスキャン



2番目: 2桁目を入力

rcall _noCursor

buf、rKeyを追加します

株式会社カウント

rjmp _waitFor

; ================================================= ==================================



; ======================== 3桁目を入力してから待つ==================== =

終了:; 3桁目を入力してからここに行きます

brtsリンク; Tフラグが設定されている場合、これはデータ入力モードです-スキャンに進みます

rcall _exit

sbisしかし、exe; EXITボタン

rjmpビュー。 SELを押すと表示されます。

sbic BUT、スペース。 _ボタン

rjmp仕上げ

ldi count、1; カウンターをリセットする

セット; ステータスレジスタにTフラグを設定します

; 最初の行「WRITE DATA」に印刷します

rcall _clear

rcall _labelWrite

rcall _labelSpace

rcall _labelData

; 二番目に行きます

rcall _down

; カーソルを設定

rcall _cursor

rjmp仕上げ

リンク:

rjmpスキャン

; ================================================== =============================



; ================セルの内容を表示する(EXACTボタン->ここをクリックした後)

表示:

; 碑文「BROWSE XXXX」を表示します

rcall _clear

rcall _browse; ブローゼ

rcall _labelSpace; _

mov rLCD、xh; 最初のXX

rcall _charFromMemory

mov rLCD、xl; 2番目のXX

rcall _charFromMemory

; メモリセルの内容を表示する

rcall _noCursor

rcall _down

ld rLCD、X +

rcall _charFromMemory

view1:

rcall _exit

LDIカウント、1

sbic BUT、スペース。 「_」ボタンが押された場合、アドレス1のセルに移動します

rjmp view1

rcall _delay1

rjmpビュー

; ================================================== =============================



; ==========================メモリ位置への値の書き込み==================== ===

入力:

st X、buf

clt; データ入力モードの完了時にTフラグをクリアします

rjmp go

; ================================================= ===================================



; ========== EXを押すのを待っています。 または、「_」を入力して続行================

_waitFor:; 2番目の数字(データ)を入力した後-ここ

sbrcモード、0

rjmp _WC

rcall _exit

sbisしかし、exe; EXを押すと、入力に移動します

rjmp入力

sbic BUT、スペース。 「_」が押された場合、

rjmp _waitFor; それから飛び越える

st X +、buf; 入力されたデータをメモリに書き込み、

ldi count、1; カウンターをリセットする

rcall _clear

rcall _labelWrite

rcall _labelSpace

rcall _labelData

rcall _down

rjmpスキャン



_WC:

rcall _exit

sbic but、exe

rjmp _WC

rjmp _execConst

; ================================================== ==============================



; =============================== ZKモード(定数で埋める)============= =====

_const:

brts to_input

rcall _exit

sbic BUT、入力; 入力ボタンが押されていない場合、

rjmp _const; 次に、サイクルを閉じて、ボタンがEXを押す、リセットする、または入力するのを待ちます

cpiカウント、1; カウンター値の比較:1の場合

breq _one; その後、最初の数字が入力されます

cpiカウント、2; 2の場合

breq _two; 次に、2番目のものが導入されます

cpiカウント、3; 3の場合

breq _three; その後、最後の桁が入力されます

rjmp _const; サイクルで

to_input:

rjmp _input



; 最初のアドレスの最初の数字を入力してください

_one:

sbrcモード、4; 2番目のビットが設定されている場合(3番目のアドレスを入力するサイン)、

rjmp _ad31; <-ここに移動

sbrcモード、1; r19の1番目のビットが設定されていない場合(2番目のアドレスを入力するサイン)、

rjmp inpConst1; それからスキップ

mov xh、rKey

株式会社カウント

rjmpスキャン

; 2番目のアドレスの最初の数字を入力する

inpConst1:

mov yh、rKey

株式会社カウント

rjmpスキャン



; 最初の住所の2桁目を入力してください

_two:

sbrcモード、4; 2番目のビットが設定されている場合(3番目のアドレスを入力するサイン)、

rjmp _ad32; <-ここに移動

sbrcモード、1; 1番目のビットがr19(2番目のアドレスを入力するサイン)に設定されている場合、

rjmp inpConts2; 次に、inpConst1に移動します

mov xl、rKey

スワップxl

株式会社カウント

rjmpスキャン

; 2番目のアドレスの2桁目を入力します

inpConts2:

mov yl、rKey

スワップイル

株式会社カウント

rjmpスキャン



; 最初の住所の3桁目を入力してください

_three:

sbrcモード、4; 2番目のビットが設定されている場合(3番目のアドレスを入力するサイン)、

rjmp _ad33; <-ここに移動

sbrcモード、1

rjmp inpConst3

rcall _noCursor

xl、rKeyを追加します。 rKey-> mlaのジュニアノートブックへ。 バイト調整 カップルX

株式会社カウント

rjmp constEnd; 3桁目を入力したら、constEndに移動します

; 2番目のアドレスの3桁目を入力してください

inpConst3:

rcall _noCursor

yl、rKeyを追加します

株式会社カウント

rjmp constEnd



constEnd:; 3桁目を入力してからここに行きます

brts _link; Tフラグが設定されている場合、これはデータ入力モードです-スキャンに進みます

sbrcモード、1; 2番目のアドレスを入力する記号が設定されている場合

rjmp _ad2; こっち

sbrcモード、2; 「KS」モードの符号が設定されている場合、

rjmp _ifCheckSum; こっち

sbrcモード、3; 「PM」モードの符号が設定されている場合、

rjmp _ifArray; こっち

rcall _exit

sbic BUT、スペース。 「_」ボタンが押された場合、

rjmp constEnd; それから飛び越える

ldi count、1; カウンターをリセットする

sbrモード、3; r19で0b00000011(RFに2番目のアドレスを入力するサイン)

; スクリーンの改良

; address2

rcall _down

rcall _labelAddr

rcall _labelTwo

rcall _colon

rcall _labelZero

rcall _labelSpace

rcall _labelSpace

rcall _labelSpace

rcall _left

rcall _left

rcall _left

rjmpスキャン



_ad2:; 2番目の住所を入力してからここに行きます

sbrcモード、2; 記号「」が設定されている場合は、次に進みます

rjmp _toCheckSum

sbrcモード、3; 「PM」記号が設定されている場合、

rjmp _toArray; <-ここ

rcall _exit

sbic BUT、スペース。 「_」ボタンが押された場合、

rjmp _ad2; それからスキップ

ldi count、1; カウンターをリセットする

セット; データ入力の符号を設定します

; スクリーンの改良

; const

rcall _down

rcall _labelConst

rcall _colon

rcall _labelSpace

rcall _labelSpace

rcall _labelSpace

rcall _labelSpace

rcall _labelSpace

rcall _labelSpace

rcall _labelSpace

rcall _left

rcall _left

rcall _left

rcall _left

rcall _left

rcall _left

rcall _left

rjmp constEnd; ->ループへ



_link:

rjmpスキャン



_ifCheckSum:; モードの2番目のビットが設定されている場合、「ZK」から「KS」に分岐します。

sbic BUT、スペース

rjmp _ifCheckSum

LDIカウント、1

; 画面コンテンツの改良:

; 住所2

rcall _down

rcall _labelAddr

rcall _labelTwo

rcall _colon

rcall _labelZero

rcall _labelSpace

rcall _labelSpace

rcall _labelSpace

rcall _left

rcall _left

rcall _left

sbrモード、7; 2番目のアドレス「KS」を入力するサイン

rjmpスキャン



_toCheckSum:; 「COP」を実行する

rcall _exit

sbic BUT、exe; 「OFF」を押すと、「COP」の実行に進みます

rjmp _toCheckSum

ldi rKey、0x00; 使用済みレジスタを事前リセットする

ldi buf、0x00

rjmp _SUM



_ifArray:; 「KS」から「PM」への分岐

sbic BUT、スペース

rjmp _ifArray

LDIカウント、1

; スクリーンの改良

; address2

rcall _down

rcall _labelAddr

rcall _labelTwo

rcall _colon

rcall _labelZero

rcall _labelSpace

rcall _labelSpace

rcall _labelSpace

rcall _left

rcall _left

rcall _left

sbrモード、11

rjmpスキャン



_toArray:; 2番目のアドレスを入力した後の遷移

LDIカウント、1

sbrモード、27; 0b00011011-> r19-3番目のアドレスを入力するサイン

rcall _exit

sbic BUT、スペース

rjmp _toArray

; スクリーンの改良

; 住所3

rcall _down

rcall _labelAddr

rcall _labelThree

rcall _colon

rcall _labelZero

rcall _labelSpace

rcall _labelSpace

rcall _labelSpace

rcall _left

rcall _left

rcall _left

rjmpスキャン



; 3番目のアドレスの最初の数字(PM)

_ad31:

mov zh、rKey

株式会社カウント

rjmpスキャン



; 最初のアドレスの2桁目

_ad32:

mov zl、rKey

スワップzl

株式会社カウント

rjmpスキャン



; 3番目のアドレスの3桁目

_ad33:

rcall _noCursor

zl、rKeyを追加します

株式会社カウント

rjmp _arrayEnd



; 3番目のアドレスを入力した後、VIが押されるのを待つ

_arrayEnd:

rcall _exit

sbic but、exe

rjmp _arrayEnd

ldi buf、0x00; 事前ゼロ化buf

rjmp _execArray



; ================================の履行================= =================

_execConst:

; 最初の比較

_ccp1:; yh> xh?

cp yh、xh

brlo _errConst; yh <xhの場合

breq _eq1; yh = xhの場合

rjmp _ccp2



_eq1:; yh = xhの場合

cp yl、xl; yl> xl?

brlo _errConst; yl <xlの場合



; 最初の数値が2番目の数値より小さい場合、

; 次に、2番目の比較に移動します

_ccp2:; yh> xhの場合

cp yh、xh; yh> xh?

breq _ccp22; yh = xhの場合

st X +、buf

rjmp _ccp2



_ccp22:; yh = xhの場合

cp yl、xl; yl> xl?

brlo _end; xl> ylの場合

st X +、buf

rjmp _ccp22



_errConst:; 最初の数値が2番目の数値より大きい場合はエラー

rcall _clear

rcall _labelWrite

rcall _labelSpace

rcall _labelConst

rcall _point

rcall _down

rcall _noCursor

rcall _labelErr

rjmp _wait



_end:; 出る

rjmp go



; ========================配列チェックサム計算========================

_SUM:

; 最初の比較

_scp1:; yh> xh?

cp yh、xh

brlo _errSum; yh <xhの場合

breq _eq2; yh = xhの場合

rjmp _scp2



_eq2:; yh = xhの場合

cp yl、xl; yl> xl?

brlo _errSum; yl <xlの場合



; 最初の数値が2番目の数値より小さい場合、

; 次に、2番目の比較に進みます

_scp2:; yh> xhの場合

cp yh、xh; yh> xh?

breq _scp22; yh = xhの場合

rcall _exCS

brcs _overflow

rjmp _scp2



_scp22:; yh = xhの場合

cp yl、xl; yl> xl?

brlo _showSum; xl> ylの場合

rcall _exCS

brcs _overflow

rjmp _scp22



_showSum:; チェックサムを表示する

rcall _clear

rcall _labelSum

rcall _down

rcall _noCursor

mov rLCD、rKey

rcall _charFromMemory

_wait:

rcall _exit

rjmp _wait



_errSum:; 最初の数値が2番目の数値より大きい場合はエラー

rcall _clear

rcall _labelSum

rcall _down

rcall _noCursor

rcall _labelErr

rjmp _wait



_overflow:; COP 255を超える場合-ここ

; フラグ転送と半転送をリセットします(念のため)

clh

clc

ldi rKey、0xff; COPが0xFFより大きい場合、FFが表示されます

rjmp _showSum



_exCS:; CS実行ルーチン

ld buf、X +

rKey、bufを追加します

; rcall _cpixl

ret



; ==============================アレイの移動===================== ============

_execArray:

; 最初の比較

_acp1:; yh> xh?

cp yh、xh

brlo _errArr; yh <xhの場合

breq _eq3; yh = xhの場合

rjmp _acp2



_eq3:; yh = xhの場合

cp yl、xl; yl> xl?

brlo _errArr; yl <xlの場合



; 最初の数値が2番目の数値より小さい場合、

; 次に、2番目の比較に進みます

_acp2:; yh> xhの場合

cp yh、xh; yh> xh?

breq _acp22; yh = xhの場合

rcall _exMA

rjmp _acp2



_acp22:; yh = xhの場合

cp yl、xl; yl> xl?

brlo _end; xl> ylの場合

rcall _exMA

rjmp _acp22



_errArr:; 最初の数値が2番目の数値より大きい場合はエラー

rcall _clear

rcall _mArray

rcall _down

rcall _noCursor

rcall _labelErr

rjmp _wait



_exMA:; PM実行ルーチン

ld rKey、X +

st Z +、rKey

ret

; ================================================== ==================



_exit:

sbisしかし、やめる; 終了ボタンが押された場合、

rjmp go; その後、移動中にモードを終了します

ret

; ================================================== ===================



; 画面を操作する



; LCD初期化

altInit:

rcall _delay1

ldi rLCD、config; ディスプレイ設定:8ビット、2行、5x8

rcall _cWrite



rcall _delay1

ldi rLCD、オン; ディスプレイをオンにします

rcall _cWrite



rcall _delay1

ldi rLCD、clrSc; スクリーンクリーニング

rcall _cWrite



rcall _delay1

ldi rLCD、incr; アドレスの増加、画面は静的です

rcall _cWrite

ret



; ビジービットチェック

_BF:

rcall _portIn; 入力データポート

rcall _modeB; コマンド読み取りモード

_loop:

sbi _cpo、e

rcall _delay

cbi _cpo、e

r24では、_dpi; データバスの読み取り

andi r24、0x80; 7番目のビットチェック

brne _loop

ret



; 遅れる

_delay:

ldi r23、20

_del:

12月r23

brne _del

ret



//より多くの遅延

_delay1:

ldi r24,0xff; 255

_d:

ldi r23,0xff; 255

_cmp_d:

12月r23

brne _cmp_d

12月r24

brne _cmp_d

ret



; チーム記録

_cWrite:

rcall _modeC

rcall _portOut

out _dpo、rLCD

rcall _delay

cbi _cpo、e

ret



; データ記録

_dWrite:

rcall _modeD

rcall _portOut

out _dpo、rLCD

rcall _delay

cbi _cpo、e

ret



; 出口データポート

_portOut:

ldi r23,0xff

out _dp、r23

ret



; プルアップ付き入力データポート

_portIn:

ldi r23,0x00

out _dp、r23

ldi r23,0xff

out _dpo、r23

ret



; コマンド記録モード

_modeC:

cbi _cpo、rw

cbi _cpo、rs

sbi _cpo、e

ret



; データ記録モード

_modeD:

sbi _cpo、rs

cbi _cpo、rw

sbi _cpo、e

ret



; スタンバイbf

_modeB:

sbi _cpo、rw; 読書

cbi _cpo、rs; チーム

ret



; アドレスとデータを入力するときの文字コード生成

_charInput:

cpi rLCD、0x0a; 10と比較

brge _grt; それ以上の場合は、_grtAに切り替えます

rcall _lstA

rjmp _return

_grt:

rcall _grtA

_return:

ret



_lstA:

ldi r21,0x30; 少ない場合

rLCD、r21を追加します。 48を追加

rcall _dWrite; LCDに書き込む

ret



_grtA:; 番号がA ... Fの場合

ldi r21,0x37; 55-rLCDに追加して文字コードを取得

rLCD、r21を追加します。

rcall _dWrite; LCDに書き込む

ret



; メモリーから読み取るときの文字形成

; rLCDを介して動作します

_charFromMemory:

プッシュrLCD; スタックに送られた

; 高バイト形成

andi rLCD、0xf0; クリアジュニアニブル

スワップrLCD; ニブルを交換する

rcall _BF

rcall _charInput

; 高バイト形成

ポップrLCD; スタックから抜け出す

andi rLCD、0x0f; クリアニブル

rcall _BF

rcall _charInput

ret



; ==========================================あらゆる種類のラベルと画面設定=== ==============================



; 「-」

_none:

; rcall _up

ldi rLCD、0x2D

rcall _BF

rcall _dWrite

ret



; 二行目

_down:

LDI rLCD、ダウン

rcall _BF

rcall _cWrite

ret



; 碑文「BROWSE」

_browse:

ldi rLCD、0x42; B

rcall _BF

rcall _dWrite

ldi rLCD、0x52; R

rcall _BF

rcall _dWrite

ldi rLCD、0x4f; O

rcall _BF

rcall _dWrite

ldi rLCD、0x57; W

rcall _BF

rcall _dWrite

ldi rLCD、0x53; S

rcall _BF

rcall _dWrite

ldi rLCD、0x45; E

rcall _BF

rcall _dWrite

ret



; 碑文「MOVE ARRAY」

_mArray:

ldi rLCD、0x4d; M

rcall _BF

rcall _dWrite

ldi rLCD、0x4f; O

rcall _BF

rcall _dWrite

ldi rLCD、0x56; V

rcall _BF

rcall _dWrite

ldi rLCD、0x45; E

rcall _BF

rcall _dWrite

rcall _labelSpace

ldi rLCD、0x41; A

rcall _BF

rcall _dWrite

ldi rLCD、0x52; R

rcall _BF

rcall _dWrite

ldi rLCD、0x52; R

rcall _BF

rcall _dWrite

ldi rLCD、0x41; A

rcall _BF

rcall _dWrite

ldi rLCD、0x59; Y

rcall _BF

rcall _dWrite

ret



; 碑文「DATA」

_labelData:

ldi rLCD、0x44; D

rcall _BF

rcall _dWrite

ldi rLCD、0x41; A

rcall _BF

rcall _dWrite

ldi rLCD、0x54; T

rcall _BF

rcall _dWrite

ldi rLCD、0x41; A

rcall _BF

rcall _dWrite

ret



; 碑文「書き込み」

_labelWrite:

ldi rLCD、0x57; W

rcall _BF

rcall _dWrite

ldi rLCD、0x52; R

rcall _BF

rcall _dWrite

ldi rLCD、0x49; 私は

rcall _BF

rcall _dWrite

ldi rLCD、0x54; T

rcall _BF

rcall _dWrite

ldi rLCD、0x45; E

rcall _BF

rcall _dWrite

ret



; 碑文「CONST」

_labelConst:

ldi rLCD、0x43; C

rcall _BF

rcall _dWrite

ldi rLCD、0x4f; O

rcall _BF

rcall _dWrite

ldi rLCD、0x4e; N

rcall _BF

rcall _dWrite

ldi rLCD、0x53; S

rcall _BF

rcall _dWrite

ldi rLCD、0x54; T

rcall _BF

rcall _dWrite

ret



; 碑文「ADDRESS」

_labelAddr:

ldi rLCD、0x41; A

rcall _BF

rcall _dWrite

ldi rLCD、0x44; D

rcall _BF

rcall _dWrite

ldi rLCD、0x44; D

rcall _BF

rcall _dWrite

ldi rLCD、0x52; R

rcall _BF

rcall _dWrite

ldi rLCD、0x45; E

rcall _BF

rcall _dWrite

ldi rLCD、0x53; S

rcall _BF

rcall _dWrite

ldi rLCD、0x53; S

rcall _BF

rcall _dWrite

ret



; 碑文「CHECKSUM」

_labelSum:

ldi rLCD、0x43; C

rcall _BF

rcall _dWrite

ldi rLCD、0x48; H

rcall _BF

rcall _dWrite

ldi rLCD、0x45; E

rcall _BF

rcall _dWrite

ldi rLCD、0x43; C

rcall _BF

rcall _dWrite

ldi rLCD、0x4b; K

rcall _BF

rcall _dWrite

ldi rLCD、0x53; S

rcall _BF

rcall _dWrite

ldi rLCD、0x55; うん

rcall _BF

rcall _dWrite

ldi rLCD、0x4d; M

rcall _BF

rcall _dWrite

ret



; 碑文「エラー」

_labelErr:

ldi rLCD、0x45; E

rcall _BF

rcall _dWrite

ldi rLCD、0x52; R

rcall _BF

rcall _dWrite

ldi rLCD、0x52; R

rcall _BF

rcall _dWrite

ldi rLCD、0x4f; O

rcall _BF

rcall _dWrite

ldi rLCD、0x52; R

rcall _BF

rcall _dWrite

ret



; 「0」

_labelZero:

ldi rLCD、0x30

rcall _BF

rcall _dWrite

ret



; 「1」

_labelOne:

ldi rLCD、0x31

rcall _BF

rcall _dWrite

ret



; 「2」

_labelTwo:

ldi rLCD、0x32

rcall _BF

rcall _dWrite

ret



; 「3」

_labelThree:

ldi rLCD、0x33

rcall _BF

rcall _dWrite

ret



; スペースバー

_labelSpace:

ldi rLCD、0x20

rcall _BF

rcall _dWrite

ret



; 両方の行をクリアします

_clear:

ldi rLCD、clrSc

rcall _BF

rcall _cWrite

ret



; 画面をクリアし、「-」を表示します

_resetLCD:

rcall _clear

rcall _noCursor; カーソルなし

rcall _BF

; rcall _cWrite

rcall _none

ret



; 点滅カーソル設定

_cursor:

ldi rLCD、カーソル

rcall _BF

rcall _cWrite

ret



; カーソルオフ

_noCursor:

ldi rLCD、noCursor

rcall _BF

rcall _cWrite

ret



; 「。」

_point:

ldi rLCD、0x2e

rcall _BF

rcall _dWrite

ret



; 「:」

_colon:

ldi rLCD、0x3a

rcall _BF

rcall _dWrite

ret



; 右カーソルシフト

_right:

ldi rLCD、右

rcall _BF

rcall _cWrite

ret



; 左シフト

_left:

LDI rLCD、左

rcall _BF

rcall _cWrite

ret


これは、メモリセルとそれに続くセルの内容が変更されて表示されるビデオです。




All Articles