JJ1WKN Log

自作や移動運用関連のログです。

PLL2001+AVR ATTINY2313 50MHz AM トランシーバの製作 その17

2009-10-30 | PLL
その17です。

ようやく完成したので、きたないソースですが公開します。

コンパイラは以前紹介したmikroBASIC Pro for AVRです。
最初はBASCOMで開発していましたが、途中からmikroBASIC Pro for AVRに変更しました。
同じBASICですが、だいぶ違いがあります。

日本語でコメントを入れてありますが、mikroBASICでは文字化けします。
また、スペースはブログの編集の都合で、全角スペースにしてありますので、そのままではコンパイルできません。

<仕様>
・受信時は表示より455kHz低い周波数を設定
(プログラムは送信時に455kHz高く設定)
・エンコーダー操作は受信時のみ
・送信時は各桁の小数点を表示
・周波数範囲は50.005-50.995MHz
・周波数ステップは5KHz

<ソース>
'50MHz PLL AM TRX 01-00 by JJ1WKN 2009-10-25
'AT Tiny2313 8MHz Internal RC OSC
'avrsp -PC1 -FL11100100 -W PLL.hex

program PLL

'ポート割り当て

'PortB
'Pin Port i/o
'12 PB0 O 7seg B
'13 PB1 O 7seg F
'14 PB2 O 7seg G
'15 PB3 O 7seg C
'16 PB4 O 7seg P
'17 PB5 O 7seg D
'18 PB6 O 7seg E
'19 PB7 O 7seg A

'PortA
'05 PA0 I ENC1
'04 PA1 I ENC2

'PortD
'02 PD0 O 桁1
'03 PD1 O 桁2
'06 PD2 O 桁3
'07 PD3 O PLL/Enable
'08 PD4 O PLL/Data
'09 PD5 O PLL/Clock
'11 PD6 I 送信/受信

'7セグLEDパターン
const LED7 as byte[10] = (
' AEDPCGFB
 %11101011,  '0
 %00001001,  '1
 %11100101,  '2
 %10101101,  '3
 %00001111,  '4
 %10101110,  '5
 %11101110,  '6
 %10001011,  '7
 %11101111,  '8
 %10001111)  '9

'変数
 dim pb,kt,k1,k2,k3,j as byte
 dim freq,pll,cmd,n as word
 dim cnt,tmp,tx as bit
 dim t0,t1,t2 as word

'表示周波数⇒3桁変換
sub procedure f2k()

 t0 = freq / 100
 k3 = t0
 t1 = t0 * 100
 t2 = freq - t1

 t0 = t2 / 10
 k2 = t0
 t1 = t0 * 10
 t2 = t2 - t1

 k1 = t2

end sub

'周波数表示
sub procedure LedDisplay()

 select case kt
  case 1
   pb = LED7[k1]   '桁1
   PortD = %00000110
  case 2
   pb = LED7[k2]   '桁2
   PortD = %00000101
  case 3
   pb = LED7[k3]   '桁3
   PortD = %00000011
  end select

  if tx=1 then        '送信モード?
   PortB = pb or %00010000  '送信表示 X.X.X.
  else
   PortB = pb
  end if

  kt = kt +1
  if kt=4 then
   kt = 1
  end if

  Delay_Ms(5)

end sub

'500ms ディレイ
sub procedure Delay500ms()
 Delay_Ms(500)
end sub

'Clockパルス出力
sub procedure ClockPulse()
 PortD.5 = 1       'ClockパルスHi
 Delay_Us(10)
 PortD.5 = 0       'ClockパルスLo
end sub

'PLL設定
sub procedure PllSet()

 PortD.3 = 0       'Enable Lo

 for j=15 to 0 step -1
  cmd = pll
  cmd = cmd >> j
  cmd = cmd and 1
  PortD.4 = cmd     'Data
  ClockPulse()
 next j

 PortD.4 = cnt      'コントロールビット 1=div 0=freq
 ClockPulse()

 PortD.3 = 1       'Enableパルス Hi
 Delay_Us(10)
 PortD.3 = 0       'Enableパルス Lo

end sub

'LEDテスト
sub procedure LedTest()
 PortB = 255       '8.
 PortD = %00000011    'K3
 Delay500ms()
 PortD = %00000101    'K2
 Delay500ms()
 PortD = %00000110    'K1
 Delay500ms()
end sub

'エンコーダーチェック
sub procedure EncoderCheck()

 if PinA.1=0 then
  Delay_Ms(3)
   if PinA.1=0 then
    if PinA.0=0 then
     freq = freq-5
     if freq=0 then  '50.000
      freq = 5    '50.005
     end if
     n = n-1
    if n=10000 then   '10000*5=50.000
     n = 10001     '10001*5=50.005
    end if
   else
    freq = Freq+5
    if freq=1000 then  '51.000
     freq = 995    '50.995
    end if
    n = n+1
    if n=10200 then   '10200*5=51.000
     n = 10199     '10199*5=50.995
    end if
   end if

   pll = n
   PllSet()      'PLL設定
   f2k()        '表示更新
   for j=1 to 10    '表示だけ、エンコーダー無視
    LedDisplay()
   next j
  end if
 end if
end sub

main:

 '入出力設定
 DdrA = %00000000
 DdrB = %11111111
 DdrD = %00111111

 LedTest()

 kt = 1     '桁
 freq = 620   '表示周波数 620kHz

 'PLL分周比設定
 pll = 2000   '10000kHz/5kHz=2000
 cnt = 1     '分周比設定
 PllSet()

 n = 10033    '10033*5=50.165
 pll = n
 cnt = 0     '周波数設定
 PllSet()

 while TRUE   '無限ループ

  f2k()      '周波数⇒3桁

  tmp = PinD.6  '送信チャック
  LedDisplay()  'チャタリング除去 5ms*2=10ms
  LedDisplay()

  if tmp=PinD.6 then 'チャタリング無し?
   if tmp=0 then   '送信 SW ON?
    if tx=0 then  '受信モード?
     tx = 1    '受信⇒送信
     pll = n+91  '+455kHz
     cnt = 0
     PllSet()   '周波数設定
    end if
    'else       送信⇒送信
   else
    if tx=1 then  '送信モード?
     tx = 0    '送信⇒受信
     pll = n
     cnt = 0
     PllSet()   '周波数設定
    end if
    'else       受信⇒受信
    EncoderCheck() 'エンコードチェック
   end if
  end if

 wend

end.