//***************************************************************** // グラフィック液晶モジュールSG12232を用いた赤外線脈波計プログラム // Copyright by Tomoaki Ueda /2005/11/02/ Version 1.00 // 【URL】http://www.neo-tech-lab.com // CQ出版株式会社トランジスタSpecial向け 対象 PIC16F873 //***************************************************************** // 【内容】初期化後、10ミリ秒タイマー割り込みで30ミリ秒ごとに // A/D(AN0)からサンプリングを行い、0-31の現在値xを得る。 // 前回サンプリング値xpと現在値xを線分で結び、波形を描画。 // 画面端まで来たら液晶画面のクリアを行い、"Neo-Tech-Lab" // と表示する。以上を繰り返す。 #include <16F873.h> #device *=16, ADC=10 #fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT, NOLVP, NOWRT #use delay(clock=20000000) #use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, BITS=8, PARITY=N) #use fast_io(A) #use fast_io(B) #use fast_io(C) /* int8 const pix[32]= {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01, 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01, 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01, 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }; */ /* ドット描画用データ(このプログラムでは未使用) */ /* int8 const pcm[32]= {0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8, 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9, 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA, 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB }; */ /* ドット描画用コマンド(このプログラムでは未使用) */ int32 const p[32]= {0xffffffff,0x7fffffff,0x3fffffff,0x1fffffff, 0x0fffffff,0x07ffffff,0x03ffffff,0x01ffffff, 0x00ffffff,0x007fffff,0x003fffff,0x001fffff, 0x000fffff,0x0007ffff,0x0003ffff,0x0001ffff, 0x0000ffff,0x00007fff,0x00003fff,0x00001fff, 0x00000fff,0x000007ff,0x000003ff,0x000001ff, 0x000000ff,0x0000007f,0x0000003f,0x0000001f, 0x0000000f,0x00000007,0x00000003,0x00000001 }; /* 線分による波形描画データ 下側 */ int32 const q[32]= {0x80000000,0xc0000000,0xe0000000,0xf0000000, 0xf8000000,0xfc000000,0xfe000000,0xff000000, 0xff800000,0xffc00000,0xffe00000,0xfff00000, 0xfff80000,0xfffc0000,0xfffe0000,0xffff0000, 0xffff8000,0xffffc000,0xffffe000,0xfffff000, 0xfffff800,0xfffffc00,0xfffffe00,0xffffff00, 0xffffff80,0xffffffc0,0xffffffe0,0xfffffff0, 0xfffffff8,0xfffffffc,0xfffffffe,0xffffffff }; /* 線分による波形描画データ 上側 */ int8 const Font20[128]= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x5F,0x00,0x00,0x00,0x00, 0x00,0x00,0x02,0x01,0x02,0x01,0x00,0x00, 0x3E,0x41,0x41,0x41,0x22,0x00,0x00,0x00, 0x10,0x74,0x1C,0x17,0x74,0x1C,0x17,0x04, 0x42,0x25,0x12,0x08,0x24,0x52,0x21,0x00, 0x60,0x56,0x49,0x4E,0x30,0x30,0x40,0x00, 0x00,0x00,0x00,0x04,0x03,0x01,0x00,0x00, 0x00,0x00,0x3E,0x41,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x41,0x3E,0x00,0x00,0x00, 0x00,0x22,0x14,0x7F,0x14,0x22,0x00,0x00, 0x08,0x08,0x08,0x7F,0x08,0x08,0x08,0x00, 0x00,0x00,0x80,0x60,0x20,0x00,0x00,0x00, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00, 0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x00, 0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00 }; /* 0x20-0x2F */ int8 const Font30[128]= {0x3E,0x61,0x51,0x49,0x45,0x43,0x3E,0x00, 0x00,0x00,0x40,0x42,0x7F,0x40,0x00,0x00, 0x42,0x61,0x51,0x51,0x49,0x49,0x46,0x00, 0x22,0x41,0x49,0x49,0x49,0x49,0x36,0x00, 0x30,0x28,0x24,0x22,0x21,0x7F,0x20,0x00, 0x47,0x45,0x45,0x45,0x45,0x45,0x39,0x00, 0x3E,0x49,0x49,0x49,0x49,0x49,0x32,0x00, 0x01,0x01,0x01,0x71,0x09,0x05,0x03,0x00, 0x36,0x49,0x49,0x49,0x49,0x49,0x36,0x00, 0x46,0x49,0x49,0x49,0x49,0x29,0x1E,0x00, 0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x00, 0x00,0x00,0x80,0x64,0x24,0x00,0x00,0x00, 0x00,0x08,0x14,0x14,0x22,0x22,0x41,0x00, 0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x00, 0x00,0x41,0x22,0x22,0x14,0x14,0x08,0x00, 0x06,0x01,0x01,0x59,0x09,0x09,0x06,0x00 }; /* 0x30-0x3F */ int8 const Font40[128]= {0x3E,0x41,0x59,0x55,0x55,0x59,0x2E,0x00, 0x60,0x18,0x16,0x11,0x16,0x18,0x60,0x00, 0x7F,0x49,0x49,0x49,0x49,0x4E,0x30,0x00, 0x3E,0x41,0x41,0x41,0x41,0x41,0x22,0x00, 0x7F,0x41,0x41,0x41,0x41,0x41,0x3E,0x00, 0x7F,0x49,0x49,0x49,0x49,0x41,0x40,0x00, 0x7F,0x09,0x09,0x09,0x09,0x01,0x01,0x00, 0x3E,0x41,0x41,0x49,0x49,0x49,0x3A,0x00, 0x7F,0x08,0x08,0x08,0x08,0x08,0x7F,0x00, 0x00,0x00,0x41,0x7F,0x41,0x00,0x00,0X00, 0x30,0x40,0x41,0x41,0x3F,0x01,0x00,0x00, 0x7F,0x08,0x08,0x14,0x22,0x41,0x00,0x00, 0x7F,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 0x7F,0x02,0x04,0x08,0x04,0x02,0x7F,0x00, 0x7F,0x02,0x04,0x08,0x10,0x20,0x7F,0x00, 0x3E,0x41,0x41,0x41,0x41,0x41,0x3E,0x00 }; /* 0x40-0x4F */ int8 const Font50[128]= {0x7F,0x09,0x09,0x09,0x09,0x09,0x06,0x00, 0x3E,0x41,0x41,0x71,0x49,0x49,0x3E,0x40, 0x7F,0x09,0x09,0x19,0x29,0x49,0x46,0x00, 0x26,0x49,0x49,0x49,0x49,0x49,0x32,0x00, 0x01,0x01,0x01,0x7F,0x01,0x01,0x01,0x00, 0x3F,0x40,0x40,0x40,0x40,0x40,0x3F,0x00, 0x03,0x0C,0x30,0x40,0x30,0x0C,0x03,0x00, 0x03,0x1C,0x60,0x18,0x60,0x1C,0x03,0x00, 0x41,0x22,0x14,0x08,0x14,0x22,0x41,0x00, 0x01,0x02,0x04,0x78,0x04,0x02,0x01,0x00, 0x41,0x61,0x55,0x49,0x55,0x43,0x41,0x00, 0x00,0x00,0x7F,0x41,0x41,0x00,0x00,0x00, 0x01,0x2A,0x2C,0x78,0x2C,0x2A,0x01,0x00, 0x00,0x00,0x41,0x41,0x7F,0x00,0x00,0x00, 0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00 }; /* 0x50-0x5F */ int8 const Font60[128]= {0x00,0x00,0x01,0x03,0x04,0x00,0x00,0x00, 0x00,0x38,0x45,0x45,0x45,0x25,0x7E,0x00, 0x7F,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 0x38,0x44,0x44,0x44,0x44,0x48,0x00,0x00, 0x38,0x44,0x44,0x44,0x44,0x7F,0x40,0x00, 0x38,0x54,0x54,0x54,0x54,0x58,0x00,0x00, 0x04,0x04,0x7E,0x05,0x05,0x00,0x00,0x00, 0x18,0xA4,0xA4,0xA4,0xA4,0x78,0x00,0x00, 0x7F,0x08,0x08,0x08,0x08,0x70,0x00,0x00, 0x00,0x00,0x00,0x7A,0x00,0x00,0x00,0x00, 0x00,0x80,0x80,0x7A,0x00,0x00,0x00,0x00, 0x7F,0x10,0x18,0x24,0x44,0x00,0x00,0x00, 0x00,0x00,0x00,0x7F,0x40,0x00,0x00,0x00, 0x7E,0x04,0x04,0x78,0x04,0x04,0x78,0x00, 0x7E,0x04,0x04,0x04,0x04,0x78,0x40,0x00, 0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00 }; /* 0x60-0x6F */ int8 const Font70[128]= {0xF8,0x24,0x24,0x24,0x24,0x18,0x00,0x00, 0x18,0x24,0x24,0x24,0x24,0xF8,0x00,0x00, 0x7C,0x08,0x04,0x04,0x04,0x00,0x00,0x00, 0x48,0x54,0x54,0x54,0x54,0x20,0x00,0x00, 0x04,0x04,0x3F,0x44,0x44,0x00,0x00,0x00, 0x3C,0x40,0x40,0x40,0x20,0x7C,0x40,0x00, 0x04,0x18,0x60,0x30,0x0C,0x04,0x00,0x00, 0x1C,0x60,0x18,0x60,0x18,0x04,0x00,0x00, 0x44,0x28,0x10,0x28,0x44,0x40,0x00,0x00, 0x04,0x88,0x90,0x60,0x18,0x04,0x00,0x00, 0x44,0x64,0x54,0x54,0x4C,0x44,0x00,0x00, 0x00,0x00,0x08,0x36,0x41,0x00,0x00,0x00, 0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00, 0x00,0x00,0x41,0x36,0x08,0x00,0x00,0x00, 0x00,0x00,0x01,0x02,0x01,0x02,0x00,0x00, 0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x00 }; /* 0x70-0x7F */ int8 rdt; /* LCDモジュール内メモリの読出しデータ */ int8 wdt; /* LCDモジュール内メモリの書込みデータ */ int8 sts; /* LCDモジュールのステータス(状態)変数 */ int8 cmd; /* LCDモジュールに対するコマンド変数 */ int8 pat[8]; /* 文字フォント(8x8)パターンのWorking変数 */ int8 col; /* 文字フォント(8x8)の描画位置 カラム(桁) */ int8 row; /* 文字フォント(8x8)の描画位置 ロー(行) */ int8 x; /* A/Dコンバート値を0-31の値に変換した現在値 */ int8 xp; /* A/Dコンバート値を0-31の値に変換した前回値 */ int32 pa; /* 測定波形の線分パターンのWorking変数 */ int8 tc; /* 10mSタイマー割込回数カウンタ(0,1,2) */ int8 i,j; /* PIC16F873 */ /* +-------u-------+ */ /* +5V-->|/MCLR RB7|-->DB7 */ /* Analog Input-->|AN0 RB6|-->DB6 */ /* A0<--|RA1 RB5|-->DB5 */ /* RES<--|RA2 RB4|-->DB4 */ /* WR<--|RA3 RB3|-->DB3 */ /* EEPROM_CS<--|RA4 RB2|-->DB2 */ /* RD<--|RA5 RB1|-->DB1 */ /* +5V===|VSS RB0|-->DB0 */ /* 20.0MHz -->|CLKIN VDD|===+5V */ /* ---|CLKOUT VSS|===GND */ /* CS2<--|RC0 RxD|<--TORX173 */ /* CS1<--|RC1 TxD|-->TOTX173 */ /* CL(PWM)<--|RC2 SDO|-->EEPROM_D */ /* EEPROM_C<--|SCK SDI|<--EEPROM_Q */ /* +---------------+ */ /* Analog Input: 赤外線脈波アンプ出力(0-5V,2.5V中心) */ /* 液晶モジュール関連 */ /* RES : H→Lで制御線がZ80系インターフェースに */ /* DB7-0 : データバス */ /* A0 : 0:制御コマンド 1:表示データ */ /* WR : ↑でDB7-0をレジスタ又はメモリに書込む */ /* RD : LでDB7-0にデータ又はステータスを読出し */ /* CS1 : Lでチップ1(左側)をセレクト */ /* CS2 : Lでチップ1(左側)をセレクト */ /* 注意: Version1.00では以下の処理は含まない */ /* トスリンクシリアル通信(TORX173,TOTX173) */ /* EEPROM拡張フォント(CS,C,D,Q) */ void CS12() /* CS1=CS2=Low */ { output_bit(PIN_C1,0);output_bit(PIN_C0,0); } void CS1() /* CS1=Low,CS2=High */ { output_bit(PIN_C1,0);output_bit(PIN_C0,1); } void CS2() /* CS1=High,CS2=Low */ { output_bit(PIN_C1,1);output_bit(PIN_C0,0); } void CSN() /* CS1=High,CS2=High */ { output_bit(PIN_C1,1);output_bit(PIN_C0,1); } void RSTS() /* ステータス・リード */ { set_tris_B(0b11111111); /* ポートBを入力に切替 */ output_bit(PIN_A1,0); /* コマンド(A0=0) */ delay_us(2); /* */ output_bit(PIN_A5,0); /* (RD=0) */ delay_us(2); /* */ sts=input_b(); /* ポートBからステータス読込 */ output_bit(PIN_A5,1); /* (RD=1) */ delay_us(1); /* */ } void RDAT() /* 表示RAMからデータ読出し */ { set_tris_B(0b11111111); /* ポートBを入力に切替 */ output_bit(PIN_A1,1); /* 表示データ(A0=1) */ delay_us(2); /* */ output_bit(PIN_A5,0); /* (RD=0) */ delay_us(2); /* */ rdt=input_b(); /* ポートBからデータを読込む */ output_bit(PIN_A5,1); /* (RD=1) */ delay_us(1); /* */ } void WCMD() /* コマンドライト */ { set_tris_B(0b00000000); /* ポートBを出力に切替 */ output_b(cmd); /* ポートBにコマンドを出力 */ output_bit(PIN_A1,0); /* コマンド(A0=0) */ delay_us(2); /* */ output_bit(PIN_A3,0); /* (WR=0) */ delay_us(2); /* */ output_bit(PIN_A3,1); /* (WR=1) */ delay_us(1); /* */ } void WDAT() /* 表示RAMにデータ書込み */ { set_tris_B(0b00000000); /* ポートBを出力に切替 */ output_b(wdt); /* ポートBにデータを出力する */ output_bit(PIN_A1,1); /* 表示データ(A0=1) */ delay_us(2); /* */ output_bit(PIN_A3,0); /* (WR=0) */ delay_us(2); /* */ output_bit(PIN_A3,1); /* (WR=1) */ delay_us(1); /* */ } void LCD_On() /* 液晶表示ON */ { CS12(); cmd=(0b10101111); WCMD(); } void LCD_Line() /* 表示開始ゼロ行目から */ { CS12(); cmd=(0b11000000); WCMD(); } void LCD_Clr() /* 液晶画面クリア */ { CS12(); /* 左右2チップを同時選択 */ for (j=0;j<3;j++) /* 各ページ毎にカラム0-60をクリア */ { cmd=(0b10111000)|j; WCMD(); /* ページアドレス j */ for (i=0;i<61;i++) { cmd=i; WCMD(); /* カラムアドレス 0-60 */ wdt=0; WDAT(); } } } void putD(int8 code) /* 指定文字code(Ascii)を指定位置(row,col)に描画する */ { if (code<0x20 || code >0x80) break; i=(code & 0x0F)<<3; if (code>0x2F) goto cp1; for (j=0;j<8;j++) { pat[j]=Font20[i]; i++; } goto cpe; cp1: if (code>0x3F) goto cp2; for (j=0;j<8;j++) { pat[j]=Font30[i]; i++; } goto cpe; cp2: if (code>0x4F) goto cp3; for (j=0;j<8;j++) { pat[j]=Font40[i]; i++; } goto cpe; cp3: if (code>0x5F) goto cp4; for (j=0;j<8;j++) { pat[j]=Font50[i]; i++; } goto cpe; cp4: if (code>0x6F) goto cp5; for (j=0;j<8;j++) { pat[j]=Font60[i]; i++; } goto cpe; cp5: if (code>0x7F) goto cpe; for (j=0;j<8;j++) { pat[j]=Font70[i]; i++; } cpe: if (col<61) { i=col; CS1(); } else { i=col-61; CS2(); } if (col>120) { col=0; row++; } if (row>3) row=0; for (j=0;j<8;j++) { cmd=(0b10111000) | row; WCMD(); /* ページアドレスx */ cmd=i; WCMD(); /* カラムアドレス */ wdt=pat[j]; WDAT(); /* pattern data */ col++; i++; if (col==61) { i=0; CS2(); } } } void LCD_Home() /* 液晶画面ホームポジション */ { row=col=0; CS1(); cmd=(0b10111000); WCMD(); /* ページアドレス 0 */ cmd=(0b00000000); WCMD(); /* カラムアドレス 0 */ col=24; /* 0行24桁から"Neo-Tech-Lab"を描画する */ putD(0x4E); putD(0x65); putD(0x6F); putD(0x2D); putD(0x54); putD(0x65); putD(0x63); putD(0x68); putD(0x2D); putD(0x4C); putD(0x61); putD(0x62); col=0; } /* USART 受信割込み処理関数 */ #int_rda void rxd() { } //************************************************* // AD変換データ上位 5 bit を取出す。 //************************************************* /* タイマー割込み */ #int_timer1 void tim1() { set_timer1(0x3CAF); //10mSecの割込み tc++; if (tc>2) //30mSecの割込みを作る { tc=0; x=read_adc()>>5; if (x>xp) pa=p[xp] & q[x]; else pa=p[x] & q[xp]; if (col<61) { i=col; CS1(); } else { i=col-61; CS2(); } cmd=(0b10111000); WCMD(); /* ページアドレス0 */ cmd=i; WCMD(); /* カラムアドレス */ wdt=make8(pa,0); WDAT(); cmd=(0b10111001); WCMD(); /* ページアドレス1 */ cmd=i; WCMD(); /* カラムアドレス */ wdt=make8(pa,1); WDAT(); cmd=(0b10111010); WCMD(); /* ページアドレス2 */ cmd=i; WCMD(); /* カラムアドレス */ wdt=make8(pa,2); WDAT(); cmd=(0b10111011); WCMD(); /* ページアドレス3 */ cmd=i; WCMD(); /* カラムアドレス */ wdt=make8(pa,3); WDAT(); col++; if (col==122) { LCD_Clr(); LCD_Home(); } xp=x; } } void main() { port_b_pullups(FALSE); // No Pullup set_tris_B(0b00000000); // Port_B All Output output_a(0b00111000); // RES: pullupHigh --> Low (Z80_mode) set_tris_A(0b00000001); // Port_A output_c(0b01000011); // CS2=CS1=High set_tris_C(0b10010000); /* PWMで液晶駆動クロック1.2kHzを作る */ setup_ccp1(CCP_PWM); //PWM MODE setup_timer_2(T2_DIV_BY_16,0xFF,1); //プリスケーラ16 ,PR2フルビット=FF set_pwm1_duty(0x1FF); //duty=50% 3FF/2=1FF /* 内蔵A/Dコンバータ初期化 */ setup_adc( ADC_CLOCK_DIV_32 ); /* 1.6usec @ 20MHz */ setup_adc_ports(AN0); /* RA0 only */ set_adc_channel(0); /* Select AN0 */ /* 液晶初期化 */ cmd=(0b11101110); WCMD(); /* モードエンド */ LCD_On(); LCD_Line(); LCD_Clr(); LCD_Home(); x=xp=0; /* タイマー1初期化 */ setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); //プリスケーラ1 set_timer1(0x3CAF); /* 10msec = (FFFF-D'50000') */ tc=0; enable_interrupts(INT_TIMER1); /* タイマー割り込み許可 */ /* enable_interrupts(INT_RDA); */ enable_interrupts(GLOBAL); /* 割込み許可 */ while(TRUE) { } }