114
卒業研究報告 題目 RGB フルカラーLED をマトリックス状に並べた表示回路の設計と製作 学籍番号: 1110153 氏名: 大塚 雅之 綿森 道夫 准教授 平成 23 2 8 高知工科大学 電子・光システム工学科

卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

Embed Size (px)

Citation preview

Page 1: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

卒業研究報告

題目

RGBフルカラーLEDをマトリックス状に並べた表示回路の設計と製作

報 告 者

学籍番号: 1110153

氏名: 大塚 雅之

指 導 教 員

綿森 道夫 准教授

平成 23年 2月 8日

高知工科大学 電子・光システム工学科

Page 2: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

1

目次

第1章 研究背景と目的・・・・・・・・・・・・・・・・・・・・・・・・ 3

1.1 研究背景・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 3

1.2 目的・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 3

第2章 PIC プロセッサ・・・・・・・・・・・・・・・・・・・・・・・・・ 4

2.1 性能・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 4

2.2 種類・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 4

2.3 開発環境・・・・・・・・・・・・・・・・・・・・・・・・・・ 5

第3章 スロットマシンの設計と製作・・・・・・・・・・・・・・・・・・・6

3.1 概略・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 6

3.2 回路図・・・・・・・・・・・・・・・・・・・・・・・・・・・ 7

3.3 仕様と動作・・・・・・・・・・・・・・・・・・・・・・・・・ 8

3.4 生じた問題点・・・・・・・・・・・・・・・・・・・・・・・・ 10

3.5 オリジナルケースの製作・・・・・・・・・・・・・・・・・・・ 12

第4章 I2C 通信方式 LED 小型回路の試作・・・・・・・・・・・・・・・・ 14

4.1 概略・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 14

4.2 スタティック点灯方式の実現・・・・・・・・・・・・・・・・・ 17

4.3 I2C 通信方式・・・・・・・・・・・・・・・・・・・・・・・・ 18

第5章 18×12LED マトリックス表示回路の設計と製作・・・・・・・・・ 24

5.1 概略・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 24

5.2 表示ソフトウェアの構成と搭載・・・・・・・・・・・・・・・・ 32

第6章 テトリスソフトウェアの開発と実装・・・・・・・・・・・・・・・ 34

6.1 概略・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 34

6.2 必要となる主要関数 ・・・・・・・・・・・・・・・・・・・・ 34

Page 3: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

2

第7章 総括・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 38

謝辞・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 39

参考文献・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 40

付録 プログラムリスト・・・・・・・・・・・・・・・・・・・・・・・・ 41

Page 4: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

3

第1章 研究背景と目的

1.1 研究背景

PIC マイコンは、私たちが生活の中で触れる電化製品、自動車、OA 機器等あらゆる物に

搭載されている。また現在は、チップの価格も下がり、インターネットで手軽に入手でき

る事から、アマチュアの間でも PIC を使った電子工作は、一般的なものになっている。

綿森研究室に所属して以降、PIC の基礎知識、及び制御技術を学びながら電子工作を行っ

てきた。これまでに、LED を用いた電子ルーレット、次に 7 セグを用いたカウントダウン

タイマーを作製した。どちらも、プログラムの記述をアセンブラで行い、特に、前者では

スイッチのチャタリングを防止するプログラムの記述法、後者ではダイナミック点灯方式

について学んだ。4 年生になって、C 言語を用いてグラフィック液晶を制御する方法につい

て学んだ。グラフィック液晶はドット単位で自由に表示ができる分、把握しなければいけ

ない項目が多く、良い C 言語の練習になった。このことをきっかけにして、グラフィック

液晶を搭載したスロットマシンを作ろうと考えた。これは回路の設計から製作まで初めて

自分で行ったもので、記念すべき第一作品である。この時はケースまで自作した。このス

ロットマシンについては第三章で改めて記述する。その後、いくつかの練習回路を作りな

がら、尐しずつではあるが工作能力やプログラム能力が向上したと思っている。そして最

終作品として、自分の全能力をかけて立ち向かうべく大型回路を選んだ。この回路が完成

する頃には、更に自分の技術力等が向上すると信じている。

1.2 目的

PIC を用いて自ら構想した物を形にする事で、アナログ・デジタル回路の理解力、回路

作成能力、プログラミング記述力の向上を目指し、物を作れる技術力を身につける事を目

的としている。具体的には、表面実装部品を UEW 線(φ0.6mm のエナメル線の一種)で

半田付けする細かい作業ができるようになる事、複雑な回路を設計し、回路図に起こし正

しく回路を組める事、そしてプログラムを作って回路を動作させることである。

今回選んだ表示回路は、PIC プロセッサを 5 個用い、Anode common LED を約 270 個、表

面実装型の D-FF アレイ IC を 108 個、抵抗を約 820 個使ったもので十分上記の目的を達成

するに足るものである。

Page 5: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

4

第2章 PIC プロセッサ

PIC(Peripheral Interface Controller)とは、その名のとおり周辺機器との接続を制御す

るのに特化したマイコンであり、アメリカの Microchip Technology Co.によって提供され

ている。

2.1 性能

PIC の主な特徴を以下に示す。(全てのシリーズに当てはまるものではない)

・動作電圧が低いので、電池駆動可。

・消費電流が小さいので、電池駆動で長時間動作する。

・フリーソフトが提供されており、開発環境の構築が容易。

・多数の機能を内蔵しており、尐ない外付け部品で回路を構成できる。

2.2 種類

PIC は汎用レジスタの幅によって以下の 3 つに大別できる。

1. 8bit

PIC10 系、12 系、16 系、18 系が該当し、さらに 3 つに大別できる。

・ベースラインシリーズ

命令長 12bit 幅の初期に開発されたシリーズで、PIC10 系、PIC12 系はこのグルー

プに属する。今でも使われているが PIC の世代としては尐し古い。

・ミッドレンジシリーズ

命令長 14bit 幅の最もよく使われるシリーズで、PIC16 系がこのグループに属する。

A/D 変換機能やシリアルポート等多くの機能を内蔵しており、種類も豊富。私が作

った作品も 16 系を用いた。

・ハイエンドシリーズ

命令長 16bit 幅の文字どおり高機能なシリーズで、PIC18 系がこのグループに属す

る。

Page 6: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

5

2.16bit

PIC24 系、dsPIC3x 系が該当し、8bit シリーズよりも性能が向上しており、特に後者は

マイコンに DSP(Digital Signal Processor)の機能を盛り込んだものである。

3.32bit

PIC32 系が該当し、消費電力を上げることなく、16bit シリーズよりも性能が向上してい

る。

2.3 開発環境

プログラム開発環境ソフトは FED Co.の Wiz-C(その他、よく使われる開発環境ソフト

も含め概略を後述する)、ライタは PICkey2、書き込みソフトウェアとして PIC

programmer を使用した。

プログラム開発環境ソフト

・MPLAB IDE

Microchip Technology Co.がフリーで提供している Windows ベースの統合開発環境ソフ

ト。

・CCSC

CCS(Custom Computer Services)Co.の C コンパイラで、PIC の種類別にコンパイラが

分かれており、それらを使い分ける必要があるが、統合環境付きのものもある。

・Wiz-C

FED(Forest Electronic Developments ) Co.の C コンパイラで、低価格ながら 12~18 シ

リーズまで多くの PIC に対応した統合開発環境ソフト。ライブラリ関数が豊富でコンパ

イルも高速である等の利点がある。

Page 7: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

6

第3章 スロットマシンの設計と製作

3.1 概略

128×64 ドットの GLCD と PIC16F876 を用いてスロットマシンを製作した。図 1 に外

観を示す。右端のボタンを押すと図柄が回転するとともに、credit が 3 消費される。左端か

ら 1、2、3 番目のボタンを押すと対応したリールが停止する。特定の図柄が揃うと任意の

得点が credit に加算される。

図 1 スロットマシンの外観

Page 8: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

7

3.2 回路図

スロットマシンの回路図を図 2 に示す。回路の概略は以下のとおりである。

・4 個のボタンを、内部プルアップ機能を持つ PORTB に接続する事で抵抗を 4 個省略。

・PIC16F876 は内部クロック機能が搭載されていない為、外部クロックとして 4MHz の

Resonator を使用。

・PORTC はすべて LCD への出力。

・特定の図柄が揃った時に音を流したいと考え、電子オルゴールメロディーIC(SM6201-4)

というチップを搭載した。抵抗値 R5 によって音量が決まる為、ブレットボードで試作

し適当な抵抗値(390kΩ)を決定した。

図 2 スロットマシン回路図

Q1

2SC1815

D2LED2D1

LED1

S5S4

S3S2

C10.22uF

J1

S1

+ V13V

R110k 40%

16F876

MCLRRA0RA1RA2RA3RA4RA5VssOSC1OSC2RC0RC1RC2RC3 RC4

RC5RC6RC7VssVddRB0RB1RB2RB3RB4RB5RB6RB7

U1

SM6201

M0TK3TK2TK1TK0VssVdd LED

PENOUTNC

OSCIOSCO

M1

U2

SG12864A

VssVddVoD/IR/WEDB0DB1DB2 DB3

DB4

DB5DB6

DB7CS1CS2RESVout

U3

U4

R510k

SPK18

R4 1k

R3 390k

R210k

Page 9: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

8

3.3 仕様と動作

3.3.1 仕様

・各図柄が揃うかどうかは取得した乱数によって管理される。(詳細は後述する)

図柄の種類、揃う確率、付与される得点を以下に示す。

図柄 確率 得点

1/256 300

1/256 200

1/127 100

1/64 15

約 1/11 10

約 1/34 2

約 1/7.8 3

これらの図柄は CAD を用いてマトリックスを作成し、1 からデザインした。

また、ハズレの場合は勿論 0 点であるが、1 ゲーム 3credit 消費するので実質-3 点である。

・白 7 図柄、黒 7 図柄、BAR 図柄が揃うと対応した音が流れる。

Page 10: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

9

3.3.2 動作

動作の要点を以下にまとめる。

1. 乱数の取得

スタートボタンが押されると、rand 関数によって乱数(WORD 型)を取得する。

次に示す命令により、WORD 型の乱数の下位 8bit を取り出す事で 0~255 までの何れ

かを得る。

r_num = ((WORD)rand( )) & 0x00FF;

(確率の計算は付録のソースコードを参照)

2. 表示の切り替え

スタートボタンを押すと Timer1 割り込みのカウントがスタートする。カウント値が、

予め TMR1H、TMR1L にセットした値と一致すると、割り込みが発生し、startflag が

True となる。

if(startflag) DispChange();

DispChange 関数で各リールの表示が切り替わる。

3.ボタンの検出

各ボタンの入力の有無は Keycheck という関数で検出する。

if(keycheckflag) Keycheck();

keycheckflag は 2ms 毎に起こる Timer0 割り込みで True とする。

4.得点計算

すべてのリールが停止すると、Calc_Credit1、Calc_Credit2 という 2 つの関数で得点

を計算する。

Calc_Credit2(stateflag);

Stateflag には取得した乱数が入っており、Calc_Credit2 にてハズレを含めた全ての図

柄のどれに相当するかを調べる。

次に、Calc_Credit1 関数で、更新後の credit の表示を生成する。

Page 11: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

10

3.4 生じた問題点

1. GLCD に何も表示されない

原因:マニュアルのコマンド記述に誤りがあった。

(Column Address Set command のコードの DB6 が実際は 0 固定であるが、A6

とされていた。訂正したコードを表 1 に示しておく。)

対処:正しいコマンドに従いプログラムを修正した。

R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0

0 0 0 A5 A4 A3 A2 A1 A0

A6 A5 A4 A3 A2 A1 A0 Column

Address

0 0 0 0 0 0 0 0

0 0 0 0 0 0 1 1

: :

1 1 1 1 1 1 1 3F

表 1 訂正後の Column Address Set command

2. 初期化時にメロディーIC が作動し音が鳴る

原因:PIC のキーのプルアップ設定時に、ごく短い時間メロディーIC にスタートパル

スが出ていた。

対処:メロディーIC を off にした後でキーのプルアップ設定を行い、その後メロディー

IC を on にした。

PORTB = 0; メロディーIC off

OPTION_REG = 0x02; PORTB プルアップ設定

PORTB = 0x0e; メロディーIC on

Page 12: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

11

3. 図柄のフォントが大きすぎてプログラムが納まらない

原因:GLCD の画面表示の自由度が高い代わりに、非常に多くのメモリーを使う。

対処:各関数の共通部分の再利用や、尐しでもプログラムが短くなるよう無駄を省き、

尐しずつ容量を圧縮、最終的に規定の容量内に納めた。

メモリーの制約により、フォントはプログラムにおいて

const BYTE 配列名[ ] = { }; 1 次元の場合

const BYTE 配列名[ ][ ] = { }; 2 次元の場合

の形で持っている。

しかし、この形式を採用すると、配列の要素の入れ替え等の変更が一切禁止されてし

まうため、リールを縦にスクロールするといったことができない。そこで、各リール

の 3 コマ分の図柄をまとめて切り替えていく方式にした。

切り替えの周期は Timer1 の初期値によるので、適当な値を入れて実際に表示させて

自然な動作に見えるものを選んだ。ただし、表示パターンが増えるごとに、ソースコ

ードも長くなりメモリーを圧迫するので、左リールは特定の場合を除き、1 種類で固定、

またハズレの場合、中、右リールは各 5 種類とした。

Page 13: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

12

3.5 オリジナルケースの製作

3DCAD ソフト、SolidWorks を用いてオリジナルのケースを製作した。設計図とケース

実装後の外観を以下に示す。

図 3 ケースの設計図

図 4 実装後の外観

Page 14: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

13

約 2~3 ヶ月間、SolidWorks の入門書で使い方を学び製作に取り組んだが、最初に試作

したケースはプログラム書き込み用の穴や、電源スイッチの位置がずれてうまくはまらな

い、厚さを 1mm で設計したが薄すぎる等の失敗があった。

また、電池 box 周辺をどの様に設計すれば良いか分からず、身の回りにある物を真似て作

製した。

Page 15: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

14

第4章 I2C 通信方式 LED 小型回路の試作

4.1 概略

最終目標である LED マトリックス表示回路のプロトタイプとして、小型版を試作した。

Anode common のフルカラーLED を 16 個使用し、4×4 のマトリックス状に配置した。PIC

は 16 系の中でも新しい 16F886 を使用し、LED のスタティックドライブを実現するために

DFF アレイ IC を搭載した。工作においては、2 枚の基板を用いて二段構造とした。最終作

品の小型版とはいえ、配線数が多く、DFF アレイ IC においてはフラットパッケージのもの

を使用したため、工作だけで約 30 時間かかった。また、この回路はスレーブ側であり、ブ

レッドボードにさしたもう一つの PIC16F886 をマスタとして I2C 通信のテストを行った。

図 5~7 に外観を、図 8 に回路図を示す。

図 5 LED 小型回路上段の表裏

図 6 LED 小型回路下段の表裏

図 7 重ねた LED 小型回路

Page 16: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

15

図 8 4×4LED マトリックス回路図

SDA

SCL

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

J1

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

3V

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

16F886

RE3RA0RA1RA2RA3RA4RA5VssRA7RA6RC0RC1RC2RC3 RC4

RC5RC6RC7VssVddRB0RB1RB2RB3RB4RB5RB6RB7

2020100202010020201002020100

100 20 20 100 20 20 100 20 20 100 20 20

2020100202010020201002020100

2020100202010020201002020100

Page 17: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

16

ここで回路について説明する。

DFF アレイのクロックラインは列ごとに共通で、RB4~RB7 を入力としている。

また、LED のデータラインは色ごとに共通である。

・RA0~RA3 は赤色のデータ

・RA4~RA7 は緑色のデータ

・RB0~RB3 は青色のデータ

RC3、RC4 は I2C 通信に使用する。

・RC3 はマスタからのクロック入力ポート

・RC4 はデータライン

さらに補足として、DFF アレイの真理値表を表 2 に示しておく。

INPUTS OUTPUTS

OE CK D

H X X Z

L ↓ X Qn

L ↑ L L

L ↑ H H

表 2 DFF アレイ真理値表

X :Don’t Care

Z :高インピーダンス

Qn : 変化なし

DFF アレイの OE(Output Enable)に関しては使用しないので、全て GND に落してある。

Page 18: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

17

4.2 スタティック点灯方式の実現

前述のとおり、スタティック点灯を実現するために DFF アレイを用いた。

その方法を以下に示す。(赤色の第 1 列をつける場合)

PORTA = 0xFF; //赤、緑 LED 消灯データセット

PORTB = 0x0F; //クロック 0ff、青 LED 消灯データセット

Wait(1); //時間待ち

PORTB = 0xFF; //全クロック on

Wait(1); //時間待ち

PORTB = 0x0F; //全クロック off

//ここまでは初期化

PORTA = 0xF0; //赤色 LED 点灯データセット

PORTB = 0x1F;//第 1 列クロック on

PORTB = 0x0F; //全クロック off

1 列毎に、クロックラインの on / off のみで LED の点灯/消灯を制御できることはプログラ

ム作成における利点である。

またこの方式の最大の利点は高輝度で LED を点灯させられる事である。(輝度は cathode

側に接続した抵抗の抵抗値に依存する)

Page 19: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

18

4.3 I2C 通信方式

4.3.1 基本構成

I2C(Inter-Integrated Circuit)通信方式とは、2 線式の同期式シリアル通信インターフ

ェースのことで、シリアル・データ信号 SDA とシリアル・クロック信号 SCL の 2 本の信

号で通信する。

基本的な構成を図 9 に示す。図のように 1 台のマスタと、1 台または複数のスレーブとの

間を、SCL と SAD という 2 本の線でパーティーライン状に接続する。常に権限を持ってい

るのはマスタ側で、マスタが送信するクロック信号 SCL を基準としてデータ信号が SDA

ライン上で転送される。

Vdd

1KΩ~5KΩ 1KΩ~5KΩ

Master Slave1

Slave2

Slave3

図 9 I2C 通信の基本構成

SCL

SDA

SCL

SDA

SCL

SDA

SCL

SDA

Page 20: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

19

4.3.2 通信手順

I2C 通信の簡単な流れは以下のとおりである。

1. クロックが High の時、データが立ち下がると通信がスタート

この時 Start Condition が発行される。次に、スレーブのアドレスと共に

R/W(Read/Write )要求を送信する。

2. クロックが Low になるごとに順次 1bit ずつデータを送信

アドレスが一致したスレーブとマスタが、1 対 1 で指定された方向で(R/W を参照)デ

ータ通信を行う。受信側が 8bit 分のデータの受信を完了する度にアクノリッジ(ACK)

信号が送信される。

3. クロックが High の時、データが立ち上がると通信ストップ

最終データの受信が完了し、ACK の返送を確認すると、スレーブは SDA を開放するの

で、マスタが SDA を Low にし、クロックを停止して High にしてから、SDA を再び

High にする事で、Stop Condition が発行され、通信を終了する。

この手順を図 10、11 に示す。

0 ハードウェアで自動返送 Repeat Start 時は

次のアドレスが来る

Start Slave address RW ACK Data(8bits ) ACK Data(8bits) ACK Stop/Repeat Start Slave address

図 10 マスタから送信時の通信手順

1 ハードウェアで自動返送

マスタ側がプログラムで送信 Stop/Repeat Start

Start Slave Address RW ACK

Data(8 bits) ACK Data(8bits) ACK Slave Address

CKP が Low の間待たされるので処理時間を確保できる Repeat Start 時は次のアドレスが来る

図 11 マスタ受信時の通信手順

Page 21: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

20

4.3.3 I2C 用制御レジスタと通信プログラム

通信に関するプログラムについて記述する前に、I2C 用制御レジスタをマスタモード時と、

スレーブモード時別に図 12、13 に示す。(色付きの字は関連しないビットとする)

Master Mode

マスタ送信モードの場合

SSPCON

WCOL SSPOV SSPEN CKP SSPM3 SSPM2 SSPM1 SSPM0

WCOL: ‘1’ ライトコリジョン検出 SSPEN: ‘1’ I2C モジュール使用許可

SSPM3~0:SSP モード設定 マスタモード 1000 / ファームウェア制御のマスタモード 1011

SSPCON2

GCEN ACKSTAT ACKDT ACKEN RCEN PEN RSEN SEN

ACKSTAT: ’0’ スレーブから ACK 受信あり / ‘1’ ACK 受信なし

RCEN: ‘1’ レシーブモード許可 PEN: ‘1’ ストップコンディション開始

RSEN: ‘1’ リピートスタートコンディション開始

SEN: ‘1’ スタートコンディション開始

SSPSTAT

SMP CKE D/A P S R/W UA BF

SMP: スルーレート ‘0’ 400KHz(ハイスピードモード)/ ‘1’ 100KHz(スタンダードスピード)

P: ‘1’ ストップビット検出 S: スタートビット検出 R/W: ‘1’ 送信中

BF: ‘1’ バッファ(SSPBUF)満 / ‘0’ バッファ(SSPBUF)空

マスタ受信モードの場合(記述のないビットに関しては送信時と同じとする)

SSPCON

WCOL SSPOV SSPEN CKP SSPM3 SSPM2 SSPM1 SSPM0

SSPOV: ‘1’ 受信オーバーフロー

SSPCON2

GCEN ACKSTAT ACKDT ACKEN RCEN PEN RSEN SEN

ACKDT: スレーブへ返す ACK データ ’0’ ACK / ‘1’ NOACK

ACKEN: ‘1’ ACK シーケンス開始

図 12 Master Mode で使用するレジスタ一覧

Page 22: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

21

Slave Mode

SSPCON

WCOL SSPOV SSPEN CKP SSPM3 SSPM2 SSPM1 SSPM0

WCOL: ‘1’ SSPBUF のライトコリジョン検出

SSPOV: ‘1’ レシーブデータオーバーフロー(受信時のみ)

SSPEN: ‘1’ I2C モジュール使用許可

CKP: ‘1’ クロックストレッチ解除 / ‘0’ クロックストレッチ

SSPM3~0:SSP モード設定 スレーブモード 10bit アドレス 0111

スレーブモード 10bit アドレス 0110

SSPCON2

GCEN ACKSTAT ACKDT ACKEN RCEN PEN RSEN SEN

GCEN: ’1’ ジェネラルコールアドレス有効

SEN: ‘1’ 送/受信時のクロックストレッチ有効

‘0’ 送信時のみクロックストレッチ有効

図 13 Slave Mode で使用するレジスタ一覧

次に I2C 通信プログラムにおいて重要な部分を記述する。

マスタ側

void Send_Mono_Data(BYTE address, BYTE data){

bSEN = 1; スタートコンディション送信

while ( bSEN ) {} 送信完了待ち

SSPBUF = address; SSPBUF にスレーブアドレスを格納

while ( bBF ) {} 送信完了待ち

while ( bACKSTAT ) {} ACK 受信待ち

SSPBUF = data; SSPBUF に送信データを格納

while ( bBF ) {} 送信完了待ち

while ( bACKSTAT ) {} ACK 受信待ち

bPEN = 1; ストップコンディション送信

while ( bPEN){} 送信完了待ち

}

Page 23: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

22

void Receive_Mono_Data(BYTE address){

bSEN = 1; スタートコンディション送信

while ( bSEN ) {} 送信完了待ち

SSPBUF = address + 1; SSPBUF にスレーブアドレスを格納

while ( bBF ) {} 送信完了待ち

while ( bACKSTAT ) {} ACK 受信待ち

bRCEN = 1; マスタ受信許可

while(!bBF){} 受信完了待ち

received_data = SSPBUF; 受信データ取り出し

bACKEN = 1; ACK 送信

while(bACKEN){} 送信完了待ち

bPEN = 1; ストップコンディション送信

while ( bPEN){} 送信完了待ち

}

・Send_Mono_Data 関数はマスタから指定したスレーブに 8bit のデータを一つだけ送る関

数である。

・Receive_Mono_Data 関数はマスタがスレーブから 8bit のデータを一つだけ受信する関数

である。

また、SSPBUF = address + 1 の部分は、スレーブアドレスが 7bit で左詰めであり、bit0

は R/W に相当するためスレーブアドレス+1 とし、マスタ受信モードを指定している。

スレーブ側

Main 関数の一部を抜粋

while(1){

d_a = Wait_Receive(); Wait_Receive をコール

if(d_a) Send_Data(BYTE data); d_a が 1 なら Send_data をコール

else received_data = Read_Data(); d_a が 0 ならを Read_Data コール

}

BYTE Wait_Receive(void){

BYTE data;

while(!bSSPIF){} 受信待ち

bSSPIF = 0; フラグクリア

if(!bD_A){ 受信したデータがアドレスなら次を実行

Page 24: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

23

data = SSPBUF; アドレスを読み捨てる

bCKP = 1; クロックストレッチ解除

while ( !bSSPIF ) {} 次のデータ受信待ち

bSSPIF = 0;

}

if ( bR_W ) return 1; R/W bit が 1 ならマスタ受信モード、1 を return

else return 0; R/W bit が 0 ならマスタ送信モード、0 を return

}

BYTE Read_Data(void){

BYTE data;

data = SSPBUF; 受信データを取り出す

bCKP = 1; クロックストレッチ解除

bSSPIF = 0;

return data; 受信データを return

}

void Send_to_Master(BYTE data){

SSPBUF = data; SSPBUF に送信データをセット

bCKP = 1; クロックストレッチ解除

while(!bSSPIF){} 送信完了待ち

}

SSPIF とは PIR1 レジスタにある I2C 通信専用の割り込みフラグである。スレーブ側の場

合このフラグが最初にセットされるのは、送信されたコントロールバイト内のアドレスが

自分のアドレスと一致した場合である。以降、各イベントが発生する度にこのフラグが立

つが、適当なタイミングでソフトウェアでクリアする必要がある。

Page 25: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

24

第5章 18×12LED マトリックス表示回路の設計と製作

5.1 概略

試作機の結果を基にして、本研究の最終作品である RGB フルカラーLED を 18×12 のマ

トリックス状に並べた表示回路を設計した。この回路は、PIC プロセッサを 5 個用い、Anode

Common LED を約 270 個、表面実装型の DFF アレイ IC を 108 個、抵抗を約 820 個使っ

た非常に大きな回路で、製作に約一ヶ月の日時を要した。図 14~17 に完成した回路の外観

を、図 18、19 に回路図を示す。

図 14 18×12LED マトリックス表示回路 1 段目表の外観

Page 26: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

25

図 15 18×12LED マトリックス表示回路 1 段目裏の外観

Page 27: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

26

図 16 18×12LED マトリックス表示回路 2 段目表の外観

Page 28: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

27

図 17 18×12LED マトリックス表示回路 2 段目裏の外観

Page 29: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

28

図 18 18×12LED マトリックス表示回路のスレーブ部分 9×6

SCL

SDA

16F887

RE3RA0RA1RA2RA3RA4RA5RE0RE1RE2VddVssRA7RA6RC0RC1RC2RC3RD0RD1 RD2

RD3RC4RC5RC6RC7RD4RD5RD6RD7VssVddRB0RB1RB2RB3RB4RB5RB6RB7

J1

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

R G B BGR BGR BGR BGR BGR

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

R G B BGR BGR BGR BGR BGR

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

R G BR G BR G BR G BR G BBGR

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

R G B BGR BGR BGR BGR BGR

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

R G BR G BR G BR G BR G BBGR

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

R G B BGR BGR BGR BGR BGR

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

R G BR G BR G BR G BR G BBGR

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

R G B BGR BGR BGR BGR BGR

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

R G BR G BR G BR G BR G BBGR

+V3V

TC74VHC574F

OE

D0

D1

D2

D3

D4

D5

D6

D7

GND

CK

Q7

Q6

Q5

Q4

Q3

Q2

Q1

Q0

Vcc

100 15 22 2215100 2215100 2215100 2215100 2215100

100 15 22 2215100 2215100 2215100 2215100 2215100100 15 22100 15 22100 15 22100 15 22100 15 222215100100 15 22 2215100 2215100 2215100 2215100 2215100 100 15 22100 15 22100 15 22100 15 22100 15 222215100

100 15 22 2215100 2215100 2215100 2215100 2215100100 15 22100 15 22100 15 22100 15 22100 15 222215100

100 15 22 2215100 2215100 2215100 2215100 2215100100 15 22100 15 22100 15 22100 15 22100 15 222215100

Page 30: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

29

図 19 18×12LED マトリックス表示回路のマスタ部分

LCD

SDA

Vss

Vdd

RST

SCL

JoyStick

GND

SEL

HORZ

VERT

Vcc

J1

+ V210VSDA

SCL

S1

S2S3

2SC3325

2SC3325

2SC3325

R G B R G BBGR R G B R G B R G B R G B R G B R G B

2SC3325

2SC3325

2SC3325

BGR R G B R G B R G B R G B

2SC3325

2SC3325

2SC3325

BGRBGRBGRBGRBGRBGRBGRBGRBGRR G B

2SC3325

2SC3325

2SC3325

R G BBGR R G B R G B R G B R G B R G B R G B

BGRBGRBGRBGRBGRBGRR G B G B R G B R G B R G BR

2SC3325

2SC3325

2SC3325

2SC3325

2SC3325

2SC3325

BGRBGRBGRBGRBGRBGRR G B

BGR R G B R G B R G B R G B R G B R G B

2SC3325

2SC3325

2SC3325

16F887

RE3RA0RA1RA2RA3RA4RA5RE0RE1RE2VddVssRA7RA6RC0RC1RC2RC3RD0RD1 RD2

RD3RC4RC5RC6RC7RD4RD5RD6RD7VssVddRB0RB1RB2RB3RB4RB5RB6RB7

U1

3.3k 3.3k

1.2k

1.2k

1.2k

100 15 22 100 15 222215100 100 15 22 100 15 22 100 15 22 100 15 22 100 15 22 100 15 22

1.2k

1.2k

1.2k

2215100 100 15 22 100 15 22 100 15 22 100 15 22

1.2k

1.2k

1.2k

221510022151002215100221510022151002215100221510022151002215100100 15 221.2k

1.2k

1.2k

100 15 222215100 100 15 22 100 15 22 100 15 22 100 15 22 100 15 22 100 15 22

221510022151002215100221510022151002215100100 15 22 15 22 100 15 22 100 15 22 100 15 22100

1.2k

1.2k

1.2k

221510022151002215100221510022151002215100100 15 22

2215100 100 15 22 100 15 22 100 15 22 100 15 22 100 15 22 100 15 22

1.2k

1.2k

1.2k

1.2k

1.2k

1.2k

Page 31: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

30

スレーブ回路の基本的な回路構成は試作機と同じだが、表示部分が18×12と大きいため、

9×6 のスレーブ回路を 4 個持つ構成とした。この 4 つのスレーブと全体を統合する 1 つの

マスタに使用した PIC は全て 16F887(40Pin)である。図 18 は 9×6 のスレーブ回路の 1

つ分であり、実際の回路はこの回路を 4 個有している。

スレーブ回路の Port 制御表を表 3、4 に示す。

色 赤色 LED1~6 緑色 LED1~6 青色 LED1~6

ポート RA0~RA5 RB0~RB5 RB0~RB5

表 3 色別 LED データライン

列番号 クロック入力ポート

1 RC0

2 RC1

3 RC2

4 RC5

5 RC6

6 RC7

7 RA6

8 RA7

9 RD6

表 4 クロックライン入力ポート

マスタ側の回路は TETORIS の文字を表現する形に並べた LED56 個を、各文字の各色に

対して一個のトランジスタ(2SC3325)で制御している。この周辺回路について説明する。

まず、トランジスタのベース側の抵抗の抵抗値を以下のようにして決定した。

三色の LED の中で一番電流を流しているのは青色 LED である。(測定値 16.5mA)

図 20 青色 LED の場合 Tr 周辺回路

R11.2k

+V3V

2SC3325

22222222

各文字で一番 LED が多いのは R の文字で 10 個分の

16.5mA×10 = 165mA

がトランジスタのコレクタ・エミッタ間に流れる可能

性がある。

余裕を持たせて Ic を 200mA とすると、

(2SC3325 の Max Ic = 500mA)

Ib = Ic/hfe より、Ib = 200mA / 100 = 2mA

PIC

Page 32: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

31

(hfe は 100 以上であるが、100 として計算してもトランジスタの飽和領域から非飽和領域

に移って見かけ上 hfe が下がるだけなので、結果は変わらない。)

図 20 より、R1 = (Vdd - Vbe) / Ib で求められ

R1 = (3V – 0.6V) / 2mA = 1.2KΩと計算される。

この回路に PIC から High (3V)の信号を与えると、コレクタ-エミッタ間に電流が流れて

LED が点灯する。

また、テトリスの実装を想定し、操作用の Joy Stick を搭載した。この Joy Stick は上下左

右の入力を、Joy Stick 内部に接続された可変抵抗による電圧変化によって認識する。そこ

で、PIC の AD 変換機能を利用して制御することとした。Joy Stick の初期電圧値及び、各

入力による電圧の変化は、PIC とシリアル接続基板(「プリント基板で作る PIC 応用装置」

鈴木哲哉著から利用)を介し RS232C を経由してパソコンに接続する構成で、Joy Stick を

傾けた時の値をパソコンに表示させる事で各入力時の値を確認した。

更に、得点表示用に低電圧 I2C 液晶モジュールという、2.7V から駆動することができる

I2C スレーブ専用の液晶を搭載した。これに関しても、事前にブレッドボードでテスト回路

を組んで駆動してみたが、最初は初期化の設定がうまくいかず苦労した。

Page 33: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

32

5.2 表示ソフトウェアの構成と搭載

次にこの回路を表示させる為のプログラムを作成した。回路の構成で記述したとおり、

表示部分を 9×6 の 4 つの領域に分割したが、マスタは全画面の各ドットのデータ(以下マ

ップデータと表現する)を常に把握する必要がある。しかし、18×12 のマップデータを保

存する配列は大きすぎて取ることができない。そこで、上半分と下半分に分けて圧縮した

状態でマップデータを保存する配列を作った。マップデータの内訳は以下のとおり。

BYTE upper_map[9][6]; 上半分のマップデータ

BYTE lower_map[9][6]; 下半分のマップデータ

Slave1 Slave2

upper_map[0][0]~[0][2] upper_map[0][3 ]~[0][5]

: :

upper_map[8][0]~[8][2] upper_map[8][3]~[8][5]

Slave4 Slave3

lower_map[0][0]~[0][2] lower_map[0][3]~[0][5]

: :

lower_map[8][0]~[8][3] lower_map[8][3]~[8][5]

圧縮データの内訳を図 21 に示す。ここで、図 21 の左から 6 個分のセルが、左から 6 個

分の LED に対応している。縦方向のセルは、縦方向に並んだ LED を意味する。

upper_map[0][0]

の上位 4bit

upper_map[0][0]

の下位 4bit

upper_map[0][1]

の上位 4bit

upper_map[0][1]

の下位 4bit

upper_map[0][2]

の上位 4bit

upper_map[0][2]

の下位 4bit

upper_map[1][0]

の上位 4bit

upper_map[1][0]

の下位 4bit

upper_map[1][1]

の上位 4bit

upper_map[1][1]

の下位 4bit

upper_map[1][2]

の上位 4bit

upper_map[1][2]

の下位 4bit

: : : : : :

図 21 圧縮データの対応図(Slave1 の最初の部分を抜粋)

Page 34: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

33

この段階では配列に予め任意のマップデータを入れておいて、マスタからスレーブに送

信した時に意図したとおりに表示されること、LCD 液晶モジュールに任意の文字を表示で

きること、Joy Stick の操作を認識できることを確認した。これらの様子を図 22 に示す。

図 22 マップデータと文字を表示している様子

Page 35: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

34

第6章 テトリスソフトウェアの開発と実装

6.1 開発に係る設計指針

次にこの表示回路を使ったアプリケーションの実装を考えた。今回はテトリスを開発し

てみようと思った。

まず、開発に係る設計指針として以下のことが挙げられる。

・既に第 5 章でも触れたとおり PIC の RAM の容量の制約で画面全体のデータを一つの配

列に持つことができないので、上下に分割し、圧縮して保存することとした。

・上記の理由で、マスタから受信するデータは必ず圧縮されており、スレーブは受信した

後にそのデータを元に戻すという作業が必要となる。

・ブロックの移動判定において、上下左右以外に各スレーブ同士の境界もチェックしなけ

ればならない。

他にも多尐の制約はあるだろうが、最低限上記のことを踏まえて、開発していくべきであ

る。

6.2 必要となる主要関数

以下に主要な関数を挙げていく。

1. 圧縮 VRAM データの表示関数

データの送信は 1 セットにつき 4 つとし、received_data という変数と temp_data[3]

という配列で受け取る。

received_data :受信したデータの列番号

temp _data[1] :左から 1 番目、2 番目のデータ(圧縮されている)

temp _data[2] :左から 3 番目、4 番目のデータ(圧縮されている)

temp _data[2] :左から 5 番目、6 番目のデータ(圧縮されている)

この圧縮されたデータを以下のようにして、元に戻していく。

Page 36: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

35

BYTE i, j;

for ( i = 0; i < 3; i++) {

j = 2 * i;

line_data[ j ] = (temp_data[i] & 0xf0) / 16; 上位 4bit を取り出し

line_data[ j + 1] = temp_data[i] & 0x0f; 下位 4bit 取り出し

}

for ( i = 0; i < 6; i++)

map_data[received_data][i] = line_data[i]; 受け取ったデータを map_data にコピー

上記命令では、line_data[0 ]~[5] に、圧縮データを元に戻してから格納し、最後に

map_data に受け取ったデータを反映させている。データの取り出しに関して、下位 4bit

を取り出すときはマスクするだけで良いが、上位 4bit に関してはマスクした後に、4bit 右

シフトする必要がある。

次にこのデータを以下のようにして表示する。

BYTE i, j, keisu = 1, r = 0, g = 0, b = 0;

for(i = 0; i < 6; i++){

line_data_R = line_data[i] & 0x01; データの bit0 が 1 なら赤表示

line_data_G = (line_data[i] & 0x02) / 2; データの bit1 が 1 なら緑表示

line_data_B = (line_data[i] & 0x04) / 4; データの bit2 が 1 なら青表示

if(!line_data_R) r += keisu;

if(!line_data_G) g += keisu;

if(!line_data_B) b += keisu;

keisu *= 2;

}

PORTA = r;

PORTB = g;

PORTD = b;

switch(received_data){

case 0:

bRC0 = 1;

break;

Page 37: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

36

case 1:

bRC1 = 1;

break;

中略

case 8:

bRD6 = 1;

break;

default:

break;

}

この命令では、for 文内で 1 列分のデータを読み込んでどの場所に何色の LED を点灯させ

るかをチェックしてループを抜けた後、ポートにデータをセットし、switch 文で列の情報

(received_data)を参照し、該当する列のクロックを on にする事で受け取ったデータを表示

部に反映している。

この回路の LED はアクティブ low だから、if(!line_data_R) r += keisu;の部分は各色デー

タを反転すれば消灯データになり、その消灯データを得るごとにポートにセットする値(r,

g , b)に 1(消灯)を代入している。

2.得点表示、Joy Stick 操作関数

得点表示は I2C 液晶に、第五章で作成した関数をそのまま利用した。予め液晶を初期

化しておき、任意のデータを I2C 通信手順に沿って送るだけなので詳細は記述しない。

Joy Stick 操作の認識は、以下のとおりである。

if(adflag){

ADCON0 = VERT; 縦方向入力チェック

Wait(1); 時間待ち

bGO = 1; AD 変換スタート

while(bGO); 終了待ち

adresult_v = ADRESH / 2; 結果を取得

Page 38: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

37

ADCON0 = HOL; 横方向入力チェック

Wait(1);

bGO = 1;

while(bGO);

adresult_h = ADRESH / 2;

}

if((adresult_v > 60) && (adresult_v < 70) && (adresult_h > 60) && (adresult_h < 70)){

入力が無かった時の処理

}

if(adresult_v > 70){上方向の入力があった時の処理}

if(adresult_v < 55){上方向の入力があった時の処理}

if(adresult_h > 70){右方向の入力があった時の処理}

if(adresult_h < 55){左方向の入力があった時の処理}

adflag は割り込みで定期的に true になる。

3. ブロックの移動及び判定関数

移動中のブロックのデータは 4×4 の配列(block[4][4])で表現しており、その位置情報は

変数 row(行)及び column(列)で把握している。移動の判定は以下に示す通りである。

下に移動の場合を例にする。図 23 は赤で囲まれた部分が移動中のブロックを示している。

移動先は D で埋められた部分で、LED が点灯している場合を1、消灯している場合を 0 と

すると、(An> 0 かつ Dn > 0)が成り立った時点で移動不可となる。左右に関しても同じ要

領である。(詳細は付録のソースコード参照)

A1 A2 A3 A4

D1 D2 D3 D4

図 23 下に移動する場合の移動判定概略図

Page 39: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

38

4. main 関数

詳細を省略した main 関数のソースコードを以下に示す。

while(1){

TMR0 = 60; タイマー0 の初期値をセット 4

if( (!np_flag) && adflag ){

ADC(); Joy Stick の入力を読む

adflag = FALSE;

}

if((adresult_v > 60) && (adresult_v < 70) && (adresult_h > 60) && (adresult_h < 70)){

Joy Stick の入力がなかった時の処理

}

if(adresult_v > 70){上方向の入力があった時の処理}

if(adresult_v < 40){下方向の入力があった時の処理}

if(adresult_h < 55){右方向の入力があった時の処理}

if(adresult_h > 70){左方向の入力があった時の処理}

switch ( np_flag ){

case 1: 次のブロックを生成する場合

省略

break;

case 0: ブロック移動中の場合

省略

break;

case 2: ゲームオーバーの場合

省略

While(1){ キー入力待ち、何れかの入力でゲーム再スタート

ADC();

if((adresult_v > 70) || (adresult_v < 40) || (adresult_h >

70)||(adresult_h < 55)){

INIT_ALL(); 各変数及びデータの初期化

break; }

Page 40: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

39

}

break;

}

while(!bT0IF){} タイマー0 オーバーフロー待ち

bT0IF = 0;

cnt0++;

cnt1++;

if(cnt0 == 9 ){ 9 回に 1 回 drop を TRUE(約 0.5s 周期でブロックが下に移動)

cnt0 = 0;

drop = TRUE;

}

if(cnt1 == 4 ){ 4 回に 1 回 adflag を TRUE

cnt1 = 0;

adflag = TRUE;

}

}

}

以上が主な関数である。表示回路のハードウェアを完成させ、個々の表示を制御するルー

チンが完成した後においても、何をどのように表示させるかという問題は別に解決しなけ

ればならず、その難しさも痛感した。

Page 41: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

40

第7章 総括

・今後の課題

ここで、今後の課題やアイデアとして思い当たるものを挙げておきたい。

・コントローラーの無線化

・ボタンやスイッチを増やして機能を拡張

・マスタの PIC をピン互換のある PIC18 シリーズに置き換えてみる。(メリットとして

プログラムメモリが増える、バンクの概念が無く、RAM の容量も大きいので vram を

圧縮する必要がなくなる可能性がある等が挙げられる)

・感想

本研究の目的のうち、回路作製能力の向上に関してはかなりの進歩があったと感じてい

る。特に、フラットパッケージの DFF アレイ IC における全ての各入力ラインは、一か所

の足から二本の配線をとる必要があり困難であった。思い起こせば、この半田付けにほぼ 1

カ月を費やした。毎日毎日何時間も(時には 20 時間位は製作をしていたであろうか)細か

い部品を見ながら細い線をつないでいく。

この単調な作業を飽きることなくやり通した原動力が何であったのか、今となっては多尐

不思議に感じない訳でもない。しかしながらこの作業が完了し、完成に近づいた日の事は

決して忘れることができない。完成したものには自分の“想い“が詰まっているような気

がした。

ソフトウェアに関しては、本研究室に所属するまで自分にとって未知の領域だったプロ

セッサを、多尐なりとも自分の構想通りに制御できるようになったのでは、と感じる。

Page 42: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

41

謝辞

今回の卒業研究及び卒表論文の作成にあたり、終始に丁寧で熱心なご指導とご教示を賜

りました高知工科大学工学部電子・光システム工学科綿森 道夫准教授に心からの感謝を

申し上げます。本研究は綿森道夫准教授のお力添えなしでは完成に至ることはなかったと

思います。

また、高知工科大学工学部電子・光システム工学科在学中に本研究実験遂行や学生生活、

その他各過程で終始ご厚意頂きました、高知工科大学電子・光システム工学科長 岩下 克

教授、成沢 忠教授、神戸 宏教授、河東田 隆教授、木村 正廣教授、八田 章光教授、

橘 昌良教授、矢野 政顕教授、真田 克教授、星野 孝総准教授、山本 真行准教授、

植田 和憲講師、杉田 彰久教育講師、高崎 敬雄教育講師、安岡 文子秘書、中山 愛

秘書の皆様には重ねて感謝の意を述べさせて頂きます。

Page 43: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

42

参考文献

電子工作のための PIC16F 活用ガイドブック 後閑 哲也 著 :技術評論社

8 ピン PIC マイコンの使い方がよくわかる本 後閑 哲也 著 :技術評論社

C 言語で作る PIC 電子工作 中尾 司 著 :CQ 出版社

PIC によるホーム・コントロール工作入門 中尾 司 著 :CQ 出版社

マイコンの 1 線 2 線 3 線インターフェース活用入門 中尾 司 著 :CQ 出版社

PIC と C 言語の電子工作 鈴木 哲哉 著 :ラトルズ

プリント基板で作る PIC 応用装置 鈴木 哲哉 著 :ラトルズ

電子回路シミュレータ入門 加藤 ただし 著 :講談社

よくわかる 3 次元 CAD システム Solid Works 入門 牛山 直樹 著 :日刊工業新聞社

よくわかる 3 次元 CAD システム実践 Solid Works 牛山 直樹 著 :日刊工業新聞社

やさしく学ぶ Jw_cad5 Obra Club 著 :エクスナレッジ

Page 44: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

43

付録 プログラムリスト

Page 45: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

44

スロットマシンソースコード

Page 46: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

45

//SlotMachine by Otsuka Masayuki

#include <p16f886.h>

#include <p16f886_bits.h>

#include <portbits.h>

#include <delays.h>

#include <maths.h>

#define TRUE 1

#define FALSE 0

#define CS1 1

#define CS2 2

#define CS 3

#define DISP_ON 0x3F

#define DISP_OFF 0x3E

#define STARTLINE 0xC0

#define PAGEADDRESS 0xB8

#define COLUMNADDRESS 0x40

#define READMODIFYRIGHT 0xE0

#define MODIFYEND 0xEE

#define PAGEMAX 8

#define BUSY 0x80

#define COLUMNMAX 0x40

#define SPMODE_ON 250

#define HAZURE 0

#define CHERRY 0x22

#define REPLAY 7

#define PRAM 0x0B

#define SUIKA 0x40

#define BIGBOUNUS1 0xC1

#define BIGBOUNUS2 0x0D

#define REG 0x7F

#define DIAGONAL_LINE1 0

#define DIAGONAL_LINE2 1

Page 47: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

46

#define TOP_LINE 2

#define MIDDLE_LINE 3

#define BOTTOM_LINE 4

#define LINE 5

#define LEFT 1

#define MIDDLE 2

#define RIGHT 3

void WriteCommand(BYTE comtype, BYTE channel);

void WriteData(BYTE data, BYTE channel);

void ClearLCD(void);

void InitLCD(void);

void DispPattern(const BYTE *patdata, BYTE cahnnel);

void WriteMidpattern(BYTE *pattern, BYTE line, BYTE position, BYTE breakpos,

BYTE p_width, BYTE p_hight, BYTE channel);

void LcatePattern(const BYTE *pattern, BYTE line, BYTE position, BYTE p_width,

BYTE p_hight, BYTE channel);

void ModifyDisp(BYTE startline, BYTE endline, BYTE startpos, BYTE endpos , BYTE

channel);

void Keycheck(void);

void DispChange(void);

void SelectDisp(BYTE state, BYTE line, BYTE button);

void Interrupt(void);

void FirstDisp(void);

void Disp_Credit(BYTE *keta, BYTE pos);

void Write_Number(const BYTE *keta, BYTE pos);

void Calc_Credit1();

void Calc_Credit2(BYTE state);

void Sp_Mode_Check(void);

BYTE keycheckflag = FALSE;

BYTE keyvalue1, keyvalue2;

BYTE keyLonflag = FALSE, keyMonflag = FALSE, keyRonflag = FALSE, keySonflag =

FALSE;

BYTE r_numL, r_numM, r_numR, r_numflag;

BYTE stateflag;

Page 48: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

47

BYTE lineflag, startflag = FALSE, selectflag = FALSE,creditflag = TRUE;

BYTE cnt = FALSE, cnt1 = FALSE, sp_cnt = FALSE;

BYTE stopL = FALSE, stopM = FALSE, stopR = FALSE, pushed, hazureflag = FALSE;

WORD credit_num = 50;

WORD r_num, sp_flag1 = FALSE, sp_flag2 = FALSE, sp_flag3 = FALSE;

const BYTE firstdispL1[4][64] = {

{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xE0,

0x60,0x70,0x70,0x70,0x70,0xF0,0xE0,0xE0,0x80,0x00,

0x00,0x00,0x00,0xE0,0xE0,0xE0,0x20,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00 },

{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x1E,0x3F,0x3F,0x7F,0x71,0xF0,

0xE0,0xE0,0xC0,0xC0,0x80,0x83,0x03,0x03,0x03,0x00,

0xC0,0xF8,0xFF,0x7F,0x0F,0x01,0x80,0xC0,0xE0,0xF0,

0x70,0x38,0x38,0x38,0x38,0xF8,0xF8,0xF0,0xC0,0x00,

0x00,0x38,0x38,0xF8,0xFC,0xFF,0x3F,0x3F,0x38,0x38,0x18,0x00,0x00,0x00 },

{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x7C,0xFC,0xFC,0xE0,0xC0,0xC0,0xC0,0xC0,0xC0,

0xE0,0xE1,0x7B,0x7F,0x3F,0x0F,0x00,0x80,0xF0,0xFE,

0x7F,0x0F,0x03,0x00,0x00,0x7E,0xFF,0xFF,0xE3,0xC0,

0xC0,0xC0,0xE0,0xF0,0x78,0x3F,0x1F,0x0F,0x01,0x00,

0x00,0xFC,0xFF,0xFF,0xC7,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00 },

{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,

0xC0,0xC0,0xC0,0xC0,0x01,0x01,0x01,0x01,0x01,0x01,

0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xC1,0x01,0x01,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,

0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0 }

};

Page 49: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

48

const BYTE firstdispL2[3][64] = {

{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFC,0xFF,

0x3F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x80,0xC0,0xF0,

0xF8,0x3E,0xFF,0xFF,0xFF,0x3F,0x0F,0x01,0x00,0xC0,

0xE0,0xE0,0x70,0x70,0x70,0x70,0xF0,0xF0,0xE0,0x00,

0x00,0x00,0x00,0x80,0xC0,0xC0,0xE0,0x60,0x70,0x70,

0x70,0xF0,0xF0,0xE0,0xC0,0x00,0x00,0x00,0xC0,0xF8,0xFF,0xFF,0xE7,0x61 },

{ 0x00,0x00,0x00,0x00,0xE0,0xFC,0xFF,0x7F,0x0F,0x01,

0x00,0xFF,0xFF,0xFF,0xF8,0x7C,0x1E,0x0F,0x07,0xC1,

0xF8,0xFF,0x7F,0x0F,0x01,0x00,0xF0,0xF8,0xF8,0x9C,

0x8C,0x8C,0x8C,0xCE,0xEE,0xFE,0xFF,0x3F,0x07,0x00,

0x00,0xF8,0xFE,0xFF,0xCF,0x83,0x00,0x80,0x80,0xC0,

0xF0,0xF0,0x71,0x11,0x01,0xC0,0xF8,0xFF,0x7F,0x0F,0x03,0x01,0x00,0x00 },

{ 0x00,0x00,0x00,0x03,0x03,0x03,0x01,0x00,0x00,0x00,

0x00,0x01,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x03,

0x03,0x01,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,

0x03,0x03,0x01,0x01,0x03,0x03,0x03,0x00,0x00,0x00,

0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x01,

0x01,0x00,0x00,0x00,0x00,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00 }

};

const BYTE firstdispR[5][64] = {

{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },

{ 0x70,0x70,0x70,0xF0,0xF0,0xE0,0x00,0x00,0x00,0xC0,

0xF0,0xF0,0x71,0x01,0x01,0xC0,0xF0,0xF0,0xF0,0xE0,

0x60,0x70,0x70,0x70,0xF0,0xF0,0xE0,0x00,0x00,0x00,

0x00,0xC0,0xC0,0xE0,0x60,0x30,0x30,0x30,0x70,0xF0,

0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },

{ 0xC0,0xF8,0xFF,0x7F,0x0F,0x01,0x80,0xF0,0xFE,0xFF,

Page 50: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

49

0x1F,0x03,0x80,0xF0,0xFE,0xFF,0x1F,0x03,0x01,0x00,

0x00,0x80,0xF0,0xFE,0xFF,0x1F,0x03,0x00,0x70,0xFE,

0xFF,0xFF,0x87,0x87,0x86,0x86,0xC6,0xE6,0xE6,0x67,

0x27,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },

{ 0x03,0x03,0x01,0x00,0x00,0x00,0x03,0x03,0x03,0x00,

0x00,0x00,0x03,0xE3,0xC3,0x00,0x00,0x00,0xC0,0xE0,

0x00,0x03,0x03,0x83,0x40,0x20,0x20,0x20,0x40,0x81,

0x01,0x83,0xC3,0x83,0x03,0x83,0x41,0x41,0x80,0x00,

0xC0,0x00,0x00,0x00,0xC0,0x00,0xC0,0x00,0x00,0xC0,

0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },

{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x1F,0x00,0x07,0x1C,0x07,0x00,0x1F,

0x00,0x10,0x00,0x07,0x08,0x10,0x10,0x10,0x08,0x07,

0x00,0x00,0x1F,0x10,0x00,0x09,0x12,0x12,0x0C,0x00,

0x0F,0x10,0x10,0x10,0x0F,0x00,0x1F,0x02,0x05,0x18,

0x00,0x0D,0x12,0x12,0x0A,0x1F,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }

};

const BYTE waku1[1] = {0xff};

const BYTE waku2[1] = {0x80};

const BYTE waku3[1] = {0x01};

const BYTE waku4[18] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,

0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81};

const BYTE wait_disp[25] = {0x7E, 0x20, 0x18, 0x20, 0x7E, 0x00, 0x2C, 0x54, 0x54,

0x7C,

0x40, 0x40, 0x00, 0x74, 0x00, 0x08, 0x7E, 0x48, 0x00,

0x40,

0x00, 0x40, 0x00, 0x40, 0x00};

const BYTE clrnum[4] = {0x00, 0x00, 0x00, 0x00};

const BYTE num0[4] = {0x7C, 0x82, 0x82, 0x7C};

const BYTE num1[4] = {0x84, 0xFE, 0x80, 0x00};

const BYTE num2[4] = {0xF2, 0x92, 0x92, 0x9E};

const BYTE num3[4] = {0x92, 0x92,0x92, 0xFE};

const BYTE num4[4] = {0x1E, 0x10, 0x10, 0xFE};

const BYTE num5[4] = {0x9E, 0x92, 0x92, 0xF2};

Page 51: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

50

const BYTE num6[4] = {0xFE, 0x90, 0x90, 0xF0};

const BYTE num7[4] = {0x02, 0x02, 0x02, 0xFE};

const BYTE num8[4] = {0xFE, 0x92, 0x92, 0xFE};

const BYTE num9[4] = {0x1E, 0x12, 0x12, 0xFE};

const BYTE dec_1[4] = {0x00, 0x08, 0x08, 0x08};

const BYTE win[18] = {0x80, 0x80, 0x80, 0x80, 0x80, 0xBE, 0x90, 0x88, 0x90, 0xBE,

0x80, 0xBE, 0x80, 0xBE, 0x84, 0x98, 0xA0, 0xBE};

const BYTE lose[18] = {0x80, 0xFF, 0xC0, 0xC0, 0xC0, 0xBE, 0xC1, 0xC1, 0xBE, 0x80,

0xA6, 0xC9, 0xC9, 0xB2, 0x80, 0xFF, 0xC9, 0xC9};

const BYTE credit[24] = {0x01, 0x39, 0x45, 0x45, 0x29, 0x01, 0x7D, 0x15, 0x69, 0x01,

0x7D, 0x55, 0x55, 0x01,

0x7D, 0x45, 0x45, 0x39, 0x00, 0x7D, 0x01, 0x05,

0x7D, 0x05};

const BYTE seven[2][22] = {

{ 0xFE, 0x02, 0x02, 0x02, 0x1E, 0xC8, 0x24, 0x22, 0x22, 0x22, 0x22,

0x22, 0xA2, 0x62, 0x24, 0x08, 0x04, 0x82, 0x42, 0x22, 0x12, 0x1E},

{0x01, 0x01, 0x01, 0x01, 0xE1, 0xA1, 0x90, 0x98, 0x8C, 0x82, 0x82,

0x81, 0x80, 0x80, 0x80, 0x80, 0x8F, 0xB0, 0xC0, 0x80, 0x00, 0x00}

};

const BYTE black_seven[2][22] = {

{0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF8, 0x3C, 0x3E, 0x3E, 0x3E, 0x3E,

0x3E, 0xBE, 0xFE, 0xFC, 0xF8, 0xFC, 0xFE, 0x7E, 0x3E, 0x1E, 0x1E},

{0x01, 0x01, 0x01, 0x01, 0xE1, 0xE1, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE,

0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xC0, 0x80, 0x00, 0x00}

};

const BYTE bar[2][22] = {

{0x00, 0xFC, 0xFC, 0x0C, 0x6C, 0x6C, 0x9C, 0xFC, 0x7C, 0x1C, 0x6C,

0x1C, 0x7C, 0xFC, 0x0C, 0x6C, 0x6C, 0x9C, 0xFC, 0xFC, 0xFC, 0x00},

{0x00, 0x1F, 0x1F, 0x18, 0x1B, 0x1B, 0x1C, 0x1F, 0x18, 0x1F, 0x1F,

0x1F, 0x18, 0x1F, 0x18, 0x1F, 0x1F, 0x1E, 0x18, 0x1F, 0x1F, 0x00}

};

const BYTE cherry[2][22] = {

{0x00, 0x00, 0x00, 0x00, 0x38, 0x60, 0xF8, 0xC0, 0x20, 0x20, 0x20,

0xC0, 0x80, 0x40, 0xB0, 0xE8, 0xB0, 0xC0, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x11, 0x11, 0x0E, 0x11,

Page 52: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

51

0x11, 0x11, 0x1F, 0x12, 0x1F, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x00}

};

const BYTE jac[2][22] = {

{0x00, 0x00, 0x00, 0xC0, 0x20, 0x10, 0x08, 0xE8, 0x08, 0x88, 0x68,

0x88, 0x08, 0xC8, 0x28, 0x28, 0x50, 0x20, 0xC0, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x00, 0x01, 0x02, 0x05, 0x0A, 0x0B, 0x08, 0x0B, 0x09,

0x0B, 0x08, 0x09, 0x0A, 0x0A, 0x05, 0x02, 0x01, 0x00, 0x00, 0x00}

};

const BYTE suika[2][22] = {

{0x00, 0x00, 0xC0, 0xA0, 0xD0, 0xA8, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4,

0xB4, 0xF4, 0x14, 0xEC, 0x54, 0x2C, 0x08, 0x50, 0xE0, 0x00, 0x00},

{0x00, 0x00, 0x03, 0x05, 0x0B, 0x15, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,

0x2D, 0x2F, 0x2C, 0x2B, 0x35, 0x3A, 0x14, 0x09, 0x07, 0x00, 0x00}

};

const BYTE pram[2][22] = {

{0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFE,

0xFE, 0xFE, 0xFC, 0xFE, 0xFC, 0x0A, 0x02, 0x14, 0x28, 0xC0, 0x00},

{0x00, 0x00, 0x0A, 0x15, 0x11, 0x21, 0x23, 0x17, 0x2F, 0x4F, 0x2F,

0x2F, 0x4F, 0x27, 0x13, 0x21, 0x15, 0x0A, 0x00, 0x00, 0x00, 0x00}

};

void main (void){

BYTE column;

ANSEL = 0;

ANSELH = 0;

CM1CON0 = 0;

CM2CON0 = 0;

ADCON0 = 0;

bRA4 = 0;

Wait(10);

bRA4 = 1;

TRISA = 0x00;

TRISB = 0xF0;

TRISC = 0x00;

Page 53: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

52

OPTION_REG = 0x02; //PORTB pull up, prescaler 1: 8

WPUB = 0xF0;

PORTB = 0x0E;

T1CON = 0x30; //timer1 prescaler 1 : 8

bTMR1IF = 0;

bTMR1IE = 1;

TMR1H = 0xC3;

TMR1L = 0x50;

InitLCD();

LcatePattern((BYTE *)firstdispL1, 0, 0, 64, 4, CS1);

LcatePattern((BYTE *)firstdispL2, 4, 0, 64, 3, CS1);

LcatePattern((BYTE *)firstdispR, 3, 0, 64, 5, CS2);

Wait(3000);

ClearLCD();

LcatePattern(wait_disp, 3, 0, 25, 1, CS);

Wait(2000);

ClearLCD();

FirstDisp();

srand(TMR0);

INTCON = 0xE0; //timer0 interrupt on

while(1) {

if(!sp_cnt) Sp_Mode_Check();

if(keycheckflag) Keycheck();

if(keySonflag){

for(column = 0; column < 18; column++){

LcatePattern((BYTE *)waku2, 3, column, 1, 1, CS1);

}

Write_Number(clrnum, 2);

Write_Number(clrnum, 7);

Page 54: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

53

Write_Number(clrnum, 12);

if(creditflag){

Calc_Credit1();

creditflag = FALSE;

}

if(selectflag){

if(cnt1 >= 21) cnt1 = 0;

else cnt1++;

if(!(cnt1 % 20)) srand(TMR0);

r_num = ((WORD)rand()) & 0x00FF;

r_numflag = (BYTE)r_num;

if(r_numflag){

if(sp_flag1 > SPMODE_ON)stateflag =

BIGBOUNUS1;

else if(sp_flag2 > SPMODE_ON)stateflag =

BIGBOUNUS2;

else if(sp_flag3 > SPMODE_ON)stateflag =

REG;

else if(r_numflag == BIGBOUNUS1)

stateflag = BIGBOUNUS1;

else if(r_numflag == BIGBOUNUS2)

stateflag = BIGBOUNUS2;

else if(r_numflag == REG) stateflag = REG;

else if(!(r_numflag % CHERRY)) stateflag =

CHERRY;

else if(!(r_numflag % SUIKA)) stateflag =

SUIKA;

else if(!(r_numflag % PRAM)) stateflag =

PRAM;

else if(!(r_numflag % REPLAY)) stateflag =

REPLAY;

else stateflag = HAZURE;

}else{

if(sp_flag1 > SPMODE_ON)stateflag =

BIGBOUNUS1;

Page 55: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

54

else if(sp_flag2 > SPMODE_ON)stateflag =

BIGBOUNUS2;

else if(sp_flag3 > SPMODE_ON)stateflag =

REG;

else stateflag = HAZURE;

}

selectflag = FALSE;

}

if(keyLonflag){

SelectDisp(stateflag, lineflag, pushed);

keyLonflag = FALSE;

}

if(keyMonflag){

SelectDisp(stateflag, lineflag, pushed);

keyMonflag = FALSE;

}

if(keyRonflag){

SelectDisp(stateflag, lineflag, pushed);

keyRonflag = FALSE;

}

}

if((stopL) && (stopM) && (stopR)){

bTMR1ON = 0;

startflag = FALSE;

stopL = FALSE;

stopM = FALSE;

stopR = FALSE;

Calc_Credit2(stateflag);

keySonflag = FALSE;

creditflag = TRUE;

sp_flag1 = FALSE;

sp_flag2 = FALSE;

sp_flag3 = FALSE;

}

Page 56: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

55

if(startflag) DispChange();

}

}

void FirstDisp(void){

BYTE page, column;

for(page = 0; page < 6; page++){

LcatePattern(waku1,1 + page, 19, 1, 1, CS1);

LcatePattern(waku1,1 + page, 50, 1, 1, CS2);

}

for(column = 0; column < 45; column++){

LcatePattern(waku2, 0, 19 + column, 1, 1, CS1);

}

for(column = 0; column < 40; column++){

LcatePattern(waku3, 7, 24 + column, 1, 1, CS1);

}

for(column = 0; column < 51; column++){

LcatePattern(waku2, 0, 0 + column, 1, 1, CS2);

LcatePattern(waku3, 7, 0 + column, 1, 1, CS2);

}

LcatePattern(waku1, 4, 0, 1, 1, CS1);

LcatePattern(waku1, 4, 17, 1, 1, CS1);

for(column = 0; column < 18; column++){

LcatePattern(waku2, 3, column, 1, 1, CS1);

}

LcatePattern(waku4, 5, 0, 18, 1, CS1);

LcatePattern(waku1, 6, 0, 1, 1, CS1);

LcatePattern(waku1, 6, 17, 1, 1, CS1);

LcatePattern(num5, 6, 7, 4, 1, CS1);

LcatePattern(num0, 6, 12, 4, 1, CS1);

LcatePattern(credit, 7, 0, 24, 1, CS1);

LcatePattern((BYTE *)suika, 1, 27, 22, 2, CS1);

LcatePattern((BYTE *)pram, 3, 27, 22, 2, CS1);

LcatePattern((BYTE *)black_seven, 5, 27, 22, 2, CS1);

Page 57: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

56

LcatePattern((BYTE *)black_seven, 1, 21, 22, 2, CS2);

LcatePattern((BYTE *)pram, 3, 21, 22, 2, CS2);

LcatePattern((BYTE *)suika, 5, 21, 22, 2, CS2);

WriteMidpattern((BYTE *)suika, 1, 56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)black_seven, 3, 56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)jac, 5, 56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)suika, 1, 0, 14, 22, 2, CS2);

WriteMidpattern((BYTE *)black_seven, 3, 0, 14, 22, 2, CS2);

WriteMidpattern((BYTE *)jac, 5, 0, 14, 22, 2, CS2);

}

void SelectDisp(BYTE state, BYTE line, BYTE button){

switch(state){

case BIGBOUNUS2:

if(button == LEFT){

LcatePattern((BYTE *)seven, 1, 27, 22, 2, CS1);

LcatePattern((BYTE *)suika, 3, 27, 22, 2, CS1);

LcatePattern((BYTE *)pram, 5, 27, 22, 2, CS1);

stopL = TRUE;

}else if(button == MIDDLE){

WriteMidpattern((BYTE *)seven, 1, 56, 8, 22, 2,

CS1);

WriteMidpattern((BYTE *)cherry, 3, 56, 8, 22, 2,

CS1);

WriteMidpattern((BYTE *)jac, 5, 56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)seven, 1, 0, 14, 22, 2,

CS2);

WriteMidpattern((BYTE *)cherry, 3, 0, 14, 22, 2,

CS2);

WriteMidpattern((BYTE *)jac, 5, 0, 14, 22, 2, CS2);

stopM = TRUE;

}else{

LcatePattern((BYTE *)seven, 1, 21, 22, 2, CS2);

Page 58: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

57

LcatePattern((BYTE *)pram, 3, 21, 22, 2, CS2);

LcatePattern((BYTE *)suika, 5, 21, 22, 2, CS2);

stopR = TRUE;

}

break;

case CHERRY:

if(button == LEFT){

LcatePattern((BYTE *)cherry, 1, 27, 22, 2, CS1);

LcatePattern((BYTE *)suika, 3, 27, 22, 2, CS1);

LcatePattern((BYTE *)pram, 5, 27, 22, 2, CS1);

stopL = TRUE;

}

else if(button == MIDDLE) stopM = TRUE;

else stopR = TRUE;

break;

case REG:

if(button == LEFT){

LcatePattern((BYTE *)bar, 1, 27, 22, 2, CS1);

LcatePattern((BYTE *)pram, 3, 27, 22, 2, CS1);

LcatePattern((BYTE *)jac, 5, 27, 22, 2, CS1);

stopL = TRUE;

}else if(button == MIDDLE){

WriteMidpattern((BYTE *)cherry, 1, 56, 8, 22, 2,

CS1);

WriteMidpattern((BYTE *)bar, 3, 56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)jac, 5, 56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)cherry, 1, 0, 14, 22, 2,

CS2);

WriteMidpattern((BYTE *)bar, 3, 0, 14, 22, 2, CS2);

WriteMidpattern((BYTE *)jac, 5, 0, 14, 22, 2, CS2);

stopM = TRUE;

}else{

LcatePattern((BYTE *)bar, 1, 21, 22, 2, CS2);

LcatePattern((BYTE *)pram, 3, 21, 22, 2, CS2);

LcatePattern((BYTE *)bar, 5, 21, 22, 2, CS2);

stopR = TRUE;

Page 59: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

58

}

break;

case REPLAY:

if(button == LEFT){

LcatePattern((BYTE *)black_seven, 1, 27, 22, 2,

CS1);

LcatePattern((BYTE *)jac, 3, 27, 22, 2, CS1);

LcatePattern((BYTE *)suika, 5, 27, 22, 2, CS1);

stopL = TRUE;

}else if(button == MIDDLE){

WriteMidpattern((BYTE *)black_seven, 1, 56, 8, 22,

2, CS1);

WriteMidpattern((BYTE *)jac, 3, 56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)pram, 5, 56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)black_seven, 1, 0, 14, 22,

2, CS2);

WriteMidpattern((BYTE *)jac, 3, 0, 14, 22, 2, CS2);

WriteMidpattern((BYTE *)pram, 5, 0, 14, 22, 2, CS2);

stopM = TRUE;

}else{

LcatePattern((BYTE *)suika, 1, 21, 22, 2, CS2);

LcatePattern((BYTE *)jac, 3, 21, 22, 2, CS2);

LcatePattern((BYTE *)seven, 5, 21, 22, 2, CS2);

stopR = TRUE;

}

break;

default:

if(button == LEFT){

LcatePattern((BYTE *)suika, 1, 27, 22, 2, CS1);

LcatePattern((BYTE *)pram, 3, 27, 22, 2, CS1);

LcatePattern((BYTE *)black_seven, 5, 27, 22, 2,

CS1);

stopL = TRUE;

}else if(button == MIDDLE){

if(state == PRAM){

Page 60: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

59

WriteMidpattern((BYTE *)jac, 1, 56, 8, 22, 2,

CS1);

WriteMidpattern((BYTE *)pram, 3, 56, 8, 22,

2, CS1);

WriteMidpattern((BYTE *)black_seven, 5,

56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)jac, 1, 0, 14, 22, 2,

CS2);

WriteMidpattern((BYTE *)pram, 3, 0, 14, 22,

2, CS2);

WriteMidpattern((BYTE *)black_seven, 5, 0,

14, 22, 2, CS2);

}else if((state == SUIKA) || (state ==

BIGBOUNUS1)){

WriteMidpattern((BYTE *)suika, 1, 56, 8, 22,

2, CS1);

WriteMidpattern((BYTE *)black_seven, 3,

56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)jac, 5, 56, 8, 22, 2,

CS1);

WriteMidpattern((BYTE *)suika, 1, 0, 14, 22,

2, CS2);

WriteMidpattern((BYTE *)black_seven, 3, 0,

14, 22, 2, CS2);

WriteMidpattern((BYTE *)jac, 5, 0, 14, 22, 2,

CS2);

}

stopM = TRUE;

}else if(button == RIGHT){

if((state == PRAM) || (state == BIGBOUNUS1)){

LcatePattern((BYTE *)black_seven, 1, 21,

22, 2, CS2);

LcatePattern((BYTE *)pram, 3, 21, 22, 2,

CS2);

LcatePattern((BYTE *)suika, 5, 21, 22, 2,

CS2);

Page 61: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

60

}else if(state == SUIKA){

LcatePattern((BYTE *)suika, 1, 21, 22, 2,

CS2);

LcatePattern((BYTE *)jac, 3, 21, 22, 2, CS2);

LcatePattern((BYTE *)seven, 5, 21, 22, 2,

CS2);

}

stopR = TRUE;

}

}

}

void Sp_Mode_Check(void){

keyvalue1 = PORTB; //read portb

if(!( keyvalue1 & 0x80)){

Wait(10); //wait for 10ms

keyvalue2 = PORTB; //read portb

if(!(keyvalue2 & 0x80)) sp_flag1++;

}

keyvalue1 = PORTB; //read portb

if(!(keyvalue1 & 0x40)){

Wait(10); //wait for 10ms

keyvalue2 = PORTB; //read portb

if(!(keyvalue2 & 0x40)) sp_flag2++;

}

keyvalue1 = PORTB; //read portb

if(!(keyvalue1 & 0x20)){

Wait(10); //wait for 10ms

keyvalue2 = PORTB; //read portb

if(!(keyvalue2 & 0x20)) sp_flag3++;

}

}

void Keycheck(void){

if(creditflag){

Page 62: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

61

keyvalue1 = PORTB; //read portb

if(!(keyvalue1 & 0x10)){

Wait(10); //wait for 10ms

keyvalue2 = PORTB; //read portb

if(!(keyvalue2 & 0x10)){

keySonflag = TRUE;

selectflag = TRUE;

bTMR1ON = 1;

}

}

}

if(keySonflag){

keyvalue1 = PORTB; //read portb

if(!( keyvalue1 & 0x80)){

Wait(10); //wait for 10ms

keyvalue2 = PORTB; //read portb

if(!(keyvalue2 & 0x80)){

keyLonflag = TRUE;

pushed = LEFT;

sp_cnt = TRUE;

}

}

keyvalue1 = PORTB; //read portb

if(!(keyvalue1 & 0x40)){

Wait(10); //wait for 10ms

keyvalue2 = PORTB; //read portb

if(!(keyvalue2 & 0x40)){

keyMonflag = TRUE;

pushed = MIDDLE;

}

}

keyvalue1 = PORTB; //read portb

if(!(keyvalue1 & 0x20)){

Wait(10); //wait for 10ms

keyvalue2 = PORTB; //read portb

if(!(keyvalue2 & 0x20)){

Page 63: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

62

keyMonflag = TRUE;

pushed = RIGHT;

}

}

}

keycheckflag = FALSE;

}

void DispChange(void){

if(cnt == 5) cnt = 0;

switch(cnt){

case 0:

if(!stopL){

LcatePattern((BYTE *)pram, 1, 27, 22, 2,

CS1);

LcatePattern((BYTE *)jac, 3, 27, 22, 2, CS1);

LcatePattern((BYTE *)black_seven, 5, 27,

22, 2, CS1);

}

if(!stopR){

LcatePattern((BYTE *)cherry, 1, 21, 22, 2,

CS2);

LcatePattern((BYTE *)black_seven, 3, 21,

22, 2, CS2);

LcatePattern((BYTE *)pram, 5, 21, 22, 2,

CS2);

}

if(!stopM){

WriteMidpattern((BYTE *)black_seven, 1,

56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)cherry, 3, 56, 8,

22, 2, CS1);

WriteMidpattern((BYTE *)jac, 5, 56, 8, 22, 2,

CS1);

WriteMidpattern((BYTE *)black_seven, 1, 0,

14, 22, 2, CS2);

Page 64: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

63

WriteMidpattern((BYTE *)cherry, 3, 0, 14,

22, 2, CS2);

WriteMidpattern((BYTE *)jac, 5, 0, 14, 22, 2,

CS2);

}

break;

case 1:

if(!stopL){

LcatePattern((BYTE *)jac, 1, 27, 22, 2, CS1);

LcatePattern((BYTE *)pram, 3, 27, 22, 2,

CS1);

LcatePattern((BYTE *)suika, 5, 27, 22, 2,

CS1);

}

if(!stopR){

LcatePattern((BYTE *)jac, 1, 21, 22, 2, CS2);

LcatePattern((BYTE *)cherry, 3, 21, 22, 2,

CS2);

LcatePattern((BYTE *)pram, 5, 21, 22, 2,

CS2);

}

if(!stopM){

WriteMidpattern((BYTE *)pram, 1, 56, 8, 22,

2, CS1);

WriteMidpattern((BYTE *)seven, 3, 56, 8, 22,

2, CS1);

WriteMidpattern((BYTE *)cherry, 5, 56, 8,

22, 2, CS1);

WriteMidpattern((BYTE *)seven, 3, 0, 14, 22,

2, CS2);

WriteMidpattern((BYTE *)cherry, 5, 0, 14,

22, 2, CS2);

}

break;

case 2:

if(!stopL){

Page 65: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

64

LcatePattern((BYTE *)bar, 1, 27, 22, 2,

CS1);

LcatePattern((BYTE *)pram, 3, 27, 22, 2,

CS1);

LcatePattern((BYTE *)jac, 5, 27, 22, 2, CS1);

}

if(!stopR){

LcatePattern((BYTE *)jac, 1, 21, 22, 2, CS2);

LcatePattern((BYTE *)cherry, 3, 21, 22, 2,

CS2);

LcatePattern((BYTE *)bar, 5, 21, 22, 2,

CS2);

}

if(!stopM){

WriteMidpattern((BYTE *)jac, 1, 56, 8, 22, 2,

CS1);

WriteMidpattern((BYTE *)pram, 3, 56, 8, 22,

2, CS1);

WriteMidpattern((BYTE *)cherry, 5, 56, 8,

22, 2, CS1);

WriteMidpattern((BYTE *)jac, 1, 0, 14, 22, 2,

CS2);

WriteMidpattern((BYTE *)pram, 3, 0, 14, 22,

2, CS2);

WriteMidpattern((BYTE *)cherry, 5, 0, 14,

22, 2, CS2);

}

break;

case 3:

if(!stopL){

LcatePattern((BYTE *)pram, 1, 27, 22, 2,

CS1);

LcatePattern((BYTE *)jac, 3, 27, 22, 2, CS1);

LcatePattern((BYTE *)seven, 5, 27, 22, 2,

CS1);

}

Page 66: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

65

if(!stopR){

LcatePattern((BYTE *)pram, 1, 21, 22, 2,

CS2);

LcatePattern((BYTE *)bar, 3, 21, 22, 2,

CS2);

LcatePattern((BYTE *)jac, 5, 21, 22, 2, CS2);

}

if(!stopM){

WriteMidpattern((BYTE *)suika, 1, 56, 8, 22,

2, CS1);

WriteMidpattern((BYTE *)black_seven, 3,

56, 8, 22, 2, CS1);

WriteMidpattern((BYTE *)jac, 5, 56, 8, 22, 2,

CS1);

WriteMidpattern((BYTE *)suika, 1, 0, 14, 22,

2, CS2);

WriteMidpattern((BYTE *)black_seven, 3, 0,

14, 22, 2, CS2);

WriteMidpattern((BYTE *)jac, 5, 0, 14, 22, 2,

CS2);

}

break;

case 4:

if(!stopL){

LcatePattern((BYTE *)suika, 1, 27, 22, 2,

CS1);

LcatePattern((BYTE *)pram, 3, 27, 22, 2,

CS1);

LcatePattern((BYTE *)seven, 5, 27, 22, 2,

CS1);

}

if(!stopR){

LcatePattern((BYTE *)jac, 1, 21, 22, 2, CS2);

LcatePattern((BYTE *)cherry, 3, 21, 22, 2,

CS2);

Page 67: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

66

LcatePattern((BYTE *)pram, 5, 21, 22, 2,

CS2);

}

if(!stopM){

WriteMidpattern((BYTE *)pram, 1, 56, 8, 22,

2, CS1);

WriteMidpattern((BYTE *)cherry, 3, 56, 8,

22, 2, CS1);

WriteMidpattern((BYTE *)bar, 5, 56, 8, 22, 2,

CS1);

WriteMidpattern((BYTE *)pram, 1, 0, 14, 22,

2, CS2);

WriteMidpattern((BYTE *)cherry, 3, 0, 14,

22, 2, CS2);

WriteMidpattern((BYTE *)bar, 5, 0, 14, 22, 2,

CS2);

}

break;

default:

break;

}

cnt++;

startflag = FALSE;

}

void WriteCommand(BYTE comtype, BYTE channel){

switch(channel){

case CS1:

PORTA = 0x18; //R/W->0, A0->0, CS1->1

break;

case CS2:

PORTA = 0x30; //R/W->0, A0->0, CS2->1

break;

case CS:

PORTA = 0x38; //R/W->0, A0->0, CS1->1, CS2->1

break;

Page 68: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

67

default:

PORTA = 0x10;

break;

}

bRA0 = 1; //Enable high

PORTC = comtype; //command out

bRA0 = 0; //Enable low

}

void WriteData(BYTE datapattern, BYTE channel){

switch(channel){

case CS1:

PORTA = 0x1c; //R/W->0, A0->1, CS1->1

break;

case CS2:

PORTA = 0x34; //R/W->0, A0->1, CS2->1

break;

case CS:

PORTA = 0x3c; //R/W->0, A0->1, CS1->1, CS2->1

break;

default:

PORTA = 0x10;

break;

}

bRA0 = 1; //Enable high

PORTC = datapattern; //data out

bRA0 = 0; //Enable low

}

void ClearLCD(void){

BYTE page, column;

for (page = 0; page < PAGEMAX; page++){

WriteCommand(PAGEADDRESS + page, CS);

WriteCommand(COLUMNADDRESS + 0, CS);

for(column = 0; column < COLUMNMAX; column++)

Page 69: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

68

WriteData(0, CS); //pattern display

}

WriteCommand(STARTLINE + 0, CS);

}

void InitLCD(void){

Wait(50);

WriteCommand(DISP_ON, CS); //display on for CS1 and CS2

ClearLCD();

}

void DispPattern(const BYTE *patdata, BYTE channel){

BYTE page, column;

BYTE *initialaddress = patdata;

for(page = 0; page < PAGEMAX; page++){

WriteCommand(PAGEADDRESS + page, channel);

WriteCommand(COLUMNADDRESS + 0, channel);

patdata = initialaddress;

for(column = 0; column < COLUMNMAX; column++ ){

WriteData(*patdata, channel);

patdata++;

}

initialaddress += COLUMNMAX; //point to next address

#pragma asmline NOP

}

}

void WriteMidpattern(BYTE *pattern, BYTE line, BYTE position, BYTE breakpos,

BYTE p_width, BYTE p_hight, BYTE channel){

BYTE page, column;

for(page = 0; page < p_hight; page++){

WriteCommand(PAGEADDRESS + line, channel);

WriteCommand(COLUMNADDRESS + position, channel);

for(column = 0; column < breakpos; column++){

Page 70: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

69

if(channel == CS1){

WriteData(pattern[column], channel);

}else{

WriteData(pattern[column + (p_width - breakpos)],

channel);

}

}

pattern += p_width;

line++;

#pragma asmline NOP

}

}

void LcatePattern(const BYTE *pattern, BYTE line, BYTE position, BYTE p_width,

BYTE p_hight, BYTE channel){

BYTE page, column;

for(page = 0; page < p_hight; page++){

WriteCommand(PAGEADDRESS + line, channel);

WriteCommand(COLUMNADDRESS + position, channel);

for(column = 0; column < p_width; column++){

WriteData(pattern[column], channel);

}

pattern += p_width;

line++;

#pragma asmline NOP

}

}

void Write_Number(const BYTE *keta, BYTE pos){

BYTE column;

WriteCommand(PAGEADDRESS + 4, CS1);

WriteCommand(COLUMNADDRESS + pos, CS1);

Page 71: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

70

for(column = 0; column < 4; column++){

WriteData(keta[column], CS1);

}

}

void Disp_Credit(BYTE *keta, BYTE pos){

BYTE column;

WriteCommand(PAGEADDRESS + 6, CS1);

WriteCommand(COLUMNADDRESS + pos, CS1);

for(column = 0; column < 4; column++){

WriteData(keta[column], CS1);

}

}

void Calc_Credit1(){

WORD c_temp;

BYTE ans, cnt = 0;

BYTE denominator = 10;

if(creditflag){

if(credit_num < 3) credit_num = 50;

credit_num -= 3;

}

c_temp = credit_num;

while(c_temp >= denominator){

ans = c_temp % denominator;

if(!cnt) Disp_Credit(num0 +ans * 4, 12);

else if(cnt == 1) Disp_Credit(num0 + ans * 4, 7);

ans = c_temp / denominator;

c_temp = ans;

cnt++;

}

if(!cnt){

Page 72: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

71

Disp_Credit(num0 + c_temp * 4, 12);

Disp_Credit(clrnum , 7);

}

else if(cnt ==1){

Disp_Credit(num0 + c_temp * 4, 7);

Disp_Credit(clrnum , 2);

}

else if(cnt == 2) Disp_Credit(num0 + c_temp * 4, 2);

}

void Calc_Credit2(BYTE state){

switch(state){

case BIGBOUNUS1:

bRB1 = 0;

Wait(10);

bRB1 = 1;

credit_num += 300;

Calc_Credit1();

LcatePattern(win, 3, 0, 18, 1, CS1);

Write_Number(num3, 2);

Write_Number(num0, 7);

Write_Number(num0, 12);

break;

case BIGBOUNUS2:

bRB2 = 0;

Wait(10);

bRB2 = 1;

credit_num += 200;

Calc_Credit1();

LcatePattern(win, 3, 0, 18, 1, CS1);

Write_Number(num2, 2);

Write_Number(num0, 7);

Write_Number(num0, 12);

break;

case CHERRY:

Page 73: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

72

credit_num += 2;

Calc_Credit1();

LcatePattern(win, 3, 0, 18, 1, CS1);

Write_Number(num2, 12);

break;

case REG:

bRB3 = 0;

Wait(10);

bRB3 = 1;

credit_num += 100;

Calc_Credit1();

LcatePattern(win, 3, 0, 18, 1, CS1);

Write_Number(num1, 2);

Write_Number(num0, 7);

Write_Number(num0, 12);

break;

case REPLAY:

credit_num += 3;

Calc_Credit1();

LcatePattern(win, 3, 0, 18, 1, CS1);

Write_Number(num3, 12);

break;

case PRAM:

credit_num += 10;

Calc_Credit1();

LcatePattern(win, 3, 0, 18, 1, CS1);

Write_Number(num0, 12);

Write_Number(num1, 7);

break;

case SUIKA:

credit_num += 15;

Calc_Credit1();

LcatePattern(win, 3, 0, 18, 1, CS1);

Write_Number(num5, 12);

Write_Number(num1, 7);

break;

Page 74: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

73

default:

LcatePattern(lose, 3, 0, 18, 1, CS1);

Write_Number(num3, 12);

Write_Number(dec_1, 7);

break;

}

}

void Interrupt(void){

if(bT0IF){

TMR0 = 0;

keycheckflag = TRUE;

bT0IF = 0;

}

if(bTMR1IF){

TMR1H = 0xC3;

TMR1L = 0x50;

startflag = TRUE;

bTMR1IF = 0;

}

}

Page 75: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

74

テトリスソースコード(master)

Page 76: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

75

#include <P16F887.h>

#include <PortBits.h>

#include <P16F887_bits.h>

#include <datalib.h>

#include <delays.h>

#include <strings.h>

#include <maths.h>

#define TRUE 0x01

#define FALSE 0

#define VERT 0x45

#define HOL 0x41

#define LCD_ADDRESS 0x7c

#define SL_1_ADDRESS 0x02

#define SL_2_ADDRESS 0x04

#define SL_3_ADDRESS 0x06

#define SL_4_ADDRESS 0x08

void INIT_ALL(void);

void Init_Map_Data(void);

void ADC(void);

BYTE Next_Block(void);

void Pat_Select(BYTE patt);

void Send_Mapdata_to_Slave(BYTE slave_address);

void Send_Blank_Block_Data(BYTE slave_address, WORD row_cnt, BYTE

column_cnt);

void Send_Current_Block_Data(BYTE slave_address, WORD row_cnt, BYTE

column_cnt);

void Move_Left(void);

void Move_Right(void);

void Rotate(void);

void Del_Current_Block(WORD row_cnt);

void Write(void);

BYTE com_write(BYTE command);

void Send_Data_LCD(BYTE data);

void I2C_LCD_init(void);

Page 77: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

76

void strdata_write(char *str, BYTE num);

BYTE enable_hol(WORD row_cnt);

BYTE enable_down(WORD row_cnt);

void copy_block_to_map(WORD row_cnt);

BYTE lines_of_delete(void);

BYTE isGameover(void);

void Check_bottom(void);

void down(void);

void calc_score(BYTE del_number);

BYTE block[4][4]; //moving piece data

BYTE line_data[4]; //data for one line

BYTE upper_map[9][6];

BYTE lower_map[9][6]; //lower map data

BYTE temp[4][4], temp_map[4];

char buf[15];

BYTE np_flag = 1;

BYTE adresult_v = 60 ,adresult_h = 60, adflag = 0;

BYTE drop = FALSE;

BYTE pattern;

BYTE cnt0 = 0, cnt1 = 1;

BYTE left = 0, right = 0;

BYTE i, j, k, m, n, start_pt, evenflag, bottom_line, sum, del, mojisu;

BYTE temp_block1, temp_block2, temp_block3;

WORD row = 0;

BYTE column = 0x0a;

int score = 0;

void main(void){

OSCCON = 0x60; //clock = 4MHz

ANSEL = 0x03; //RA0, RA1 analog input

ANSELH = 0;

ADCON1 = 0; //ADconverter enable

CM1CON0 = 0;

Page 78: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

77

CM2CON0 = 0;

TRISA = 0x03; //RA0, RA1 input

TRISB = 0x07; //RB0, RB1, RB2 input

TRISC = 0x18; //RC3, RC4 input

TRISD = 0; //all ports are output

SSPCON = 0x08; //I2C master mode

SSPSTAT = 0x80;

SSPADD = 0x04;

OPTION_REG = 0x07; //PORTB pull up enable,

Timer0 prescaler 1:256

WPUB = 0x07;

bSSPEN = 1; //I2C enable

PR2 = 6;

T2CON = 0x04; // timer2 on

PORTA = 0;

PORTB = 0;

PORTC = 0;

PORTD = 0;

INIT_ALL();

while(1){

TMR0 = 60;

if( (!np_flag) && adflag ){

ADC();

adflag = FALSE;

}

if((adresult_v > 60) && (adresult_v < 70) &&

(adresult_h > 60) && (adresult_h < 70)){

}

if(adresult_v > 70){

Del_Current_Block(row);

Wait(1);

Page 79: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

78

Rotate();

Write();

adresult_v = 60;

}

if(adresult_v < 40){

down();

score += 1;

}

if(adresult_h < 55){

Del_Current_Block(row);

Move_Right();

Write();

adresult_h = 60;

}

if(adresult_h > 70){

Del_Current_Block(row);

Move_Left();

Write();

adresult_h = 60;

}

switch ( np_flag ){

case 1: // ********* start

condition

pattern = Next_Block();

Pat_Select(pattern);

Send_Mapdata_to_Slave(SL_1_ADDRESS);

Send_Mapdata_to_Slave(SL_2_ADDRESS);

Send_Mapdata_to_Slave(SL_3_ADDRESS);

Send_Mapdata_to_Slave(SL_4_ADDRESS);

if ( column > 2 && column < 12 )

Page 80: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

79

Send_Current_Block_Data( SL_1_ADDRESS, row +

0x10, column);

if ( column > 8 && column < 18 )

Send_Current_Block_Data( SL_2_ADDRESS, row +

0x10, column - 6);

np_flag = 0;

break;

case 0: // ************

block down condition

if( drop ){

down();

}

break;

case 2: // Game Over

state

com_write(0x01);

com_write(0x83);

Send_Data_LCD('G');

Send_Data_LCD('A');

Send_Data_LCD('M');

Send_Data_LCD('E');

Send_Data_LCD(' ');

Send_Data_LCD('O');

Send_Data_LCD('V');

Send_Data_LCD('E');

Send_Data_LCD('R');

while(1){

ADC();

if((adresult_v > 70) ||

(adresult_v < 40) || (adresult_h > 70) || (adresult_h < 55)){

INIT_ALL();

np_flag = 1;

row = 0;

column = 0x0a;

Page 81: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

80

score = 0;

break;

}

}

break;

}

while(!bT0IF){}

bT0IF = 0;

cnt0++;

cnt1++;

if(cnt0 == 9 ){

cnt0 = 0;

drop = TRUE;

}

if(cnt1 == 4 ){

cnt1 = 0;

adflag = TRUE;

}

}

}

void INIT_ALL(void){

Init_Map_Data();

Send_Mapdata_to_Slave(SL_1_ADDRESS);

Send_Mapdata_to_Slave(SL_2_ADDRESS);

Send_Mapdata_to_Slave(SL_3_ADDRESS);

Send_Mapdata_to_Slave(SL_4_ADDRESS);

for(i = 0; i < 3; i++){

PORTA = 0x70;

PORTB = 0x38;

PORTC = 0xa6;

PORTD = 0x11;

Wait(500);

PORTA = 0;

Page 82: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

81

PORTB = 0;

PORTC = 0;

PORTD = 0;

Wait(500);

}

I2C_LCD_init();

com_write(0x84);

Send_Data_LCD('S');

Send_Data_LCD('T');

Send_Data_LCD('A');

Send_Data_LCD('R');

Send_Data_LCD('T');

Send_Data_LCD('!');

Send_Data_LCD('!');

Wait(1000);

com_write(0x01);

com_write(0x80);

Send_Data_LCD('S');

Send_Data_LCD('C');

Send_Data_LCD('O');

Send_Data_LCD('R');

Send_Data_LCD('E');

com_write(0x8f);

Send_Data_LCD('0');

srand(TMR0);

}

void ADC(void){

ADCON0 = VERT;

bGO = 1;

while(bGO);

adresult_v = ADRESH / 2;

Page 83: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

82

ADCON0 = HOL;

Wait(1);

bGO = 1;

while(bGO);

adresult_h = ADRESH / 2;

}

void Check_bottom(void){

if ( block[3][0] + block[3][1] + block[3][2] + block[3][3] )

bottom_line = 3;

else if ( block[2][0] + block[2][1] + block[2][2] +

block[2][3] ) bottom_line = 2;

else if ( block[1][0] + block[1][1] + block[1][2] +

block[1][3] ) bottom_line = 1;

else bottom_line = 0;

}

void copy_block_to_map(WORD row_cnt){

start_pt = column / 2;

evenflag = column % 2;

Check_bottom();

for(i = 0; i < bottom_line + 1; i++ ) {

if(row_cnt < 9)

if ( evenflag ) {

temp_block1 = block[i][0];

temp_block2 = block[i][1] * 16 +

block[i][2];

temp_block3 = block[i][3] * 16;

if ( start_pt > 2 )

Page 84: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

83

upper_map[row_cnt][start_pt - 3] |= temp_block1;

if ( start_pt > 1 )

upper_map[row_cnt][start_pt - 2] |= temp_block2;

if ( start_pt > 0)

upper_map[row_cnt][start_pt - 1] |= temp_block3;

} else {

temp_block1 = block[i][0] * 16 +

block[i][1];

temp_block2 = block[i][2] * 16 +

block[i][3];

if ( start_pt > 2 )

upper_map[row_cnt][start_pt - 3] |= temp_block1;

if ( start_pt > 1 )

upper_map[row_cnt][start_pt - 2] |= temp_block2;

}

else if ( row_cnt < 18 )

if ( evenflag ) {

temp_block1 = block[i][0];

temp_block2 = block[i][1] * 16 +

block[i][2];

temp_block3 = block[i][3] * 16;

if ( start_pt > 2 )

lower_map[row_cnt -

9][start_pt - 3] |= temp_block1;

if ( start_pt > 1 )

lower_map[row_cnt -

9][start_pt - 2] |= temp_block2;

if ( start_pt > 0 )

lower_map[row_cnt -

9][start_pt - 1] |= temp_block3;

} else {

temp_block1 = block[i][0] * 16 +

Page 85: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

84

block[i][1];

temp_block2 = block[i][2] * 16 +

block[i][3];

if ( start_pt > 2 )

lower_map[row_cnt -

9][start_pt - 3] |= temp_block1;

if ( start_pt > 1 )

lower_map[row_cnt -

9][start_pt - 2] |= temp_block2;

}

row_cnt++;

}

}

BYTE lines_of_delete(void){

BYTE led_on, del_num = 0;

int i;

for(m = 0; m < 2; m++){

for(i = 8; i >= 0; i--){

for(n = 0; n < 4; n++){

led_on = 0;

for(j = 0; j < 6; j++){

if(m == 0){

if((lower_map[i][j]

& 0xf0) && (lower_map[i][j] & 0x0f)) led_on++;

}else{

if((upper_map[i][j]

& 0xf0) && (upper_map[i][j] & 0x0f)) led_on++;

}

}

if(led_on == 6){

del_num++;

if(m == 0){

if(i){

Page 86: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

85

for(j = i; j

> 0; j--){

for(k = 0; k < 6; k++) lower_map[j][k] = lower_map[j -

1][k];

}

}

for(k = 0; k < 6;

k++) lower_map[0][k] = upper_map[8][k];

for(j = 8; j > 0; j--){

for(k = 0;

k < 6; k++) upper_map[j][k] = upper_map[j - 1][k];

}

for(j = 0; j < 6; j++)

upper_map[0][j] = 0;

}else{

if(i){

for(j = i; j

> 0; j--){

for(k = 0; k < 6; k++) upper_map[j][k] = upper_map[j -

1][k];

}

}

for(j = 0; j < 6; j++)

upper_map[0][j] = 0;

}

}else n = 4;

}

}

}return del_num;

}

void calc_score(BYTE del_number){

Page 87: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

86

BYTE inc = 10, denominator = 10;

BYTE ans = 0, ans1 = 0, add = 0x8f;

int temp_score;

inc *= del_number;

score += inc;

temp_score = score;

if(score){

com_write(0x01);

while(temp_score >= denominator){

ans = temp_score % denominator;

com_write(add);

Send_Data_LCD('0' + ans);

temp_score /= denominator;

ans1 = temp_score;

add--;

}

com_write(add);

Send_Data_LCD('0' + ans1);

strcpy(buf, "SCORE");

mojisu = strlen(buf);

com_write(0x80);

strdata_write(buf, mojisu);

}

}

BYTE isGameover(void){

if(upper_map[1][2] || upper_map[1][3]) return FALSE;

else return TRUE;

}

BYTE enable_down(WORD row_cnt){

Page 88: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

87

Check_bottom();

if ( row_cnt + bottom_line > 17) return FALSE;

start_pt = column / 2;

evenflag = column % 2;

sum = 0;

for(i = 0; i < bottom_line + 1; i++ ) {

if(row_cnt < 9){

if ( evenflag ) {

if ( start_pt > 2 ) temp_map[0] =

upper_map[row_cnt][start_pt -3 ] & 0x0f; else temp_map[0] = 0;

if ( start_pt > 1 ) {

temp_map[1] =

upper_map[row_cnt][start_pt -2 ] / 16;

temp_map[2] =

upper_map[row_cnt][start_pt -2 ] & 0x0f;

} else {

temp_map[1] = 0;

temp_map[2] = 0;

}

if ( start_pt > 0 ) temp_map[3] =

upper_map[row_cnt][start_pt -1] / 16; else temp_map[3] = 0;

} else {

if ( start_pt > 2 ) {

temp_map[0] =

upper_map[row_cnt][start_pt - 3] / 16;

temp_map[1] =

upper_map[row_cnt][start_pt - 3] & 0x0f;

} else {

temp_map[0] = 0;

temp_map[1] = 0;

}

if ( start_pt > 1 ) {

Page 89: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

88

temp_map[2] =

upper_map[row_cnt][start_pt - 2 ] / 16;

temp_map[3] =

upper_map[row_cnt][start_pt - 2 ] & 0x0f;

} else {

temp_map[2] = 0;

temp_map[3] = 0;

}

}

} else {

if ( evenflag ) {

if ( start_pt > 2 ) temp_map[0] =

lower_map[row_cnt - 9][start_pt - 3] & 0x0f; else temp_map[0] = 0;

if ( start_pt > 1 ) {

temp_map[1] =

lower_map[row_cnt - 9][start_pt - 2] / 16;

temp_map[2] =

lower_map[row_cnt - 9][start_pt - 2] & 0x0f;

} else {

temp_map[1] = 0;

temp_map[2] = 0;

}

if ( start_pt > 0 ) temp_map[3] =

lower_map[row_cnt - 9][start_pt -1] / 16; else temp_map[3] = 0;

} else {

if ( start_pt > 2 ) {

temp_map[0] =

lower_map[row_cnt - 9][start_pt - 3 ] / 16;

temp_map[1] =

lower_map[row_cnt - 9][start_pt - 3 ] & 0x0f;

} else {

temp_map[0] = 0;

temp_map[1] = 0;

}

if ( start_pt > 1 ) {

temp_map[2] =

Page 90: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

89

lower_map[row_cnt - 9][start_pt - 2 ] / 16;

temp_map[3] =

lower_map[row_cnt - 9][start_pt - 2 ] & 0x0f;

} else {

temp_map[2] = 0;

temp_map[3] = 0;

}

}

}

for ( j = 0; j < 4; j++ )

if ( ( block[i][j] > 0 ) && ( temp_map[j] > 0 ) )

sum++;

row_cnt++;

}

return ( !sum );

}

BYTE enable_hol(WORD row_cnt){

start_pt = column / 2;

evenflag = column % 2;

sum = 0;

for(i = 0; i < 4; i++ ) {

if(row_cnt < 9){

if ( evenflag ) {

if ( start_pt > 2 ) temp_map[0] =

upper_map[row_cnt][start_pt -3 ] & 0x0f; else temp_map[0] = 0;

if ( start_pt > 1 ) {

temp_map[1] =

upper_map[row_cnt][start_pt -2 ] / 16;

temp_map[2] =

Page 91: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

90

upper_map[row_cnt][start_pt -2 ] & 0x0f;

} else {

temp_map[1] = 0;

temp_map[2] = 0;

}

if ( start_pt > 0 ) temp_map[3] =

upper_map[row_cnt][start_pt -1] / 16; else temp_map[3] = 0;

} else {

if ( start_pt > 2 ) {

temp_map[0] =

upper_map[row_cnt][start_pt - 3] / 16;

temp_map[1] =

upper_map[row_cnt][start_pt - 3] & 0x0f;

} else {

temp_map[0] = 0;

temp_map[1] = 0;

}

if ( start_pt > 1 ) {

temp_map[2] =

upper_map[row_cnt][start_pt - 2 ] / 16;

temp_map[3] =

upper_map[row_cnt][start_pt - 2 ] & 0x0f;

} else {

temp_map[2] = 0;

temp_map[3] = 0;

}

}

} else {

if ( evenflag ) {

if ( start_pt > 2 ) temp_map[0] =

lower_map[row_cnt - 9][start_pt - 3] & 0x0f; else temp_map[0] = 0;

if ( start_pt > 1 ) {

temp_map[1] =

lower_map[row_cnt - 9][start_pt - 2] / 16;

temp_map[2] =

lower_map[row_cnt - 9][start_pt - 2] & 0x0f;

Page 92: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

91

} else {

temp_map[1] = 0;

temp_map[2] = 0;

}

if ( start_pt > 0 ) temp_map[3] =

lower_map[row_cnt - 9][start_pt -1] / 16; else temp_map[3] = 0;

} else {

if ( start_pt > 2 ) {

temp_map[0] =

lower_map[row_cnt - 9][start_pt - 3 ] / 16;

temp_map[1] =

lower_map[row_cnt - 9][start_pt - 3 ] & 0x0f;

} else {

temp_map[0] = 0;

temp_map[1] = 0;

}

if ( start_pt > 1 ) {

temp_map[2] =

lower_map[row_cnt - 9][start_pt - 2 ] / 16;

temp_map[3] =

lower_map[row_cnt - 9][start_pt - 2 ] & 0x0f;

} else {

temp_map[2] = 0;

temp_map[3] = 0;

}

}

}

for ( j = 0; j < 4; j++ )

if ( ( block[i][j] > 0 ) && ( temp_map[j] > 0 ) )

sum++;

row_cnt++;

}

return ( !sum );

}

Page 93: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

92

void down(void){

if ( enable_down(row + 1) ) {

Del_Current_Block( row );

row++;

Write();

} else {

Wait(1);

copy_block_to_map( row );

del = lines_of_delete();

Send_Mapdata_to_Slave(SL_1_ADDRESS);

Send_Mapdata_to_Slave(SL_2_ADDRESS);

Send_Mapdata_to_Slave(SL_3_ADDRESS);

Send_Mapdata_to_Slave(SL_4_ADDRESS);

calc_score(del);

if (!isGameover()) np_flag = 2;

else {

np_flag = 1;

row = 0;

column = 0x0a;

}

}

drop = FALSE;

}

void Init_Map_Data(void){

for ( i = 0; i < 9; i++)

for ( j = 0; j < 6; j++ ) {

upper_map[i][j] = 0;

lower_map[i][j] = 0;

}

}

BYTE Next_Block(void)

Page 94: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

93

{

BYTE pat;

// pat = TMR2;

// pat = ((WORD)rand()) & 0x00FF;

pat = ((WORD)rand()) / 256;

return pat %= 7;

// return pat;

}

void Pat_Select(BYTE patt){

for ( i = 0; i < 4; i++)

for ( j = 0; j < 4; j++ )

block[ i ][ j ] = 0x00;

switch(patt){

case 0:

block[0][1] = 0x01;

block[1][1] = 0x01;

block[2][1] = 0x01;

block[3][1] = 0x01;

break;

case 1:

block[1][1] = 0x02;

block[1][2] = 0x02;

block[2][1] = 0x02;

block[3][1] = 0x02;

break;

case 2:

block[0][2] = 0x03;

block[1][1] = 0x03;

block[1][2] = 0x03;

block[2][1] = 0x03;

break;

case 3:

Page 95: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

94

block[0][1] = 0x04;

block[1][1] = 0x04;

block[1][2] = 0x04;

block[2][2] = 0x04;

break;

case 4:

block[1][1] = 0x05;

block[2][1] = 0x05;

block[2][2] = 0x05;

block[3][1] = 0x05;

break;

case 5:

block[1][1] = 0x06;

block[1][2] = 0x06;

block[2][1] = 0x06;

block[2][2] = 0x06;

break;

case 6:

block[1][1] = 0x07;

block[1][2] = 0x07;

block[2][2] = 0x07;

block[3][2] = 0x07;

break;

default :

break;

}

}

void Send_Mapdata_to_Slave(BYTE slave_address){

for ( i = 0; i < 9; i++ ) {

switch ( slave_address ) {

case SL_1_ADDRESS:

Page 96: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

95

for(j = 0; j < 3; j++)

line_data[j + 1] =

upper_map[i][j];

break;

case SL_2_ADDRESS:

for(j = 0; j < 3; j++)

line_data[j + 1] =

upper_map[i][j + 3];

break;

case SL_3_ADDRESS:

for(j = 0; j < 3; j++)

line_data[j + 1] =

lower_map[i][j + 3];

break;

case SL_4_ADDRESS:

for(j = 0; j < 3; j++)

line_data[j + 1] =

lower_map[i][j];

break;

default:

for (j = 0; j < 3; j++)

line_data[j + 1] = 0;

break;

}

line_data[0] = i;

bSEN = 1; //start

conditon

while ( bSEN ) {}

SSPBUF = slave_address; //send

slave address

while ( bBF ) {}

while ( bACKSTAT ) {}

for(j = 0; j < 4; j++){

Page 97: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

96

SSPBUF = line_data[j];

while ( bBF ) {}

while ( bACKSTAT ) {}

}

bPEN = 1;

while ( bPEN ) {}

}

}

void Send_Blank_Block_Data(BYTE slave_address, WORD row_cnt, BYTE

column_cnt){

line_data[1] = column_cnt;

line_data[0] = row_cnt;

line_data[ 2] = 0;

line_data[ 3] = 0;

bSEN = 1; //start conditon

while ( bSEN ) {}

SSPBUF = slave_address; //send slave

address

while ( bBF ) {}

while ( bACKSTAT ) {}

for(i = 0; i < 4; i++){

SSPBUF = line_data[i];

while ( bBF ) {}

while ( bACKSTAT ) {}

}

bPEN = 1;

while ( bPEN ) {}

}

Page 98: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

97

void Send_Current_Block_Data(BYTE slave_address, WORD row_cnt, BYTE

column_cnt){

line_data[1] = column_cnt;

for ( i = 0; i < 4; i++ ) {

if ( row_cnt > 33 ) break;

line_data[0] = row_cnt;

line_data[ 2] = block[i][0] * 16 + block[i][1];

line_data[ 3] = block[i][2] * 16 + block[i][3];

if(line_data[2] + line_data[3]){

bSEN = 1;

//start conditon

while ( bSEN ) {}

SSPBUF = slave_address;

//send slave address

while ( bBF ) {}

while ( bACKSTAT ) {}

for(j = 0; j < 4; j++){

SSPBUF = line_data[j];

while ( bBF ) {}

while ( bACKSTAT ) {}

}

bPEN = 1;

while ( bPEN ) {}

row_cnt++;

}

}

}

void Rotate(void){

Page 99: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

98

BYTE temp_b[4][4];

for(i = 0; i < 4; i++)

for(j = 0; j < 4; j++)

temp_b[i][j] = block[i][j];

for(j = 0; j < 4; j++)

for(i = 0; i < 4; i++)

temp[3 - j][i] = block[i][j];

for(i = 0; i < 4; i++)

for(j = 0; j < 4; j++)

block[i][j] = temp[i][j];

if(!((column > 5) && (column < 15) &&

(enable_hol(row)))){

for(i = 0; i < 4; i++)

for(j = 0; j < 4; j++)

block[i][j] = temp_b[i][j];

}

}

void Move_Left(void){

if ( block[0][0] + block[1][0] + block[2][0] + block[3][0] )

left = 0;

else if ( block[0][1] + block[1][1] + block[2][1] +

block[3][1] ) left = 1;

else if ( block[0][2] + block[1][2] + block[2][2] +

block[3][2] ) left = 2;

else left = 3;

Page 100: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

99

column--;

if(column + left < 6) column++;

else {

if(!enable_hol(row)) column++;

}

}

void Move_Right(void){

if ( block[0][3] + block[1][3] + block[2][3] + block[3][3] )

right = 0;

else if ( block[0][2] + block[1][2] + block[2][2] +

block[3][2] ) right = 1;

else if ( block[0][1] + block[1][1] + block[2][1] +

block[3][1] ) right = 2;

else right = 3;

column++;

if(column - right > 14) column--;

else {

if(!enable_hol(row)) column--;

}

}

void Del_Current_Block(WORD row_cnt){

for ( i =0; i < 4; i++) {

if(row_cnt < 9){

if(column < 12)

Send_Blank_Block_Data(SL_1_ADDRESS, row_cnt + 0x10, column);

if(column > 8)

Send_Blank_Block_Data(SL_2_ADDRESS, row_cnt + 0x10, column - 6);

}else{

if(column < 12)

Send_Blank_Block_Data(SL_4_ADDRESS, row_cnt + 0x10, column);

if(column > 8)

Page 101: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

100

Send_Blank_Block_Data(SL_3_ADDRESS, row_cnt + 0x10, column - 6);

}

row_cnt++;

if ( row_cnt > 17 ) break;

}

/*

if(row < 9)

if(column < 9)

Send_Blank_Block_Data(SL_1_ADDRESS, 0xff, column);

else if(column < 12){

Send_Blank_Block_Data(SL_1_ADDRESS,

0xff, column);

Send_Blank_Block_Data(SL_2_ADDRESS,

0xff, column - 6);

}else Send_Blank_Block_Data(SL_2_ADDRESS, 0xff,

column - 6);

if ( row > 5)

if(column < 9)

Send_Blank_Block_Data(SL_4_ADDRESS, 0xff, column);

else if(column < 12){

Send_Blank_Block_Data(SL_4_ADDRESS,

0xff, column);

Send_Blank_Block_Data(SL_3_ADDRESS,

0xff, column - 6);

}else Send_Blank_Block_Data(SL_3_ADDRESS, 0xff,

column - 6);

*/

}

void Write(void){

if(row < 9){

if(column < 12)

Send_Current_Block_Data(SL_1_ADDRESS, row + 0x10, column );

if(column > 8)

Send_Current_Block_Data(SL_2_ADDRESS, row + 0x10, column - 6 );

Page 102: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

101

}

if ( row > 5) {

if(column < 12)

Send_Current_Block_Data(SL_4_ADDRESS, row + 0x10, column );

if(column > 8)

Send_Current_Block_Data(SL_3_ADDRESS, row + 0x10, column - 6 );

}

}

BYTE com_write(BYTE command){

bSEN = 1;

while ( bSEN ) {}

SSPBUF = 0b01111100;

while ( bBF ) {}

while ( bACKSTAT ) {}

SSPBUF = 0;

while ( bBF ) {}

while ( bACKSTAT ) {}

SSPBUF = command;

while ( bBF ) {}

while ( bACKSTAT ) {}

bPEN = 1;

while ( bPEN ) {}

Wait(1);

return 0;

}

void strdata_write(char *str, BYTE num){

BYTE i;

Page 103: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

102

bSEN = 1;

while ( bSEN ) {}

SSPBUF = 0b01111100;

while ( bBF ) {}

SSPBUF = 0b01000000;

while ( bBF ) {}

for ( i = 0; i < num; i++ ) {

SSPBUF = *str++;

while ( bBF ) {}

}

bPEN = 1;

while ( bPEN ) {}

}

void Send_Data_LCD(BYTE data){

bSEN = 1; //start conditon

while ( bSEN ) {}

SSPBUF = 0x7c; //send slave address

while ( bBF ) {}

while ( bACKSTAT ) {}

SSPBUF = 0x40; //send data

while ( bBF ) {}

while ( bACKSTAT ) {}

SSPBUF = data; //send data

while ( bBF ) {}

while ( bACKSTAT ) {}

Page 104: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

103

bPEN = 1; //stop conditon

while ( bPEN){}

Wait(1);

}

void I2C_LCD_init(void){

Wait(100);

com_write(0x3c);

Wait(1);

com_write(0x3d);

Wait(1);

com_write(0x14);

Wait(1);

com_write(0x72);

Wait(1);

com_write(0x56);

Wait(1);

com_write(0x6c);

Wait(300);

com_write(0x3c);

Wait(1);

com_write(0x0c);

Wait(1);

com_write(0x01);

Wait(10);

}

Page 105: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

104

テトリスソースコード(Slave)

Page 106: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

105

#include <P16F887.h>

#include <PortBits.h>

#include <P16F887_bits.h>

#include <datalib.h>

#include <delays.h>

void Init_LCD(void);

BYTE Wait_Receive(void);

BYTE Read_Data(void);

void LED_ON( BYTE data);

void div_data(void);

void mapping(void);

void convert_block_data(void);

void block_write(void);

void reflesh_block(void);

void clear_map(void);

BYTE line_data[6];

BYTE temp_data[3];

BYTE block[4];

BYTE map_data[9][6];

BYTE line_data_R;

BYTE line_data_G;

BYTE line_data_B;

BYTE d_a = 0, received_data = 0;

void main(void) {

BYTE i, j, first_row_num;

OSCCON = 0x60;

ANSEL = 0;

ANSELH = 0;

TRISA = 0;

TRISB = 0;

TRISC = 0x18;

TRISD = 0;

Page 107: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

106

SSPCON = 0x06; //slave mode, 7bit address

SSPSTAT = 0x80; //srew rate control disable for

standard speed mode(100kHz and 1kHz)

SSPADD = 0x06; //slave address

bCKP = 1; //clock stretch off

bSEN = 1; //clock stretch enable both receive and

tarnsmit

bSSPEN = 1; //I2C enable

bWCOL = 0;

bSSPOV = 0;

ADCON0 = 0;

CM1CON0 = 0;

CM2CON0 = 0;

Init_LCD();

clear_map();

while(1){

for(i = 0; i < 4; i++){

d_a = Wait_Receive(); //wait for receive

if(i ==0){

if(!d_a) received_data =

Read_Data();

}

else{

if(!d_a) temp_data[i-1] =

Read_Data();

}

}

if ( received_data < 9 ) {

mapping();

div_data();

}else if (received_data <0x30 ){

received_data -= 16;

/*

Page 108: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

107

if ( received_data < 9 ) {

convert_block_data();

block_write();

div_data();

}

*/

if ( (received_data > 8) && (received_data <

18) ) {

received_data -= 9;

convert_block_data();

block_write();

div_data();

}

}

else reflesh_block();

}

}

void Init_LCD(void){

PORTA = 0x3f;

PORTB = 0xff;

PORTC = 0;

PORTD = 0x3f;

Wait(1);

PORTC = 0xff;

bRA6 = 1;

bRA7 = 1;

bRD6 = 1;

PORTC = 0;

bRA6 = 0;

bRA7 = 0;

bRD6 = 0;

}

Page 109: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

108

void clear_map(void) {

BYTE i, j;

for ( i = 0; i < 9; i++)

for ( j = 0; j < 6; j++ )

map_data[i][j] = 0;

}

BYTE Wait_Receive(void){

BYTE data;

while(!bSSPIF){} //wait for receive

bSSPIF = 0;

if(!bD_A){

data = SSPBUF;

bCKP = 1;

while ( !bSSPIF ) {}

bSSPIF = 0;

}

if ( bR_W ) return 1; //send data form slave to master

else return 0; //receive data from

master to slave}

}

BYTE Read_Data(void){

BYTE data;

data = SSPBUF;

bCKP = 1;

bSSPIF = 0;

return data;

}

Page 110: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

109

void LED_ON( BYTE data){

BYTE x, y;

x = (data & 0xf0) / 16;

y = data &0x0f;

switch(x){

case 0:

bRA0 = 0;

break;

case 1:

bRA1 = 0;

break;

case 2:

bRA2 = 0;

break;

case 3:

bRA3 = 0;

break;

case 4:

bRA4 = 0;

break;

case 5:

bRA5 = 0;

break;

default:

break;

}

switch(y){

case 0:

bRC0 = 1;

break;

case 1:

bRC1 = 1;

break;

Page 111: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

110

case 2:

bRC2 = 1;

break;

case 3:

bRC5 = 1;

break;

case 4:

bRC6 = 1;

break;

case 5:

bRC7 = 1;

break;

case 6:

bRA6 = 1;

break;

case 7:

bRA7 = 1;

break;

case 8:

bRD6 = 1;

break;

default:

break;

}

PORTA = 0x3f;

PORTB = 0xff;

PORTC = 0;

PORTD = 0x3f;

}

void mapping(void) {

BYTE i, j;

for ( i = 0; i < 3; i++) {

Page 112: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

111

j = 2 * i;

line_data[ j ] = (temp_data[i] & 0xf0) / 16;

line_data[ j + 1] = temp_data[i] & 0x0f;

}

for ( i = 0; i < 6; i++)

map_data[received_data][i] = line_data[i];

}

void convert_block_data(void){

BYTE i, j;

for ( i = 0; i < 2; i++){

j = 2 * i;

block[ j] = (temp_data[i + 1] & 0xf0) / 16;

block[j + 1] = temp_data[i + 1] & 0x0f;

}

}

void block_write(void) {

BYTE i, j, sum, color;

j = temp_data[0];

for ( i = 0; i < 6; i++ ) {

if ( ( i + 6 >= j ) && ( i + 2 < j ) )

sum = block[i + 6 - j];

else sum = 0;

color = map_data[received_data][i];

// if ( sum && !color ) line_data[i] = sum;

********* TYPE1 Yuusen background

// else line_data[i] = color;

if ( sum ) line_data[i] = sum;

// ********* TYPE2 Yuusen block data

else line_data[i] = color;

}

}

Page 113: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

112

void reflesh_block(void) {

BYTE j, receiv_copy;

receiv_copy = received_data;

for ( received_data = 0; received_data < 9; received_data

++ ) {

for ( j = 0; j < 6; j++)

line_data[j] = map_data[received_data][j];

div_data();

}

received_data = receiv_copy;

}

void div_data(void){

BYTE i, j, keisu = 1, r = 0, g = 0, b = 0;

for(i = 0; i < 6; i++){

line_data_R = line_data[i] & 0x01;

line_data_G = (line_data[i] & 0x02) / 2;

line_data_B = (line_data[i] & 0x04) / 4;

if(!line_data_R) r += keisu;

if(!line_data_G) g += keisu;

if(!line_data_B) b += keisu;

keisu *= 2;

}

PORTA = r;

PORTB = g;

PORTD = b;

switch(received_data){

case 0:

bRC0 = 1;

break;

case 1:

bRC1 = 1;

Page 114: 卒業研究報告 - kochi-tech.ac.jp · PDF file128×64 ドットのglcd とpic16f876 を用いてスロットマシンを製作した。図1

113

break;

case 2:

bRC2 = 1;

break;

case 3:

bRC5 = 1;

break;

case 4:

bRC6 = 1;

break;

case 5:

bRC7 = 1;

break;

case 6:

bRA6 = 1;

break;

case 7:

bRA7 = 1;

break;

case 8:

bRD6 = 1;

break;

default:

break;

}

PORTA = 0x3f;

PORTB = 0xff;

PORTC = 0;

PORTD = 0x3f;

}