2015-03-27

EEPROM 24FC256にpickit2で書き込み


もっとリアルな電子オルゴールを作りたいと思い外部のメモリからデータを読み取りPWMでWAVデータを再生する。
してみたい、という安易な希望から始めました。
なかなか簡単には行かなかった。

まず、EEPROMにデータを書き込まないと始まらないのですが苦労しました。
I2Cでpickit2から24FC256にデータを送って書き込むようなのですが、I2Cのエラーになって読み書きできません。
原因は単純で配線が長すぎたようです。
ブレッドボードを使って環境が良くないのに配線が10cm以上有った。
写真のように出来るだけ配線が短くなるようにやり直しをしてやっと書き込めました。

2015-03-22

PICで電子オルゴール No2

前回の続きで基板を見直しをしました。
部品の選定をしてレイアウトを整理しました。


基板の配線は以下の通り。
上から(部品側から)みた図になっています。

回路図は次の通りです。



2015-03-18

PICで電子オルゴール

久々に電子工作をしました。
母校の小学校がとうとう閉校になるので、何か記念になるものを残しておこうと思い校歌を電子オルゴールにしてみました。
PICマイコン12F629と圧電スピーカ、電池といった簡単な構成でできます。
写真にあるものは、CDSをつけて明るくなると鳴り出すように作ったので部品がCDSと抵抗2本が増えています。


開発はmikroBASICを使いました。
ライターはPICKit2。

MikroBasicのライブラリーにSOUNDがあり、音程と長さを指定して音を鳴らすことができます。
PIC12F629にはEEPROMがあります。このEEPROMに音程長さを記憶させておき順に読み込み音楽を演奏させています。
そのままでは音程と長さで4バイト必要になりますが、プログラム内部でドレミと音符の長さのテーブルを持ち、EEPROMにはその番号のみで上位4ビットで長さ、下位4ビットで音程の番号を表現させました。

EEPROMの内容は校歌なので載せてもと思い、ソースのみを公開します。
休符の扱いがわからずDelayで表現しています。
Delayはライブラリーで実装されておらず、パラメータに変数が使えないので4分休符のみのコーディングです。
調子に乗ってコーディングしていたら、プログラムエリアが足りなくなりました。
SOUNDとEEPROMのライブラリーで結構メモリーを食ってしまっているようです。



program MUSIC
'                             0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
'                             R   C   C#  D   D#  E   F   F#  G   G#  A   A#  B   C   C#  D
  const doremi as word[16]= (  0,262,277,294,311,330,349,370,392,415,440,466,494,523,554,587)
'                 tempo=120
'                              0    1    2    3    4    5    6    7    8  9
'                              1    2.   2    4.   4    8.   8   16.   16
  const onpu   as word[9]= (2000,1500,1000,0750,0500,0375,0250,0188,0125)

' Declarations section
sub procedure init_rtn
  GPIO = 0
  CMCON = 000111
  TRISIO = 000000
  'ANSEL = 000000

  Sound_Init(GPIO, 2)

end sub

main:

  dim eromdt as byte
  dim takapt as byte
  dim nagapt as byte
  dim takasa as word
  dim nagasa as word
  dim yasumi as word
  dim i as byte

  init_rtn

  while true
    i=0                         'EPROM READ POINTER
    while < 127                 'EPROM MAC ADDRESS 128
      eromdt = EEPROM_Read(i)   'DATA READ FROM EPROM
      if eromdt = $FF then      'DATA VALUE FF is END of DATA
        i =128                  'Exit Loop When set 128
      else
        takapt = eromdt and $0f 'DATA low4bit is SOUND Pitch
        nagapt = eromdt >> 4    'DATA High4bit is SOUND Length
        if takapt = 0 then
          'select case nagapt
          '  case 4
              Delay_ms(500)
          '  case 2
          '    delay_ms(1000)
          '  case 0
          '    delay_ms(2000)
          'end select
        else
          takasa = doremi[takapt]'Pitch Table
          nagasa = onpu[nagapt]
          Sound_Play(takasa,nagasa)
          Delay_ms(16)
        end if
      end if
      i=i+1
    wend
    
    'ENTRY SLEEP '
     GPIO =0
     OPTION_REG = 000000
     INTCON = %10001000'
     NOP
     NOP
     asm
       sleep
     end asm
     NOP
     NOP
    'RESUME SLEEP
     INTCON = 000000

  wend

end.