' '$prog &HFF , &HC2 , &HDC , &HF9 ' generated. Take care that the chip supports all fuse bytes. 'ヒューズ・ビット設定 CKDIV8 = 1 , BODLEVEL = 4.3V , SUT = 00 ' ' ********************************************** ' * LCD to LED (8-LED) 制御ボード * ' * * ' * AVR is using ATmega88P * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2010. 3.26 * ' ********************************************** ' ' Ver 1.01 初回公開バージョン ' ' '### LEDのコモンタイプを指定する ### Const Led_type = 0 'カソードコモン = 0 , アノードコモン = 1 ' ' $regfile = "m88pdef.dat" '使用するAVRを設定。 $crystal = 8000000 'AVRクロックを設定。 ' $hwstack = 64 'ハードウェア・スタックの容量を設定。 $swstack = 8 'ソフトウェア・スタックの容量を設定。 $framesize = 24 'フレーム領域の容量を設定。 ' Const Bright = 110 '輝度の初期値。 ' ' * 変数の宣言 * ' Dim Led_counter As Byte 'ダイナミック点灯の桁カウンター。 Dim Led_buff(8) As Byte 'ダイナミック点灯のセグメントデータ。 Dim Led_temp1 As Byte 'LED用 汎用テンポラリ変数 Byte型 No.1 ' Dim Comflag As Byte 'LCDコマンドの受信フラグ。 Dim Comdata As Byte 'LCDコマンドの受信データ。 Dim Comulbit As Byte 'LCDコマンド 4bit上位・下位フラグ。 Dim Comcode As Byte 'LCDコマンド 8bitコード。 Dim Ddram_adr As Byte 'DDRAM(表示データ)アドレス。 Dim Cgram_adr As Byte 'CGRAM(キャラクタ・ジェネレータ)アドレス。 Dim Ddram_buff(128) As Byte 'DDRAM(表示データ)バッファー。 Dim Cgram_buff(64) As Byte 'CGRAM(キャラクタ・ジェネレータ)バッファー。 Dim Curmode As Byte 'カーソル制御モード。(bit1:ON/OFF bit0:ブリンク) Dim Curdirec As Byte 'カーソルの移動方向。(bit1:0-左 bit1:1-右) Dim Ramadrsel As Byte 'RAMアドレスの選択。(0:DDRAM , 1:CGRAM) Dim Blinkdata As Byte 'カーソルブリンク時の元データ保管用。 Dim Blinkff As Byte 'カーソルブリンク用F/F。 ' Dim Temp1 As Byte '汎用テンポラリ変数 Byte型 No.1 Dim Temp2 As Byte '汎用テンポラリ変数 Byte型 No.2 ' ' * ポート名の定義 * ' Led_common Alias Portb 'LEDのコモン端子接続ポート。 Led_segment Alias Portd 'LEDのセグメント端子接続ポート。 ' ' * ポートの初期設定 * ' Config Led_common = Output 'LEDのコモン端子接続ポートを出力に設定する。 Config Led_segment = Output 'LEDのセグメント端子接続ポートを出力に設定する。 Portc = &B0011_1111 '制御入力端子をプルアップ。 Config Aci = Off 'アナログ比較器の電源を切る。 ' ' * タイマーの設定 * ' Config Timer2 = Timer , Prescale = 8 , Clear Timer = 1 '8,000,000Hz / 8 = 1,000,000Hz (ダイナミック点灯用) Ocr2a = 125 - 1 '1,000,000Hz / 8,000Hz = 125カウント Ocr2b = Bright '輝度の初期値を設定する。 ' Config Timer1 = Timer , Prescale = 256 , Clear Timer = 1 '8,000,000Hz / 256 = 31,250Hz(カーソル点滅用) Compare1a = 12500 - 1 '31,250Hz / 2.5Hz(400mS) = 12,500カウント ' ' * LCDコマンド割り込みの設定 * ' Set Pcmsk1.pcint9 'PC1のピン変化割り込みを許可する。 On Pcint1 Lcdeint Nosave 'PC1のピン変化割り込み1ルーチンを設定。 Enable Pcint1 'ピン変化割り込み1を許可。 Set Pcifr.pcif1 'ピン変化割り込み1をリセットする。 ' ' * プログラムの初期設定 * ' For Temp1 = 1 To 128 'DDRAM(表示データ)バッファーをスペースにクリアする。 Ddram_buff(temp1) = &H20 Next Temp1 ' Led_counter = 0 '桁カウンターの初期値。 Comulbit = 8 'LCDコマンドを8bitモードに初期化。 Ddram_adr = 1 Cgram_adr = 1 Ramadrsel = 0 Enable Interrupts 'すべての割り込みを許可。 ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: Gosub Lcdcom 'LCDコマンドの受信と分析処理。 Gosub Curblink 'カーソルの点滅処理。 ' If Tifr2.ocf2a = 1 Then 'If ダイナミック点灯時間か? Then Led_temp1 = 0 'Timer2 比較A一致フラグをリセット。 Set Led_temp1.ocf2a Tifr2 = Led_temp1 Gosub Ledcomset End If ' If Tifr2.ocf2b = 1 Then 'If ダイナミック消灯時間か? Then Led_temp1 = 0 'Timer2 比較B一致フラグをリセット。 Set Led_temp1.ocf2b Tifr2 = Led_temp1 Gosub Ledcomoff End If Goto Main ' ' ******************************* ' * LCDコマンドの受信と分析処理 * ' ******************************* ' Lcdcom: If Comflag = 0 Then Return 'If LCDコマンドの受信無しか? Then Comflag = 0 If Comulbit = 8 Then Goto Lcdcom1 'If LCDコマンドが8bitバスモードか? Then ' Temp1 = Comdata And &B0011_1100 '4bit LCDコマンドの上下バイトを合成する。 If Comulbit <> 0 Then Goto Lcdcom2 'If 下位データか? Then ' Shift Temp1 , Left , 2 '上位データを受信。 Comcode = Temp1 Comulbit = 1 Return ' ' Lcdcom1: 'LCDコマンドが8bitバスモード。 Comdata = Comdata And &B0011_1101 If Comdata = &H0C Then Comulbit = 8 'If LCDコマンドが[&H30]8bitバス指定か? Then If Comdata = &H08 Then Comulbit = 0 'If LCDコマンドが[&H20]4bitバス指定か? Then Ocr2b = Bright '輝度の初期値を設定する。 Return ' ' * 下位データの受信とコマンド処理 * ' Lcdcom2: Shift Temp1 , Right , 2 Comcode = Comcode Or Temp1 '8bitに合成する。 Comulbit = 0 ' If Blinkff <> 0 Then 'If カーソル消灯中か? Then Led_buff(ddram_adr) = Blinkdata 'カーソル位置のデータを戻す。 End If ' If Comdata.0 = 1 Then Goto Lcdcom3 'If RAMデータ書き込みか(RS=1)? Then ' ' * LCD制御コマンドの処理 * ' Select Case Comcode Case Is > &H7F : 'If コマンド[bit7] DDRAMアドレス設定か? Ddram_adr = Comcode And &H7F Ddram_adr = Ddram_adr + 1 Ramadrsel = 0 ' Case Is > &H3F : 'If コマンド[bit6] CGRAMアドレス設定か? Cgram_adr = Comcode And &H3F Cgram_adr = Cgram_adr + 1 Ramadrsel = 1 ' Case Is > &H1F : 'If コマンド[bit5] 機能設定か? If Comcode.4 = 1 Then 'If LCDコマンドが[&H30](DL=1)8bitバス指定か? Then Comulbit = 8 End If ' Case Is > &H0F : 'If コマンド[bit4] カーソル表示シフトか? If Comcode.3 = 0 Then 'If カーソル移動(S/C=0)か? Then If Comcode.2 = 0 Then 'If 左移動(R/L=0)か? Then If Ddram_adr <> 1 Then 'If DDRAMアドレスが左端でないか? Then Ddram_adr = Ddram_adr - 1 End If Else '右移動(R/L=1) If Ddram_adr < &H80 Then 'If DDRAMアドレスが終端でないか? Then Ddram_adr = Ddram_adr + 1 End If End If End If ' Case Is > &H07 : 'If コマンド[bit3] 表示ON/OFFか? Curmode = Comcode And &H03 'カーソルの制御モードを設定する。 If Comcode.2 = 0 Then 'If 表示オフ(SLEEP)か? Then Bitwait Pinc.1 , Reset '[E]信号が(L)になるまで待つ。 Portc = &H00 '制御入力端子のプルアップを禁止する。 Led_common = 0 'LEDのコモン端子接続ポートをオフに設定する。 Led_segment = 0 'LEDのセグメント端子接続ポートをオフに設定する。 $asm IN R16,MCUCR '[BOD]の休止設定。 ORI R16,$60 Out Mcucr , R16 'BODSとBODSEに[1]をセットする。 Out Mcucr , R16 'BODSに[1]をセットする。 ANDI R16,$DF Out Mcucr , R16 'BODSEに[0]をセットする。 $end Asm 'Power Powerdown 'AVRをパワーダウン・モードに移行する。 Powerdown '(仮)レジファイル[m88pdef.dat]にバグ有り。 Portc = &B0011_1111 '制御入力端子をプルアップ。 End If ' Case Is > &H03 : 'If コマンド[bit2] 入力モード設定か? Curdirec = Comcode And &H03 ' Case Is > &H01 : 'If コマンド[bit1] カーソルをホーム移動か? Ddram_adr = 1 Ramadrsel = 0 ' Case &H01 : 'If コマンド[bit0] 表示消去か? For Temp1 = 1 To 128 'DDRAM(表示データ)バッファーをスペースにクリアする。 Ddram_buff(temp1) = &H20 Next Temp1 For Temp1 = 1 To 8 'LEDのセグメントデータバッファをクリアする。 Led_buff(temp1) = &H00 Next Temp1 Ddram_adr = 1 Ramadrsel = 0 End Select ' Lcdcom9: Blinkff = 0 'カーソルブリンク用F/Fをリセットする。 Return ' ' * RAMデータ書き込み処理 * ' Lcdcom3: If Ramadrsel = 1 Then Goto Lcdcom4 'If CGRAMへの書き込みか? Then If Comcode > &H7F Then Goto Lcdcom5 'If 輝度制御コードか? Then ' Ddram_buff(ddram_adr) = Comcode 'DDRAMに文字コードを書き込む。 If Ddram_adr < 9 Then 'If LEDの表示エリアか? Then If Comcode = &H2E Then 'If ピリオドか? Then Temp1 = Ddram_adr If Temp1 <> 1 Then 'If カーソル位置が左端以外か? Then Temp1 = Temp1 - 1 End If Temp2 = Led_buff(temp1) 'LED表示にピリオドを重ねる。 Temp2 = Temp2 Or &H80 Led_buff(temp1) = Temp2 Else 'ピリオド以外の場合。 If Comcode < &H20 Then 'If [00-1F] ユーザーCGか? Then Temp1 = Comcode + 1 Temp2 = Cgram_buff(temp1) Led_buff(ddram_adr) = Temp2 Gosub Curmove 'カーソルの移動制御。 Else '[20-7F] 記号・英文字。 Temp1 = Comcode - &H20 Temp2 = Lookup(temp1 , Led_segdata) Led_buff(ddram_adr) = Temp2 Gosub Curmove 'カーソルの移動制御。 End If End If End If Goto Lcdcom9 ' ' * CGRAMへの書き込み * ' Lcdcom4: Cgram_buff(cgram_adr) = Comcode 'CGRAMにデータを書き込む。 Cgram_adr = Cgram_adr + 1 Goto Lcdcom9 ' ' * 輝度制御 * ' Lcdcom5: Temp1 = Comcode And &H7F Select Case Temp1 '輝度値の上下限を確認する。 Case Is < 5 : Temp1 = 5 Case Is > 115 : Temp1 = 115 End Select Ocr2b = Temp1 '輝度値をタイマーに設定する。 Goto Lcdcom9 ' ' * カーソル移動制御 サブルーチン * ' Curmove: If Curdirec.1 = 1 Then 'If カーソルの移動方向が右か? Then If Ddram_adr < &H80 Then 'If DDRAMアドレスが終端でないか? Then Ddram_adr = Ddram_adr + 1 End If Else If Ddram_adr <> 1 Then 'If DDRAMアドレスが左端でないか? Then Ddram_adr = Ddram_adr - 1 End If End If Return ' ' ********************** ' * カーソルの点滅処理 * ' ********************** ' Curblink: If Curmode.0 = 0 Then Return 'If カーソルのブリンクがOFFか? Then ' If Tifr1.ocf1a = 1 Then 'If 400mS経過したか? Then Set Tifr1.ocf1a 'Timer1 比較A一致フラグをリセット。 If Blinkff = 0 Then 'If カーソル消灯か? Then Blinkdata = Led_buff(ddram_adr) 'カーソル位置のデータを保管する。 If Blinkdata = 0 Then 'If カーソル位置の表示がスペースか? Then Temp1 = &H08 '[_]を表示する。 Else Temp1 = &H00 '消灯する。 End If Led_buff(ddram_adr) = Temp1 Blinkff = 1 Else Led_buff(ddram_adr) = Blinkdata Blinkff = 0 End If End If Return ' ' *********************************** ' * LCDコマンド割り込み処理 [E]信号 * ' *********************************** ' Lcdeint: $asm PUSH R0 PUSH R16 IN R0,SREG 'ステータス・レジスタを待避。 ' SBIS PINC,1 'If [E]信号の立ち上がりか? Then RJMP Lcdeint1 ' SER R16 'LCDコマンドフラグをセットする。 STS {comflag},R16 IN R16,PINC 'LCDコマンドを保管する。 STS {comdata},R16 ' Lcdeint1: Out Sreg , R0 'ステータス・レジスタを復帰。 POP R16 POP R0 $end Asm Return ' ' ******************************************* ' * ダイナミック点灯 コモン表示制御ルーチン * ' ******************************************* ' Ledcomset: #if Led_type = 0 'カソードコモンの場合。 Led_segment = Led_buff(led_counter + 1) #else 'アノードコモンの場合。 Led_temp1 = Led_buff(led_counter + 1) Led_segment = Not Led_temp1 #endif ' On Led_counter Goto Ledcom0 , Ledcom1 , Ledcom2 , Ledcom3 , Ledcom4 , Ledcom5 , Ledcom6 , Ledcom7 Ledcom0: Led_common = &B0010_0000 Goto Ledcomend ' Ledcom1: Led_common = &B0100_0000 Goto Ledcomend ' Ledcom2: Led_common = &B1000_0000 Goto Ledcomend ' Ledcom3: Led_common = &B0000_0001 Goto Ledcomend ' Ledcom4: Led_common = &B0000_1000 Goto Ledcomend ' Ledcom5: Led_common = &B0000_0100 Goto Ledcomend ' Ledcom6: Led_common = &B0000_0010 Goto Ledcomend ' Ledcom7: Led_common = &B0001_0000 ' Ledcomend: Led_counter = Led_counter + 1 If Led_counter > 7 Then Led_counter = 0 Return ' ' ******************************************* ' * ダイナミック点灯 コモン消灯制御ルーチン * ' ******************************************* ' Ledcomoff: Led_common = 0 #if Led_type = 0 'カソードコモンの場合。 Led_segment = 0 #else 'アノードコモンの場合。 Led_segment = &HFF #endif Return ' ' End ' ' * ASCII文字コード → セグメント・データ 変換テーブル * ' Led_segdata: Data &H00 , &H01 , &H02 , &H24 , &H41 , &H10 , &H20 , &H09 ' !”#$%&’ Data &H39 , &H0F , &H22 , &H14 , &H80 , &H40 , &H80 , &H52 '()*+,-./ Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 '01234567 Data &H7F , &H6F , &H03 , &H18 , &H21 , &H48 , &H0C , &H64 '89:;<=>? Data &H5F , &H77 , &H7C , &H58 , &H5E , &H79 , &H71 , &H3D '@ABCDEFG Data &H74 , &H04 , &H1E , &H75 , &H38 , &H37 , &H54 , &H5C 'HUJKLMNO Data &H73 , &H67 , &H50 , &H6C , &H78 , &H1C , &H3E , &H2A 'PQRSTUVW Data &H76 , &H6E , &H1B , &H60 , &H62 , &H42 , &H23 , &H08 'XYZ[\]^_ Data &H36 , &H77 , &H7C , &H58 , &H5E , &H79 , &H71 , &H3D '`abcdefg Data &H74 , &H04 , &H1E , &H75 , &H38 , &H37 , &H54 , &H5C 'hijklmno Data &H73 , &H67 , &H50 , &H6C , &H78 , &H1C , &H3E , &H2A 'pqrstuvw Data &H76 , &H6E , &H1B , &H63 , &H12 , &H44 , &H46 , &H70 'xyz{|}