(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
.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
これは、メモリセルとそれに続くセルの内容が変更されて表示されるビデオです。