' ' ********************************************** ' * * ' * AVR & BASCOM-AVR トレーニング・ボード * ' * 初期設定 Ver.1.01 * ' * * ' * AVR is using ATmega88P * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2010.10.29 * ' ********************************************** ' $regfile = "m88pdef.dat" '使用するAVRを設定。 $crystal = 16000000 'AVRクロックを設定。 ' $hwstack = 64 'ハードウェア・スタックの容量を設定。 $swstack = 10 'ソフトウェア・スタックの容量を設定。 $framesize = 24 'フレーム領域の容量を設定。 ' ' * ポート名の定義 * ' Sw_1 Alias Pind.0 'スイッチ[1]の接続ポート。 Sw_2 Alias Pind.1 'スイッチ[2]の接続ポート。 Sw_3 Alias Pind.2 'スイッチ[3]の接続ポート。 Sw_4 Alias Pind.3 'スイッチ[4]の接続ポート。 ' Led_1r Alias Portd.4 'LED1[赤]の接続ポート。 Led_2g Alias Portd.5 'LED2[緑]の接続ポート。 Led_3y Alias Portd.6 'LED3[黄]の接続ポート。 Led_4b Alias Portd.7 'LED4[青]の接続ポート。 Sp_out Alias Portc.5 'スピーカーの接続ポート。 ' Ad_photo Alias 0 '光センサーのA/Dコンバータ・チャネル番号。 Ad_thermo Alias 1 '温度センサーのA/Dコンバータ・チャネル番号。 Ad_ain1 Alias 2 '測定入力[1]のA/Dコンバータ・チャネル番号。 Ad_ain2 Alias 3 '測定入力[2]のA/Dコンバータ・チャネル番号。 Ad_ain3 Alias 4 '測定入力[3]のA/Dコンバータ・チャネル番号。 Ad_spin Alias 5 'スピーカー入力のA/Dコンバータ・チャネル番号。 ' ' * ポートの初期設定 * ' Config Led_1r = Output 'LED1の接続ポートを出力に設定する。 Config Led_2g = Output 'LED2の接続ポートを出力に設定する。 Config Led_3y = Output 'LED3の接続ポートを出力に設定する。 Config Led_4b = Output 'LED4の接続ポートを出力に設定する。 Config Sp_out = Output 'スピーカーの接続ポートを出力に設定する。 ' Set Portd.0 'スイッチ[1]の接続ポートをプルアップする。 Set Portd.1 'スイッチ[2]の接続ポートをプルアップする。 Set Portd.2 'スイッチ[3]の接続ポートをプルアップする。 Set Portd.3 'スイッチ[4]の接続ポートをプルアップする。 Didr0 = &B00111111 'デジタル入力禁止レジスタの設定。 ' ' * LCDの初期設定 * ' Config Lcdmode = Port 'LCDを4ビットのポートモードに設定。 Config Lcdbus = 4 'LCDデータバスを4bitに設定。 Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 'LCDのポート割り当て。 Config Lcdpin = Pin , Db6 = Portb.1 , Db7 = Portb.0 Config Lcdpin = Pin , E = Portb.4 , Rs = Portb.5 Config Lcd = 16 * 2 'LCD表示を16文字2行に設定。 Cls 'LCD表示をすべて消去。 ' ' * A/Dコンバータの初期設定 * ' Config Adc = Single , Prescaler = Auto , Reference = Avcc 'A/Dコンバータの設定。 Start Adc 'A/Dコンバータに電源を供給。 ' ' ↓********************************************↓ ' ↓ これ以降に各自のプログラムを作成して下さい ↓ ' ↓********************************************↓ ' '================================================================================================== ' ' ************************************* ' * デジタル温度センサー [DS18B20] * ' * 温度制御+アラーム プログラム * ' * O-Family 2022. 7.31 * ' ************************************* Dim Temperature As Integer '温度の測定値。(温度値x10, 25.6℃ = 256) Dim Temperror As Byte '[DS18B20]のエラーフラグ。(0:正常, 1:デバイスが見つからない, 2:CRCエラー) Dim Rxbuff(9) As Byte '受信データを格納する配列。 Dim Swcount As Byte 'スイッチ入力チェック用タイマーカウンター。 Dim Swflag As Byte 'スイッチ入力検出フラグ。 Dim Swdata As Byte 'スイッチ入力データ。 Dim Swtemp As Byte 'スイッチ入力データの一時保管用。 Dim Opmode As Byte '動作モード。(0:OFF, 1:アラームのみ, 2:制御のみ, 3:アラーム+制御, 4:一時停止中) Dim Interval As Word 'アラームと制御の時間間隔。(秒) Dim Hightemp As Integer '高温の設定値。(温度値x10, 25.6℃ = 256) Dim Lowtemp As Integer '低温の設定値。(温度値x10, 25.6℃ = 256) Dim Setposition As Byte '設定カーソルの位置。(0:設定終了, 1:動作モード, 2:時間間隔, 3:高温の設定値, 4:低温の設定値) Dim Alarmtime As Word 'アラーム検出間隔のタイマー。 ' Dim Temp1 As Byte '汎用テンポラリ変数 Byte型 No.1 Dim Tempi1 As Integer '汎用テンポラリ変数 Integer型 No.1 Dim Templ1 As Long '汎用テンポラリ変数 Long型 No.1 Dim Tempstr As String * 20 '汎用テンポラリ変数 String型 No.1 ' Dim Eepdummy As Eram Long 'EEPROM 4バイトのダミーエリア。 Dim Eepprgid As Eram Long 'EEPROM プログラムのID。 Dim Eepopmode As Eram Byte 'EEPROM 動作モード。(0:OFF, 1:アラームのみ, 2:制御のみ, 3:アラーム+制御) Dim Eepinterval As Eram Word 'EEPROM アラームと制御の時間間隔。(秒) Dim Eephightemp As Eram Word 'EEPROM 高温の設定値。(温度値x10, 25.6℃ = 256) Dim Eeplowtemp As Eram Word 'EEPROM 低温の設定値。(温度値x10, 25.6℃ = 256) '-------------------------------------------------------------------------------------------------- Deflcdchar 0 , &H08 , &H14 , &H08 , &H06 , &H09 , &H08 , &H09 , &H06 'カスタム文字[℃]をLCDへ書き込む。 Deflcdchar 1 , &H17 , &H0B , &H17 , &H19 , &H16 , &H17 , &H16 , &H19 'カスタム文字[℃]の反転をLCDへ書き込む。 Cursor Off 'LCDのカーソルをオフにする。 ' Config Timer0 = Timer , Prescale = 1024 , Clear Timer = 1 '16,000,000Hz / 1024 = 15,625Hz Compare0a = 156 - 1 '15,625Hz / 156カウント= 約100Hz(10mS) ' Config Timer1 = Timer , Prescale = 1024 , Clear Timer = 1 'Timer1の設定。16,000,000Hz / 1024 = 15,625Hz Compare1a = 15625 - 1 '15,625Hz / 15625カウント = 1Hz(1秒) ' Config 1wire = Portd.3 '[DS18B20]のデータ線を接続するポートピンを設定する。 ' ' * EEPROMのデータを確認する * ' If Eepprgid <> &H38315344 Then 'If EEPROMが初期値か? Then Eepprgid = &H38315344 'EEPROM プログラムのID。[DS18]" Eepopmode = 0 'EEPROM 動作モード。(0:OFF, 1:アラームのみ, 2:制御のみ, 3:アラーム+制御) Eepinterval = 10 'EEPROM アラームと制御の時間間隔。(秒) Eephightemp = 300 'EEPROM 高温の設定値。(温度値x10, 30.0℃ = 300) Eeplowtemp = 100 'EEPROM 低温の設定値。(温度値x10, 10.0℃ = 100) End If ' Opmode = Eepopmode '動作モード。(0:OFF, 1:アラームのみ, 2:制御のみ, 3:アラーム+制御, 4:一時停止中) Interval = Eepinterval 'アラームと制御の時間間隔。(秒) Hightemp = Eephightemp '高温の設定値。(温度値x10, 25.6℃ = 256) Lowtemp = Eeplowtemp '低温の設定値。(温度値x10, 25.6℃ = 256) ' Setposition = 0 '設定カーソルの位置。(0:設定終了, 1:動作モード, 2:時間間隔, 3:高温の設定値, 4:低温の設定値) Gosub Opmodedisp '動作モードをLCDに表示する。 Gosub Intervaldisp '時間間隔をLCDに表示する。 Gosub Hightempdisp '高温の設定値をLCDに表示する。 Gosub Lowtempdisp '低温の設定値をLCDに表示する。 Alarmtime = 0 'アラームのタイマーをクリアする。 '-------------------------------------------------------------------------------------------------- ' ' ******************** ' * メイン・ルーチン * ' ******************** ' Main: ' ' * 10mS毎の処理 * ' If Tifr0.ocf0a = 1 Then 'If 10mS経過したか? Then Set Tifr0.ocf0a 'Timer0 比較A一致フラグをリセット。 ' Gosub Swin 'スイッチ入力の検出。 ' ' * スイッチ入力の処理 * ' Select Case Swflag Case 1 : 'ボタンの短押しの場合。 Select Case Swdata Case &B0000_0001 '[SW1]が押された場合。 Reset Led_1r 'LED1[赤]を消灯し、外部出力(6ピン)を[L]にする。 Reset Led_2g 'LED2[緑]を消灯し、外部出力(7ピン)を[L]にする。 If Opmode = 4 Then 'If 一時停止中か? Then Opmode = Eepopmode '一時停止の前の状態に戻す。 Gosub Opmodedisp '動作モードをLCDに表示する。 End If ' Setposition = Setposition + 1 '設定カーソルの位置を移動させる。 If Setposition > 4 Then 'If 設定終了か? Then Setposition = 0 Gosub Beep1k50ms '1000Hzの音を50mS鳴らす。 Waitms 50 End If Gosub Beep1k50ms '1000Hzの音を50mS鳴らす。 Gosub Cursordisp '設定カーソルを表示する。 ' Case &B0000_0010 '[SW2]が押された場合。 Gosub Pushsw2 '設定中に[SW2]が押された場合の処理を行う。 ' Case &B0000_0100 '[SW3]が押された場合。 Gosub Pushsw3 '設定中に[SW3]が押された場合の処理を行う。 ' Case &B0000_0011 '[SW1]と[SW2]が同時に押された場合。 If Opmode = 4 Then 'If 一時停止中か? Then Opmode = Eepopmode '一時停止の前の状態に戻す。 Else Opmode = 4 '一時停止中にする。 Reset Led_1r 'LED1[赤]を消灯し、外部出力(6ピン)を[L]にする。 Reset Led_2g 'LED2[緑]を消灯し、外部出力(7ピン)を[L]にする。 End If Gosub Opmodedisp '動作モードをLCDに表示する。 Gosub Beep1k50ms '1000Hzの音を50mS鳴らす。 End Select Swflag = 0 ' Case 2 : 'ボタンの1秒長押しの場合。 Select Case Swdata Case &B0000_0010 '[SW2]が長押しされた場合。 Gosub Pushsw2 '設定中に[SW2]が押された場合の処理を行う。 ' Case &B0000_0100 '[SW3]が長押しされた場合。 Gosub Pushsw3 '設定中に[SW3]が押された場合の処理を行う。 End Select Swflag = 0 End Select End If ' ' * 1秒毎の処理 * ' If Tifr1.ocf1a = 1 Then 'If 1秒経過したか? Then Set Tifr1.ocf1a 'Timer1 比較A一致フラグをリセットする。 ' Gosub Tempread '[DS18B20]から温度データを読み出す。 ' If Setposition = 0 Then 'If 設定中ではないか? Then ' ' * 測定温度値を表示する * ' Locate 1 , 1 Select Case Temperror '[DS18B20]の状態により処理する。 Case 0 : '[DS18B20]の通信が正常の場合。 Tempstr = Str(temperature) '数値変数を文字変数に変換する。 Lcd "["; If Temperature < 0 Then 'If 温度値がマイナスか? Then Lcd Format(tempstr , " 0.0") ; '温度値を表示する。 Else '温度値がプラスの場合。 Lcd Format(tempstr , " 0.0") ; '温度値を表示する。 End If Lcd " " ; Chr(0) ; "]" '℃を表示する。 ' Case 1 : '[DS18B20]が見つからない場合。 Lcd "Not found" ' Case 2 : 'CRCにエラーがある場合。 Lcd "CRC Error" End Select ' ' * アラームと制御出力の処理 * ' Alarmtime = Alarmtime + 1 'アラーム検出間隔のタイマーを加算する。 If Alarmtime >= Interval Then 'If アラームの検出時間になったか? Then Alarmtime = 0 'アラームのタイマーをクリアする。 ' Locate 1 , 16 '高温の設定値の確認。 If Temperature >= Hightemp Then 'If 温度の測定値が高温の設定値以上になったか? Then Lcd Chr(1) ; '[℃]を反転表示する。 If Opmode = 1 Or Opmode = 3 Then 'If 動作モードが[1]:アラームのみ または[3]:アラーム+制御か? Then Gosub Beep4k100ms '4000Hzの音を100mS鳴らす。 End If If Opmode = 2 Or Opmode = 3 Then 'If 動作モードが[2]:制御のみ または[3]:アラーム+制御か? Then Set Led_1r 'LED1[赤]を点灯し、外部出力(6ピン)を[H]にする。 End If Else Lcd Chr(0) ; '[℃]を通常表示する。 Reset Led_1r 'LED1[赤]を消灯し、外部出力(6ピン)を[L]にする。 End If Locate 2 , 16 '低温の設定値の確認。 If Temperature <= Lowtemp Then 'If 温度の測定値が低温の設定値以下になったか? Then Lcd Chr(1) ; '[℃]を反転表示する。 If Opmode = 1 Or Opmode = 3 Then 'If 動作モードが[1]:アラームのみ または[3]:アラーム+制御か? Then Gosub Beep4k100ms '4000Hzの音を100mS鳴らす。 End If If Opmode = 2 Or Opmode = 3 Then 'If 動作モードが[2]:制御のみ または[3]:アラーム+制御か? Then Set Led_2g 'LED2[緑]を点灯し、外部出力(7ピン)を[H]にする。 End If Else Lcd Chr(0) ; '[℃]を通常表示する。 Reset Led_2g 'LED2[緑]を消灯し、外部出力(7ピン)を[L]にする。 End If End If End If End If ' Goto Main '================================================================================================== ' ' ************************************************* ' * [DS18B20]から温度データを読み出すサブルーチン * ' ************************************************* ' Tempread: 1wreset '1-Wireバスを初期化する。(リセットを送信) If Err = 1 Then Goto Tempread1 'If デバイスが接続されていないか? Then ' 1wwrite &HCC '[SKIP ROM]コマンドを送信する。(シリアル番号の指定をしない) 1wwrite &HBE '[READ SCRATCHPAD]コマンドを送信する。(温度データ読み込み) Rxbuff(1) = 1wread(9) '温度データを含むDS18B20のメモリー内容を受信する。 Temp1 = Crc8(rxbuff(1) , 9) '受信データの9バイトすべてでCRC8を計算する。 If Temp1 <> 0 Then Goto Tempread2 'If CRCエラーか? Then ' Tempi1 = Makeint(rxbuff(1) , Rxbuff(2)) '2バイトの温度データを1ワードにする。 Templ1 = Tempi1 * 625 'DS18B20の温度分解能を掛ける。(0.0625 X 10000) Templ1 = Templ1 / 1000 '表示用に桁合わせをする。(25.6℃ = 256) Temperature = Templ1 '温度データを保管する。(Integer型 25.6℃ = 256) Temperror = 0 '[DS18B20]のエラーフラグをクリアする。 ' Tempread3: '[DS18B20]に温度変換を開始させる。 1wreset '1-Wireバスを初期化する。(リセットを送信) 1wwrite &HCC '[SKIP ROM]コマンドを送信する。(シリアル番号の指定をしない) 1wwrite &H44 '[CONVERT T]コマンドを送信する。(温度変換) Return ' Tempread1: 'デバイスが見つからない場合。 Temperror = 1 Return ' Tempread2: 'CRCエラーの場合。 Temperror = 2 Goto Tempread3 ' -------------------------------------- ' * 1000Hzの音を50mS鳴らすサブルーチン * ' -------------------------------------- Beep1k50ms: Sound Sp_out , 50 , 1333 '1000Hzの音を50mS鳴らす。 Return ' -------------------------------------- ' * 4000Hzの音を100mS鳴らすサブルーチン * ' -------------------------------------- Beep4k100ms: Sound Sp_out , 400 , 333 '4000Hzの音を100mS鳴らす。 Return ' ' ************************************** ' * 設定カーソルを表示するサブルーチン * ' ************************************** ' Cursordisp: If Setposition = 0 Then 'If 設定終了か? Then Cursor Noblink Else '設定項目の選択の場合。 Select Case Setposition Case 1 : Locate 2 , 1 '[1] 動作モード。 Case 2 : Locate 2 , 7 '[2] 時間間隔。 Case 3 : Locate 1 , 12 '[3] 高温の設定値。 Case 4 : Locate 2 , 12 '[4] 低温の設定値。 Case Else : Locate 1 , 1 '[0] 設定終了。 End Select Cursor Blink End If Return ' ' ******************************************************* ' * 設定中に[SW2]が押された場合の処理を行うサブルーチン * ' ******************************************************* ' Pushsw2: Select Case Setposition Case 1 : '[1]動作モードの変更。 Opmode = Opmode - 1 Gosub Opmodeset '動作モードを設定してLCDへ表示する。 ' Case 2 : '[2]時間間隔の減算。 Interval = Interval - 1 Gosub Intervalset '時間間隔を設定してLCDへ表示する。 ' Case 3 : '[3]高温の設定値の減算。 Hightemp = Hightemp - 10 Gosub Hightempset '高温の設定値を設定してLCDへ表示する。 ' Case 4 : '[4]低温の設定値の減算。 Lowtemp = Lowtemp - 10 Gosub Lowtempset '低温の設定値を設定してLCDへ表示する。 End Select Return ' ' ******************************************************* ' * 設定中に[SW3]が押された場合の処理を行うサブルーチン * ' ******************************************************* ' Pushsw3: Select Case Setposition Case 1 : '[1]動作モードの変更。 Opmode = Opmode + 1 Gosub Opmodeset '動作モードを設定してLCDへ表示する。 ' Case 2 : '[2]時間間隔の加算。 Interval = Interval + 1 Gosub Intervalset '時間間隔を設定してLCDへ表示する。 ' Case 3 : '[3]高温の設定値の加算。 Hightemp = Hightemp + 10 Gosub Hightempset '高温の設定値を設定してLCDへ表示する。 ' Case 4 : '[4]低温の設定値の加算。 Lowtemp = Lowtemp + 10 Gosub Lowtempset '低温の設定値を設定してLCDへ表示する。 End Select Return ' ' ********************************* ' * 動作モードの設定とLCDへの表示 * ' ********************************* ' Opmodeset: '動作モードの設定。 Select Case Opmode Case 4 : Opmode = 0 '動作モードの上限の場合。 Case Is > 3 : Opmode = 3 '動作モードの下限の場合。 End Select Eepopmode = Opmode 'EEPROMに保存する。 ' Opmodedisp: '動作モードをLCDに表示。 Locate 2 , 1 Select Case Opmode Case 0 : Lcd " OFF " '[0]OFFの場合。 Case 1 : Lcd "Alarm" '[1]アラームのみの場合。 Case 2 : Lcd "Contr" '[2]制御のみの場合。 Case 3 : Lcd "Al+Cn" '[3]アラーム+制御の場合。 Case 4 : Lcd "-----" '[4]一時停止中の場合。 End Select Gosub Cursordisp '設定カーソルを表示する。 Return ' ' ******************************* ' * 時間間隔の設定とLCDへの表示 * ' ******************************* ' Intervalset: '時間間隔の設定。 Select Case Interval Case 1000 : Interval = 1 'If 時間間隔の上限か? Then Case 0 : Interval = 999 'If 時間間隔の下限か? Then End Select Eepinterval = Interval 'EEPROMに保存する。 ' Intervaldisp: '時間間隔をLCDに表示。 Locate 2 , 7 Tempstr = Str(interval) '数値変数を文字変数に変換する。 Lcd Format(tempstr , " 0") ; "s" '時間間隔の設定値を表示する。 Gosub Cursordisp '設定カーソルを表示する。 Return ' ' *********************************** ' * 高温の設定値の設定とLCDへの表示 * ' *********************************** ' Hightempset: '高温の設定値の設定。 Select Case Hightemp Case Is > 1250 : Hightemp = 1250 'If 高温の設定値の上限か? Then Case Is =< Lowtemp : Hightemp = Lowtemp + 10 'If 高温の設定値の下限か? Then End Select Eephightemp = Hightemp 'EEPROMに保存する。 ' Hightempdisp: '高温の設定値をLCDに表示。 Locate 1 , 12 Lcd "H"; Tempi1 = Hightemp / 10 '小数点以下を切り捨てる。 Hightempdisp1: Tempstr = Str(tempi1) '数値変数を文字変数に変換する。 If Tempi1 < 0 Then 'If 温度値がマイナスか? Then Lcd Format(tempstr , " 0") ; '温度値を表示する。 Else '温度値がプラスの場合。 Lcd Format(tempstr , " 0") ; '温度値を表示する。 End If Lcd Chr(0) '℃を表示する。 Gosub Cursordisp '設定カーソルを表示する。 Return ' ' *********************************** ' * 低温の設定値の設定とLCDへの表示 * ' *********************************** ' Lowtempset: '低温の設定値の設定。 Select Case Lowtemp Case Is => Hightemp : Lowtemp = Hightemp - 10 'If 低温の設定値の上限か? Then Case Is < -550 : Lowtemp = -550 'If 低温の設定値の下限か? Then End Select Eeplowtemp = Lowtemp 'EEPROMに保存する。 ' Lowtempdisp: '低温の設定値をLCDに表示。 Locate 2 , 12 Lcd "L"; Tempi1 = Lowtemp / 10 '小数点以下を切り捨てる。 Goto Hightempdisp1 ' ' ***************************** (10mS毎に呼び出す) ' * スイッチ入力 サブルーチン * (Swflag = 1 : スイッチ入力有り , 2 : リピート) ' ***************************** (Swdata = スイッチ データ) ' Swin: Select Case Swcount Case 0 : 'スイッチ入力チェック開始。 Gosub Swport 'スイッチ接続ポートからデータを入力。 If Swdata <> 0 Then 'If スイッチ入力が有るか? Then Swtemp = Swdata 'スイッチ データを一時保存。 Swcount = 1 End If ' Case Is < 4 : 'チャタリング除去期間。 Swcount = Swcount + 1 ' Case 4 : 'スイッチ入力を再確認。 Gosub Swport 'スイッチ接続ポートからデータを入力。 If Swdata = Swtemp Then 'If スイッチ入力が確定か? Then Swflag = 1 Swcount = Swcount + 1 Else 'エラーの場合。 Swcount = 0 End If ' Case Else : 'スイッチが離されるのを待つ。 Gosub Swport 'スイッチ接続ポートからデータを入力。 If Swdata <> Swtemp Then 'If スイッチの状態が変わったか? Then Swcount = 0 Else 'スイッチが押し続けられている場合。 If Swcount < 104 Then 'If リピート期間待ち(1秒未満)か? Then Swcount = Swcount + 1 Else '1秒経過した場合。 Swflag = 2 Swcount = 95 'リピートを開始。 End If End If End Select Return ' -------------------------------------------------- ' * スイッチ接続ポートからのデータ入力サブルーチン * (Swdata = スイッチ データ) ' -------------------------------------------------- Swport: Swdata.0 = Not Sw_1 Swdata.1 = Not Sw_2 Swdata.2 = Not Sw_3 Return ' ' End