TOPへ戻る
■動画
■回路図・部品表
■解説
■ソースファイル
■ソースファイルのダウンロード
■今後について
■参考URL
★20091004 AVRに長門さんがいらしたようです |
■回路図
←クリックすると拡大します。
■部品リスト
部品番号 |
部品名 |
単価 |
個数 |
仕入先 |
CN1 |
2.1mm標準DCジャック(基板取付用) MJ-179P 内径2.1mm 外形 5.5mm |
40円 |
1個 |
秋月電子通商 |
CN2 |
ピンヘッダ(オス) 40P(1×40) |
50円 |
1個 |
秋月電子通商 |
U1 |
ATMEGA168-20PU |
525円 |
1個 |
マルツパーツ館 |
U2 |
GDM12864H |
2480円 |
1個 |
ストロベリー・リナックス |
U3 |
多出力クリスタルオシレータ EXO3(20MHz) |
250円 |
1個 |
秋月電子通商 |
R1 |
金属皮膜抵抗器 1/4w 4.3kΩ |
円 |
1個 |
|
C1,C2 |
パスコン 0.1uF |
円 |
1個 |
|
VR1 |
可変抵抗器 10kΩ |
円 |
1個 |
|
PB1 |
ブレッドボード |
円 |
1個 |
秋月電子通商 |
←クリックすると拡大し
このページの下のほうに載せてありますが、ニコニコ動画でPICに長門さんがいらしたようです
を見て、AVR版を作ってみました。
作るにはハイスペックでなければと思って、CPUはATmega168-20MHz、液晶はGDM12864にしました。
忠実に再現するために漢字fontを載せようと考えました。
8x8の漢字フォントは恵梨沙フォントを使い、ビットマップフォントを組み込みで使おう!さんの、データを使用しています。
Size after:
AVR Memory Usage
----------------
Device: atmega168
Program: 55726 bytes (340.1% Full)
(.text + .data + .bootloader)
Data: 55550 bytes (5424.8% Full)
(.data + .bss + .noinit)
大きすぎて、絶対 ATmega168 内に入りませんので、使用するフォントだけ抜き出す方式に変更。
一文字一文字手動で拾うのは大変なので、VBAでやっつけプログラムを作成。
←クリックすると拡大します
Option Explicit
Sub 文字列toFontData()
Dim start_ad As Long
Dim end_ad As Long
Dim strcode As String
Dim foundcell As Integer
Dim i As Integer
Dim j As Integer
Dim in_s As String
Dim foo As String
For i = 2 To 30
Cells(i, 1) = ""
Next i
in_s = Cells(1, 1) ' 変換する文を読み込む
For i = 1 To Len(in_s)
foo = Mid(in_s, i, 1) ' 1文字取り出し
strcode = CLng("&h" & Hex(Asc(foo))) 'JISコードに変換し数値化
For j = 0 To 87
foo = Sheet1.Cells(7169 + j, 2)
start_ad = CLng("&h" & Mid(foo, 4, 4))
end_ad = CLng("&h" & Mid(foo, 11, 4))
If start_ad <= strcode And end_ad >= strcode Then
foo = Mid(foo, 24, 14)
Exit For
End If
Next j
foundcell = Sheet1.Cells.Find(What:=foo).Row
foo = Sheet1.Cells(foundcell + (strcode - start_ad + 2), 2)
Cells(i + 1, 1) = Mid(foo, 2, Len(foo) - 3)
Next i
End Sub
←クリックすると拡大します
こんな感じにA1セルに文字を入れて、マクロを実行すうと、sheet1からフォントデータを
拾ってきてくれます。
■ソースファイル
#include "font.h"
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#define LCD_E 0x08 // モデル、ピン配置によって変更する。
#define LCD_DI 0x04
#define LCD_CS1 0x02
#define LCD_CS2 0x01
#define LCD_CONT PORTC
#define LCD_DATA PORTD
unsigned char cXpos,cYpos,cT;
unsigned int FontPosData;
int Flag;
void commut_lcd(void);
void erase_lcd(char line);
void print_lcd(char xp, char yp, char *chaine);
void lcd(char cVar);
void lcd_wait( int m )
{
// _delay_ms(m); 引数を渡しちゃだめ。wiki参照
while(m--) _delay_ms(1);
}
void lcd(char cVar)
{
LCD_DATA = cVar;
_delay_us(140+10); // Tasu 140ns(Min)
LCD_CONT |= LCD_E;
_delay_us(450+10); // Twh 450ns(Min)
LCD_CONT &= ~LCD_E;
}
/*-------------------------------------------------------------
cX(dot) cY(行)
--------------------------------------------------------------*/
void print_lcd(char cX, char cY, char *chaine)
{
cXpos=cX-1;
cYpos=cY-1;
Flag=0;
commut_lcd();
while(*chaine != 0){
FontPosData=(int)((*chaine++)-32)*5; // 表示する文字の格納位置を計算
for( cT = 0 ; cT <= 5 ; cT++ ){ // 1文字表示処理
if(cXpos>=64 && Flag==0){
commut_lcd();
Flag=1;
}
if(cT==5)
lcd(0);
else {
lcd(pgm_read_byte(&tab_font[FontPosData+cT]));
}
cXpos++;
}
lcd_wait(150);//150ms
}
}
/*-------------------------------------------------------------
cX(dot) cY(行)
--------------------------------------------------------------*/
void print_lcd_elisa(char cX, char cY,char *yuki)
{
int i=0;
cXpos=cX-1;
cYpos=cY-1;
Flag=0;
commut_lcd();
for(;;){
FontPosData=i*8; // 表示する文字の格納位置を計算
if(pgm_read_byte(&yuki[FontPosData])==0xff && pgm_read_byte(&yuki[FontPosData+1])==0xff )
break;
for( cT = 0 ; cT <= 8 ; cT++ ){ // 1文字表示処理
if(cXpos>=64 && Flag==0){
commut_lcd();
Flag=1;
}
if(cT==8)
lcd(0);
else {
lcd(pgm_read_byte(&yuki[FontPosData+cT]));
}
cXpos++;
}
lcd_wait(150);//150ms
i++;
}
}
void commut_lcd(void)
{
if(cXpos >= 64){ // 右側のLCD
LCD_CONT |= LCD_CS1;
LCD_CONT &= ~LCD_CS2;
}else{ // 左側のLCD
LCD_CONT |= LCD_CS2;
LCD_CONT &= ~LCD_CS1;
}
LCD_CONT &= ~LCD_DI; // instruction code
lcd(0xB8 + cYpos); // Set Address(X address) page
if(cXpos >=64) cXpos -=64;
lcd(0x40 + cXpos); // Set Address(y address)
LCD_CONT |= LCD_DI; // data code
}
void erase_lcd(char line)
{
char cy;
LCD_CONT |= LCD_CS1; // 左エリア有効
LCD_CONT |= LCD_CS2; // 右エリア有効
LCD_CONT &= ~LCD_DI; // instruction code
lcd(0xC0); // Set Address(X address) Page0
if(line){
lcd(0x40); // Set Address(Y address)
lcd(0xB8 + (line-1)); // page++ Set Address(X address)
LCD_CONT |= LCD_DI; // data code
for( cy = 0 ; cy <= 63 ; cy++ )
lcd(0);
}
else {
for( cT = 0 ; cT <= 7 ; cT++ ){
LCD_CONT &= ~LCD_DI; // instruction code
lcd(0x40); // Set Address(Y address)
lcd(0xB8 +cT); // page++ Set Address(X address)
LCD_CONT |= LCD_DI;
for( cy = 0 ; cy <= 63 ; cy++ )
lcd(0);
}
}
}
void init_lcd(void)
{
PORTD=0x00; // LCD DATA BUS 全ピン 0 出力
DDRD = (1<<PB7)| (1<<PB6)|(1<<PB5)|(1<<PB4)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0); // PortB 全ピン出力モード
PORTC = 0x00; // LCD CONTROL SIG 全ピン 0 出力
DDRC = (1<<PD3)|(1<<PD2)|(1<<PD1)|(1<<PD0); // PortC PC0-PD3
// DDRC = (1<<PD6)|(1<<PD5)|(1<<PD4)|(1<<PD3)|(1<<PD2); // PortD PD2-PD6 (※SIO用にPD0,PD1は空き)
for( cT = 0 ; cT <= 1 ; cT++ ){
LCD_CONT &= ~LCD_DI; // instruction code
if(cT){
LCD_CONT &= ~LCD_CS1; // 左エリア無効
LCD_CONT |= LCD_CS2; // 右エリア有効
}
else{
LCD_CONT |= LCD_CS1; // 左エリア有効
LCD_CONT &= ~LCD_CS2; // 右エリア無効
}
lcd(0x3F); // lcd on
lcd(0xC0); // Set Display Start Line
}
erase_lcd(0);
}
void cursor_blnk(int x, int y, int n)
{
int i;
for(i=0;i<n;i++){
print_lcd(x,y,"_");
lcd_wait(500); //500ms
print_lcd(x,y," ");
lcd_wait(500); //500ms
}
}
void main(void)
{
//#ifdef debug
init_lcd();
cursor_blnk(1,1,5);
print_lcd(1,1,"YUKI.N>");
print_lcd_elisa(6*7,1,&yuki1); // みえてる?
cursor_blnk(6*7+9*5,1,2);
print_lcd_elisa(1,2,&yuki2); // ああ
cursor_blnk(9*2,2,1);
print_lcd(1,3,"YUKI.N>");
print_lcd_elisa(6*7,3,&yuki3); // そっちの時空間とは
// print_lcd_elisa(6*7,4,&yuki4); // まだ完全には連結を絶たれていない。
print_lcd_elisa(6*7,4,&yuki4a);// まだ完全には連結を
print_lcd_elisa(6*7,4,&yuki4b);// 絶たれていない。
lcd_wait(500); //500ms
print_lcd_elisa(6*7,5,&yuki5); // でも時間の問題。
print_lcd_elisa(6*7,6,&yuki6); // そうなれば最後。
cursor_blnk(6*7+9*8,6,5);
// print_lcd_elisa( 1,7,&yuki7); // どうすりゃいい?
print_lcd_elisa( 1,7,&yuki7a);// d
print_lcd_elisa( 1,7,&yuki7b);// ど
print_lcd_elisa(1*9,7,&yuki7c);// う
print_lcd_elisa(2*9,7,&yuki7d);// s
print_lcd_elisa(2*9,7,&yuki7e);// す
print_lcd_elisa(3*9,7,&yuki7f);// r
print_lcd_elisa(3*9,7,&yuki7g);// y
print_lcd_elisa(3*9,7,&yuki7h);// り
print_lcd_elisa(4*9,7,&yuki7i);// ゃ
print_lcd_elisa(5*9,7,&yuki7j);// い
print_lcd_elisa(6*9,7,&yuki7j);// い
print_lcd_elisa(7*9,7,&yuki7k);// ?
cursor_blnk(9*8,7,2);
print_lcd(1,8,"YUKI.N>");
print_lcd_elisa(6*7,8,&yuki8); // どうにもならない。
cursor_blnk(6*7+9*9,8,5);
//#endif
//#ifdef debug
init_lcd();
// print_lcd_elisa(6*7,1,&yuki9); // 情報統合思念体は失望している。
print_lcd_elisa(6*7,1,&yuki9a); // 情報統合思念体は失
print_lcd_elisa(6*7,1,&yuki9b); // 望している。
lcd_wait(500); //500ms
// print_lcd_elisa(6*7,2,&yuki10); // これで進化の可能性は失われた。
print_lcd_elisa(6*7,2,&yuki10a); // これで進化の可能性
print_lcd_elisa(6*7,2,&yuki10b); // は失われた。
cursor_blnk(6*7+8*6,2,5);
print_lcd(1,3,"YUKI.N>");
print_lcd_elisa(6*7,3,&yuki11); // 涼宮ハルヒは
print_lcd_elisa(6*7,4,&yuki12); // 何もない所から
print_lcd_elisa(6*7,5,&yuki13); // 情報を生み出す力を
print_lcd_elisa(6*7,6,&yuki14); // 持っていた。
// print_lcd_elisa(6*7,7,&yuki15); // それは情報統合思念体にも
print_lcd_elisa(6*7,7,&yuki15a); // それは情報統合思念
print_lcd_elisa(6*7,7,&yuki15b); // 体にも
print_lcd_elisa(6*7,8,&yuki16); // ない力。
cursor_blnk(6*7+8*4,8,2);
//#endif
//#ifdef debug
init_lcd();
// print_lcd_elisa(6*8,1,&yuki17); // この情報創造能力を解析すれば
print_lcd_elisa(6*8,1,&yuki17a); // この情報創造能力を
print_lcd_elisa(6*8,1,&yuki17b); // 解析すれば
lcd_wait(500); //500ms
print_lcd_elisa(6*8,2,&yuki18); // 自律進化への糸口が
// print_lcd_elisa(6*8,3,&yuki19); // つかめるかもしれないと考えた。
print_lcd_elisa(6*8,3,&yuki19a); // つかめるかもしれな
print_lcd_elisa(6*8,3,&yuki19b); // いと考えた。
cursor_blnk(1,4,2);
//#endif
//#ifdef debug
init_lcd();
print_lcd(1,1,"YUKI.N>");
print_lcd_elisa(6*7,1,&yuki20); // あなたに賭ける。
cursor_blnk(6*7+8*9,1,2);
print_lcd_elisa(1,2,&yuki21); // 何をだよ
print_lcd(1,3,"YUKI.N>");
// print_lcd_elisa(6*7,3,&yuki22); // もう一度こちらへ回帰することを
print_lcd_elisa(6*7,3,&yuki22a); // もう一度こちらへ回
print_lcd_elisa(6*7,3,&yuki22b); // 帰することを
print_lcd_elisa(6*7,4,&yuki23); // 我々は望んでいる。
lcd_wait(500); //500ms
// print_lcd_elisa(6*7,5,&yuki24); // 涼宮ハルヒは重要な観察対象。
print_lcd_elisa(6*7,5,&yuki24a); // 涼宮ハルヒは重要な
print_lcd_elisa(6*7,5,&yuki24b); // 観察対象。
lcd_wait(500); //500ms
print_lcd_elisa(6*7,6,&yuki25); // わたしという個体も
lcd_wait(500); //500ms
// print_lcd_elisa(6*7,7,&yuki26); // あなたには戻ってきて欲しいと感じている。
print_lcd_elisa(6*7,7,&yuki26a); // あなたには戻ってき
print_lcd_elisa(6*7,7,&yuki26b); // て欲しいと感じてい
print_lcd_elisa(6*7,7,&yuki26c); // る。
cursor_blnk(6*7+8*2,7,2);
//#endif
//#ifdef debug
init_lcd();
print_lcd(1,1,"YUKI.N>");
cursor_blnk(6*7,1,2);
// print_lcd_elisa(6*7,1,&yuki27); // また図書館に
print_lcd_elisa(6*7,1,&yuki27a); // また
lcd_wait(500); //500ms
print_lcd_elisa(6*7+8*2+3,1,&yuki27b); // 図
print_lcd_elisa(6*7+8*3+3,1,&yuki27c); // 書
print_lcd_elisa(6*7+8*4+3,1,&yuki27d); // 館
print_lcd_elisa(6*7+8*5+3,1,&yuki27e); // に
cursor_blnk(6*7+8*7,1,2);
init_lcd();
print_lcd(1,1,"YUKI.N>");
print_lcd(6*7,1," sleeping beau");
print_lcd(6*7,2,"ty");
cursor_blnk(6*9,2,2);
//#endif
LCD_CONT &= ~LCD_CS1;
LCD_CONT &= ~LCD_CS2;
while(1);
}
ソースファイルのダウンロード
EXCELのマクロファイルのダウンロード
恵梨沙フォントHomePage
ビットマップフォントを組み込みで使おう!
Disconnected Place 切り離された空間
2009/10/06 1版 とりあえずうp