ZEO-S 와 ZEO-IO2 로 8채널 ADC를 모두 사용하는 예제입니다.

 

CDS 8개를 각각 ADC1 ~ ADC8에 연결하고 CDS 밝기에 따라

LED를 ON/OFF 합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

윈도우 프로그램 화면 – 잠깐 동안 CDS를 가렸다가 뗄 경우

 

 

 

 

 

윈도우 프로그램 – CDS를 순차적으로 가린 경우

 

 

 

 

 

   

코드 C#

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using ZeoDotNetLib;

using System.Diagnostics;

using System.Threading;

 

namespace ADCTest8CH

{

public partial class Form1 : Form

{

// LED 를 그룹으로 지정

PIN_NAME LED1 = PIN_NAME.PA3 | PIN_NAME.PA4;

PIN_NAME LED2 = PIN_NAME.PA5 | PIN_NAME.PA6;

PIN_NAME LED3 = PIN_NAME.PA7 | PIN_NAME.PA8;

PIN_NAME LED4 = PIN_NAME.PA9 | PIN_NAME.PB12;

PIN_NAME LED5 = PIN_NAME.PB0 | PIN_NAME.PB1;

PIN_NAME LED6 = PIN_NAME.PB2 | PIN_NAME.PB3;

PIN_NAME LED7 = PIN_NAME.PB4 | PIN_NAME.PB5;

PIN_NAME LED8 = PIN_NAME.PB6 | PIN_NAME.PB7;

 

// ZEO용 인스턴스

const int ADC_MEM_SIZE = 0x3C00;

ZeoDotNetLib.ZeoLib ZEO1 = new ZeoDotNetLib.ZeoLib();

 

// 그래픽용

GraphControl GraphCtrl;

 

public Form1()

{

InitializeComponent();

 

this.cboADCSpeed.SelectedIndex = 0;

this.cboReadSpeed.SelectedIndex = 0;

}

 

private void Form1_Load(object sender, EventArgs e)

{

GraphCtrl = new GraphControl(new Font("Arial", 12), new Font("Arial", 10), new Font("Arial", 8));

GraphCtrl.TabIndex = 0;

GraphCtrl.Dock = DockStyle.Fill;

GraphCtrl.Name = "ADC1 ";

 

//Add Graph Control to the form

GraphPanel.Controls.Add(GraphCtrl);

 

//Add series

GraphCtrl.AddPointsSerie("ADC1", Axes.VerticalPrimary, " 1", Color.Red);

GraphCtrl.AddPointsSerie("ADC2", Axes.VerticalPrimary, " 2", Color.Green);

GraphCtrl.AddPointsSerie("ADC3", Axes.VerticalPrimary, " 3", Color.Blue);

GraphCtrl.AddPointsSerie("ADC4", Axes.VerticalPrimary, " 4", Color.DarkBlue);

GraphCtrl.AddPointsSerie("ADC5", Axes.VerticalPrimary, " 5", Color.YellowGreen);

GraphCtrl.AddPointsSerie("ADC6", Axes.VerticalPrimary, " 6", Color.SkyBlue);

GraphCtrl.AddPointsSerie("ADC7", Axes.VerticalPrimary, " 7", Color.Gray);

GraphCtrl.AddPointsSerie("ADC8", Axes.VerticalPrimary, " 8", Color.DarkGreen);

 

GraphCtrl.Invalidate();

 

 

if (FStatus.OK == this.ZEO1.Open())

{

this.ZEO1.InitZeo(ADC_MEM_SIZE);

this.lblBoardInfo.Text = "ZEO-" + this.ZEO1.GetZeroType().ToString() + ", " + this.ZEO1.GetBoardVersion().ToString();

 

this.btnStart.Enabled = this.btnStop.Enabled = true;

this.ZEO1.ADCReceived += new eventADCReceived(ZEO_ADCReceived);

this.ZEO1.Pin_DirOutput(LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 | LED8);

this.ZEO1.Pin_Reset(LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 | LED8);

}

else

{

this.lblBoardInfo.Text = "open fail";

this.lblBoardInfo.ForeColor = Color.Red;

}

Thread.Sleep(1000);

}

 

private void Form1_FormClosing(object sender, FormClosingEventArgs e)

{

Thread.Sleep(100);

ZEO1.Close();

}

 

private void btnStart_Click(object sender, EventArgs e)

{

// ADC 8채널 지정

ADCStarter[] _start = new ADCStarter[]{

new ADCStarter(ADCChannel._1,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._2,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._3,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._4,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._5,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._6,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._7,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._8,(ADCSpeed1) cboADCSpeed.SelectedIndex),

};

 

this.ZEO1.InitADC1(_start);

this.ZEO1.WaitStandby();

 

}

 

int m_iAdcDiv = 0;

int[] g_iADCData;

 

// ADC 데이터를 받으면

void ZEO_ADCReceived(byte[] bData)

{

 

if (bData == null) return;

if (bData.Length <= 7) return;

 

int iADCChannelCount = this.ZEO1.GetADCChannelCount();

if (iADCChannelCount <= 0) return;

 

UInt16[] uiData = new UInt16[bData.Length / 2];

Buffer.BlockCopy(bData, 0, uiData, 0, bData.Length);

 

g_iADCData = Array.ConvertAll(uiData, new Converter<UInt16, int>(UInt16ToInt32));

 

for (int i = 0; i < g_iADCData.Length; i += (iADCChannelCount * m_iAdcDiv))

{

GraphCtrl.GetPointsSerie("ADC1").AddPoint(g_iADCData[i]);

GraphCtrl.GetPointsSerie("ADC2").AddPoint(g_iADCData[i + 1]);

GraphCtrl.GetPointsSerie("ADC3").AddPoint(g_iADCData[i + 2]);

GraphCtrl.GetPointsSerie("ADC4").AddPoint(g_iADCData[i + 3]);

GraphCtrl.GetPointsSerie("ADC5").AddPoint(g_iADCData[i + 4]);

GraphCtrl.GetPointsSerie("ADC6").AddPoint(g_iADCData[i + 5]);

GraphCtrl.GetPointsSerie("ADC7").AddPoint(g_iADCData[i + 6]);

GraphCtrl.GetPointsSerie("ADC8").AddPoint(g_iADCData[i + 7]);

}

 

// 그래프 refresh

GraphCtrl.Invalidate();

}

 

public static int UInt16ToInt32(UInt16 pf)

{

return Convert.ToInt32(pf);

}

 

private void DisplayResult(string _str)

{

Console.WriteLine(_str);

}

 

private void button2_Click(object sender, EventArgs e)

{

this.ZEO1.DisableADC();

}

 

private void tmrRx_Tick(object sender, EventArgs e)

{

if (g_iADCData == null) return;

 

if (g_iADCData.Length>8)

{

this.ZEO1.Pin_Write(LED1, Convert.ToBoolean(g_iADCData[0] < 750));

this.ZEO1.Pin_Write(LED2, Convert.ToBoolean(g_iADCData[1] < 750));

this.ZEO1.Pin_Write(LED3, Convert.ToBoolean(g_iADCData[2] < 750));

this.ZEO1.Pin_Write(LED4, Convert.ToBoolean(g_iADCData[3] < 750));

this.ZEO1.Pin_Write(LED5, Convert.ToBoolean(g_iADCData[4] < 750));

this.ZEO1.Pin_Write(LED6, Convert.ToBoolean(g_iADCData[5] < 750));

this.ZEO1.Pin_Write(LED7, Convert.ToBoolean(g_iADCData[6] < 750));

this.ZEO1.Pin_Write(LED8, Convert.ToBoolean(g_iADCData[7] < 750));

}

}

 

private void cboReadSpeed_SelectedIndexChanged(object sender, EventArgs e)

{

// 데이터 읽기 간격을 변경하면

m_iAdcDiv = cboReadSpeed.SelectedIndex + 1;

}

 

}

}

 

 

 

 

   

   

전체 코드 Visual C# 2008 용

다운로드

   

출처: http://whiteat.com/bPDS_ZEO/186977 

   

 

 

Posted by WhiteAT

댓글을 달아 주세요

 

ZEO-S 모듈의 I/O, ADC, PWM을 실험할 수 있는 보드 입니다.

 

ZEO-S 를 장착하지 않은 상태

 

 

 

 

ZEO-S 를 장착한 상태

 

 

 

ZEO-S 의 연결 핀

 

ZEO-IO2 보드

ZEO-S

CDS

CDS1

PB13*

CDS2

PB14*

CDS3

PB15*

CDS4

PA16*

CDS5

PA15

CDS6

PA14

CDS7

PA13*

CDS8

PA12*

LED

D1

PA3

D2

PA4

D3    

PA5

D4

PA6

D5

PA7

D6

PA8

D7

PA9

D8

PB12

D14

PB0

D15

PB1

D16

PB2

D17

PB3

D18

PB4

D19

PB5

D20

PB6

D21

PB7

SERVO

SERVO1

PA0

SERVO2

PA1

SERVO3

PA2

SERVO4

PA10

SERVO5

PA11

SERVO6

PA12*

SERVO7

PA13*

SERVO8

PA16*

SERVO9

PB13*

SERVO10

PB14*

SERVO11

PB15*

 

* 표시는 ADC 와 PWM 기능이 있는 핀이며 다음과 같이 딥스위치로 선택하여 사용합니다.

 

DIP 스위치

ON

OFF

1

SERVO4 사용

2

SERVO5 사용

3

CDS8 사용

SERVO6 사용

4

CDS7 사용

SERVO7 사용

5

CDS4 사용

SERVO8 사용

6

CDS1 사용

SERVO9 사용

7

CDS2 사용

SERVO10 사용

8

CDS3 사용

SERVO11사용

 

 

원문: http://whiteat.com/Product_ZEO/186932

 

Posted by WhiteAT

댓글을 달아 주세요

 

ZEO-S 의 Pulse Counter 로 스위치 입력을 카운터 해보았습니다. Pulse Counter 로 몇 KHz까지 정확히 읽을 수 있는지 실험해 보겠습니다.

 

ZEO-S 의 PWM (PA11) 과 Pulse Counter (PA12)를 점퍼로 연결합니다. 그러면 PA11의 PWM 출력이 PA12 의 Pulse Counter 로 입력됩니다.

 

 

 

100Khz 의 PWM으로 실험을 진행합니다.

 

 

 

 

 

10초 동안 아래처럼 약 1,000,000 개의 펄스를 입력 받게 됩니다.

 

 

 

 

 

24초 동안 아래처럼 약 24,000,000 개의 펄스를 입력 받게 됩니다.

 

 

 

 

 

 

200Khz 의 PWM에서는 10초 동안 아래처럼 약 2,000,000 개의 펄스를 입력 받게 됩니다.

 

 

200Khz 의 PWM에서도 정확한 카운터를 얻었습니다.

 

 

 

코드 C#

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ZeoDotNetLib;


namespace PulseInputFromPWM
{
  public partial class Form1 : Form
  {
    Double dTotalCnt = 0;
    UInt16 lastCnt = 0;
    ZeoLib ZEO = new ZeoLib();
    int iTmrCnt = 0;

    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      this.ZEO.Open();
      this.ZEO.InitZeo(0);
      this.label1.Text = this.ZEO.ToString();

      this.ZEO.InitCount(7);
     
      // 2Khz 파형 발생
      //this.ZEO.InitPWMC(PWM_Frequency._2Khz, 0, 0, 0, 0);

      // 100Khz 파형 발생
      this.ZEO.InitPWMC(360-1, 0, 0, 0, 0);
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
      this.ZEO.Close();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
      this.GetCounts();
      this.lblTmr.Text = (iTmrCnt++/5).ToString()+"초 경과";
    }
 
    public void GetCounts()
    {
      if (!this.ZEO.IsOpened) return;

      UInt16   _cnt = 0;
      this.ZEO.GetCount(7, out _cnt);


      if (_cnt - lastCnt >=0)
        dTotalCnt += (_cnt-lastCnt);
      else
        dTotalCnt += (_cnt - lastCnt)+65536;

      lastCnt = _cnt  ;

      this.lblTotalCount.Text = dTotalCnt.ToString();
 
    }

    private void btnStart_Click(object sender, EventArgs e)
    {
      this.ZEO.UpdatePWMC(2, 200);
      iTmrCnt = 0;
      dTotalCnt = 0;
    }

    private void btnStop_Click(object sender, EventArgs e)
    {
      this.ZEO.UpdatePWMC(2, 0);
    }
 

  }
}

 

 

 

 

DC 모터 구동에 필요한 PWM, 스텝모터 구동에 사용되는 PULSE 도 ZEO-S의 Pulse Counter로 감시하게 되면 동작 유무를 쉽게 판단할 수 있고, 데이터 라인에 연결하여 데이터 전송되는지 체크하는데 사용할 수도 있습니다.

 

 

전체 코드 Visual C# 2008 용

 

 다운로드



  

출처: http://whiteat.com/185984

 

 

 

 

 

Posted by WhiteAT

댓글을 달아 주세요

 

ZEO-S 의 Pulse Counter 기능으로 펄스 카운터를 쉽게 구할 수 있습니다.

이 기능은 엔코더 모터 회전 수를 계산하는데 많이 사용되는데, 여기서는 버튼의 눌림을 예로 들었으며

모터 회전수 계산은 다음에 올리도록 하겠습니다.

 

 

 

 

 

준비

 

ZEO-IO BOARD에 연결하여 0.5초 간격으로 스위치 눌림 횟수를 확인해 보는 예제입니다.

Pulse Counter0, 1, 2, 4, 5, 6 이 사용되며 버튼의 눌림 횟수의 누적 값과 현재 값을 화면에 표시해 보겠습니다.

 

 

 

 

 

ZEO-S 와 스위치의 연결 상태는 아래와 같습니다.

 

스위치

ZEO-S

 

SW2

PA13

 

SW3

PA14

 

SW4

PA15

 

SW6

PB13

 

SW7

PB13

 

SW8

PB14

 

 

 

 

SW, SW3, SW4, SW6, SW7, SW8이 각각 눌린 누적 횟수는 15, 17, 19, 8, 28, 16 이며

0.5초 동안에 눌린 횟수(즉, 변화값 )는 2,5,2,4,5,1 입니다.

 

 

 

 

 

 

 

SW, SW3, SW4, SW6, SW7, SW8이 각각 눌린 누적 횟수는 55, 53, 55, 30, 48, 63 이며

0.5초 동안에 눌린 횟수(즉, 변화값)는 3,5,3,7,6,12 입니다.

 

 

 

 

코드 C#

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
 using System.Text;
using System.Windows.Forms;
using ZeoDotNetLib;

namespace OutputTest1
{
  public partial class Form1 : Form
  {
    ZeoLib ZEO = new ZeoLib();
    UInt16[] cntLast = new UInt16[8];// 카운터 변화량 계산을 위해 최근 값을 저장


    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      this.ZEO.Open();
      this.ZEO.InitZeo(0);
      this.label1.Text = this.ZEO.ToString();

      this.ZEO.InitCount(0);
      this.ZEO.InitCount(1);
      this.ZEO.InitCount(2);
      this.ZEO.InitCount(3);
      this.ZEO.InitCount(4);
      this.ZEO.InitCount(5);
      this.ZEO.InitCount(6);
      this.ZEO.InitCount(7);

    }

 
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
      this.ZEO.Close();
     }

    public void GetCounts()
    {
      if (!this.ZEO.IsOpened) return;

      StringBuilder sb = new StringBuilder();
      UInt16[] _cnt = null;


      // 한번에 하나의 카운터만 읽기 (상황에 맞게 선택 사용)
      //UInt16   _cnt2 = 0;
      //this.ZEO.GetCount(0, out _cnt2);

      // 한번에 모든 카운터 읽기  (상황에 맞게 선택 사용)
      this.ZEO.GetCounts(out _cnt);

      this.lblCount0.Text = _cnt[0].ToString() + ".." + (_cnt[0] - cntLast[0]).ToString() + "";
      this.lblCount1.Text = _cnt[1].ToString() + ".." + (_cnt[1] - cntLast[1]).ToString() + "";
      this.lblCount2.Text = _cnt[2].ToString() + ".." + (_cnt[2] - cntLast[2]).ToString() + ""; ;
      this.lblCount4.Text = _cnt[4].ToString() + ".." + (_cnt[4] - cntLast[4]).ToString() + ""; ;
      this.lblCount5.Text = _cnt[5].ToString() + ".." + (_cnt[5] - cntLast[5]).ToString() + ""; ;
      this.lblCount6.Text = _cnt[6].ToString() + ".." + (_cnt[6] - cntLast[6]).ToString() + ""; ;

      Buffer.BlockCopy(_cnt, 0, this.cntLast, 0, cntLast.Length * 2);
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
      this.GetCounts();
    }
  }
}

 

 

 

 

 

 

 

 

 

 

 

ReadPort() 와 다른 점

 

이 예제를 보면 ReadPort() 를 사용하여 HIGH, LOW 를 비교하여 카운터해도 됩니다. 하지만 ReadPort()를 사용할 경우 정확한 값을 얻기 힘듭니다. 그 이유는 ReadPort()의 경우 호출되는 순간의 상태를 읽는 것이라 빠르게 변하는 모든 값을 읽기가 거의 불가능하기 때문입니다. 예를 들어 1초에 1000번 정도 상태를 읽으려면 1초에 1000번을 읽어야 하는데 ZEO-S에서는 거의 불가능한 일입니다. 이 때는 Pulse Counter 를 사용해야 합니다.

 

Pulse Counter는 1초에 10000번 이상 변하는 상태도 다 읽어 낼 수 있기 때문입니다.

 

  

전체 코드 Visual C# 2008 용

 

 다운로드



  

출처: http://whiteat.com/185922

 

 

Posted by WhiteAT

댓글을 달아 주세요

 

스위치(버튼)의 입력을 받아 LED 를 ON/OFF 하는 예제입니다.

스위치의 눌림 상태에 따라 LED ON 위치가 변경되는 것을 알 수 있습니다.


스위치(버튼)의 눌림 상태를 읽는 방법은 아래 코드와 같이 3가지 방법이 있습니다.



 

 

 

 

 

 

 

 

 

 

 

코드 C#

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using ZeoDotNetLib;

 

namespace WATInputOutput

{

public partial class Form1 : Form

{

#region ZEO-IO Pin Define

const PIN_NAME D1 = PIN_NAME.PA0;

const PIN_NAME D2 = PIN_NAME.PA1;

const PIN_NAME D3 = PIN_NAME.PA2;

const PIN_NAME D4 = PIN_NAME.PA3;

const PIN_NAME D5 = PIN_NAME.PA4;

const PIN_NAME D6 = PIN_NAME.PA5;

const PIN_NAME D7 = PIN_NAME.PA6;

const PIN_NAME D8 = PIN_NAME.PA7;

const PIN_NAME D9 = PIN_NAME.PA8;

const PIN_NAME D10 = PIN_NAME.PA9;

const PIN_NAME D11 = PIN_NAME.PA10;

const PIN_NAME D12 = PIN_NAME.PA11;

const PIN_NAME D13 = PIN_NAME.PA16;

const PIN_NAME D14 = PIN_NAME.PB0;

const PIN_NAME D15 = PIN_NAME.PB1;

const PIN_NAME D16 = PIN_NAME.PB2;

const PIN_NAME D17 = PIN_NAME.PB3;

const PIN_NAME D18 = PIN_NAME.PB4;

const PIN_NAME D19 = PIN_NAME.PB5;

const PIN_NAME D20 = PIN_NAME.PB6;

const PIN_NAME D21 = PIN_NAME.PB7;

const PIN_NAME D22 = PIN_NAME.PB8;

const PIN_NAME D23 = PIN_NAME.PB9;

const PIN_NAME D24 = PIN_NAME.PB10;

const PIN_NAME D25 = PIN_NAME.PB11;

 

 

const PIN_NAME SW1 = PIN_NAME.PA12;

const PIN_NAME SW2 = PIN_NAME.PA13;

const PIN_NAME SW3 = PIN_NAME.PA14;

const PIN_NAME SW4 = PIN_NAME.PA15;

 

const PIN_NAME SW5 = PIN_NAME.PB12;

const PIN_NAME SW6 = PIN_NAME.PB13;

const PIN_NAME SW7 = PIN_NAME.PB14;

const PIN_NAME SW8 = PIN_NAME.PB15;

 

#endregion

 

 

 

PIN_NAME pin1 = D1 | D2| D3;

PIN_NAME pin2 = D4 | D5 | D6;

PIN_NAME pin3 = D7 | D8 | D9;

PIN_NAME pin4 = D10 | D11 | D12 | D13;

PIN_NAME pin5 = D14 | D15 | D17;

PIN_NAME pin6 = D16 | D18 | D19;

PIN_NAME pin7 = D20 | D21 | D22;

PIN_NAME pin8 = D23 | D24 | D25;

 

// ZEO-S 인스턴스

ZeoLib ZEO = new ZeoLib();

 

 

public Form1()

{

InitializeComponent();

}

 

private void Form1_Load(object sender, EventArgs e)

{

// ZEO 초기화

this.ZEO.Open();

if (this.ZEO.IsOpened)

{

this.ZEO.InitZeo(0);

this.ZEO.Pin_Set(this.ZEO.PIN_ALL);

this.ZEO.PORT_DirOutputALL();

// 스위치를 입력으로 설정

this.ZEO.PORT_DirInput(SW1 | SW2 | SW3 | SW4 | SW5 | SW6 | SW7 | SW8 );

}

 

}

 

private void Form1_FormClosing(object sender, FormClosingEventArgs e)

{

// ZEO 닫기

if (this.ZEO.IsOpened)

this.ZEO.Close();

}

 

private void timer1_Tick(object sender, EventArgs e)

{

if (!this.ZEO.IsOpened)

{

Console.WriteLine("ZEO-S 가 연결되어 있지 않습니다.");

return;

}

 

// 모든 포트의 값을 읽어

UInt32[] uiData = this.ZEO.ReadPortAll();

 

//////////////////////////////////////////////////

// 방법1

 

// SW1 눌리면

if (this.ZEO.PA12this.ZEO.Pin_Set(pin1);

else this.ZEO.Pin_Reset(pin1);

 

// SW2 눌리면

if (this.ZEO.PA13this.ZEO.Pin_Set(pin2);

else this.ZEO.Pin_Reset(pin2);

 

// SW3 눌리면

if (this.ZEO.PA14this.ZEO.Pin_Set(pin3);

else this.ZEO.Pin_Reset(pin3);

 

// SW4 눌리면

if (this.ZEO.PA15this.ZEO.Pin_Set(pin4);

else this.ZEO.Pin_Reset(pin4);

 

 

/////////////////////////////////////////////

// 방법2

 

 

// SW5 눌리면

this.ZEO.Pin_Write(pin5this.ZEO.PB12);

 

// SW6 눌리면

this.ZEO.Pin_Write(pin6this.ZEO.PB13);

 

 

//////////////////////////////////////

// 방법3

 

// SW7 눌리면

if ((uiData[1] & 0x4000) == 0x4000) this.ZEO.Pin_Set(pin7);

else this.ZEO.Pin_Reset(pin7);

 

// SW8 눌리면

if ((uiData[1] & 0x8000) == 0x8000) this.ZEO.Pin_Set(pin8);

else this.ZEO.Pin_Reset(pin8);

 

}

}

}

 

 

 

 

전체 코드 Visual C# 2008 용

다운로드

 

출처: http://whiteat.com/163865 

 

 

Posted by WhiteAT

댓글을 달아 주세요

 

Timer 를 이용하여 LED 를 연속으로 이동하는 예제입니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

동영상

 


 

 

 

 

 

코드 C#

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using ZeoDotNetLib;

 

 

namespace ZEO_Flow2

{

public partial class Form1 : Form

{

// LED 상태

int iStatus = 0;

 

// ZEO-S 인스턴스

ZeoLib ZEO = new ZeoLib();

 

 

public Form1()

{

InitializeComponent();

}

 

private void Form1_Load(object sender, EventArgs e)

{

// ZEO 초기화

this.ZEO.Open();

if (this.ZEO.IsOpened)

{

this.ZEO.InitZeo(0);

this.ZEO.PORT_DirOutputALL();

this.ZEO.Pin_Set(this.ZEO.PIN_ALL);

}

}

 

private void Form1_FormClosing(object sender, FormClosingEventArgs e)

{

// ZEO 닫기

if (this.ZEO.IsOpened)

this.ZEO.Close();

}

 

private void timer1_Tick(object sender, EventArgs e)

{

if (!this.ZEO.IsOpened)

{

Console.WriteLine("ZEO-S 가 연결되어 있지 않습니다.");

return;

}

 

switch (iStatus)

{

case 0: this.ZEO.Pin_Reset(PIN_NAME.PA0); break;

case 1: this.ZEO.Pin_Reset(PIN_NAME.PA2); break;

case 2: this.ZEO.Pin_Reset(PIN_NAME.PA4); break;

case 3: this.ZEO.Pin_Reset(PIN_NAME.PA6); break;

 

case 4: this.ZEO.Pin_Set(PIN_NAME.PA0); break;

case 5: this.ZEO.Pin_Reset(PIN_NAME.PA8); break;

case 6: this.ZEO.Pin_Set(PIN_NAME.PA2); break;

case 7: this.ZEO.Pin_Reset(PIN_NAME.PA10); break;

case 8: this.ZEO.Pin_Set(PIN_NAME.PA4); break;

case 9: this.ZEO.Pin_Reset(PIN_NAME.PA16); break;

case 10: this.ZEO.Pin_Set(PIN_NAME.PA6); break;

case 11: this.ZEO.Pin_Reset(PIN_NAME.PA1); break;

 

case 12: this.ZEO.Pin_Set(PIN_NAME.PA8); break;

case 13: this.ZEO.Pin_Reset(PIN_NAME.PA3); break;

case 14: this.ZEO.Pin_Set(PIN_NAME.PA10); break;

case 15: this.ZEO.Pin_Reset(PIN_NAME.PA5); break;

case 16: this.ZEO.Pin_Set(PIN_NAME.PA16); break;

case 17: this.ZEO.Pin_Reset(PIN_NAME.PA7); break;

 

 

case 18: this.ZEO.Pin_Set(PIN_NAME.PA1); break;

case 19: this.ZEO.Pin_Reset(PIN_NAME.PA9); break;

case 20: this.ZEO.Pin_Set(PIN_NAME.PA3); break;

case 21: this.ZEO.Pin_Reset(PIN_NAME.PA11); break;

case 22: this.ZEO.Pin_Set(PIN_NAME.PA5); break;

case 23: this.ZEO.Pin_Reset(PIN_NAME.PB0); break;

 

 

case 24: this.ZEO.Pin_Set(PIN_NAME.PA7); break;

case 25: this.ZEO.Pin_Reset(PIN_NAME.PB2); break;

case 26: this.ZEO.Pin_Set(PIN_NAME.PA9); break;

case 27: this.ZEO.Pin_Reset(PIN_NAME.PB4); break;

case 28: this.ZEO.Pin_Set(PIN_NAME.PA11); break;

case 29: this.ZEO.Pin_Reset(PIN_NAME.PB6); break;

 

case 30: this.ZEO.Pin_Set(PIN_NAME.PB0); break;

case 31: this.ZEO.Pin_Reset(PIN_NAME.PB9); break;

 

case 32: this.ZEO.Pin_Set(PIN_NAME.PB2); break;

case 33: this.ZEO.Pin_Reset(PIN_NAME.PB11); break;

case 34: this.ZEO.Pin_Set(PIN_NAME.PB4); break;

case 35: this.ZEO.Pin_Reset(PIN_NAME.PB1); break;

case 36: this.ZEO.Pin_Set(PIN_NAME.PB6); break;

case 37: this.ZEO.Pin_Reset(PIN_NAME.PB3); break;

case 38: this.ZEO.Pin_Set(PIN_NAME.PB9); break;

case 39: this.ZEO.Pin_Reset(PIN_NAME.PB5); break;

case 40: this.ZEO.Pin_Set(PIN_NAME.PB11); break;

case 41: this.ZEO.Pin_Reset(PIN_NAME.PB7); break;

case 42: this.ZEO.Pin_Set(PIN_NAME.PB1); break;

case 43: this.ZEO.Pin_Reset(PIN_NAME.PB8); break;

case 44: this.ZEO.Pin_Set(PIN_NAME.PB3); break;

case 45: this.ZEO.Pin_Reset(PIN_NAME.PB10); break;

 

case 46: this.ZEO.Pin_Set(PIN_NAME.PB5); break;

case 47: this.ZEO.Pin_Reset(PIN_NAME.PA0); break;

case 48: this.ZEO.Pin_Set(PIN_NAME.PB7); break;

case 49: this.ZEO.Pin_Reset(PIN_NAME.PA2); break;

case 50: this.ZEO.Pin_Set(PIN_NAME.PB8); break;

case 51: this.ZEO.Pin_Reset(PIN_NAME.PA4); break;

case 52: this.ZEO.Pin_Set(PIN_NAME.PB10); break;

default:

iStatus = 2;

 

break;

}

 

iStatus++;

 

}

}

}

 

 

 

전체 코드 Visual C# 2008 용

 

 다운로드



  

출처:  http://docs.whiteat.com/?p=396


'ZEO 시리즈' 카테고리의 다른 글

ZEO-S Pulse Counter, C#  (0) 2013.08.29
ZEO-S, 스위치로 LED ON/OFF, C#  (0) 2013.06.13
ZEO-S, LED 연속으로 이동, C#  (0) 2013.06.08
ZEO-S, LED 이동 속도 조절, C#  (0) 2013.06.06
ZEO-S ADC 샘플링 테스트 C#  (0) 2013.04.16
ZEO-IO BOARD – ZEO IO 실험 보드  (0) 2013.04.10
Posted by WhiteAT

댓글을 달아 주세요

Timer 의 Interval 값을 조정하여 LED 이동속도를 조절하는 예제입니다.

 

 

 

 

 

 

 

 

동영상

 

 


 

 

 

 

코드 C#

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using ZeoDotNetLib;

 

namespace ZEO_Flow

{

public partial class Form1 : Form

{

const int STEP = 25;

int iStatus = 0;

int NowStep = -STEP;

 

PIN_NAME pin1 = PIN_NAME.PA0 | PIN_NAME.PA2| PIN_NAME.PA4 | PIN_NAME.PA6

| PIN_NAME.PA8 | PIN_NAME.PA10 | PIN_NAME.PA16;

PIN_NAME pin2 = PIN_NAME.PA1 | PIN_NAME.PA3 | PIN_NAME.PA5 | PIN_NAME.PA7

| PIN_NAME.PA9 | PIN_NAME.PA11;

PIN_NAME pin3 = PIN_NAME.PB0 | PIN_NAME.PB2 | PIN_NAME.PB4 | PIN_NAME.PB6

| PIN_NAME.PB9 | PIN_NAME.PB11;

PIN_NAME pin4 = PIN_NAME.PB1 | PIN_NAME.PB3 | PIN_NAME.PB5 | PIN_NAME.PB7

| PIN_NAME.PB8 | PIN_NAME.PB10;

 

ZeoLib ZEO = new ZeoLib();

public Form1()

{

InitializeComponent();

}

 

private void Form1_Load(object sender, EventArgs e)

{

this.ZEO.Open();

this.ZEO.InitZeo(0);

this.ZEO.PORT_DirOutputALL();

this.ZEO.Pin_Set(this.ZEO.PIN_ALL);

}

 

private void Form1_FormClosing(object sender, FormClosingEventArgs e)

{

this.ZEO.Close();

}

 

private void timer1_Tick(object sender, EventArgs e)

{

if (timer1.Interval < 200)

{

timer1.Interval += NowStep/10;

}

else

{

timer1.Interval += NowStep;

}

 

if (timer1.Interval < 100)

{

NowStep = STEP;

}

else if (timer1.Interval > 1000)

{

NowStep = -STEP;

}

 

 

Console.WriteLine("int:"+timer1.Interval.ToString() +", nowstep:"+NowStep.ToString() );

 

switch (iStatus)

{

case 0:

this.ZEO.Pin_Reset(pin1);

this.ZEO.Pin_Set(pin4);

break;

case 1:

this.ZEO.Pin_Reset(pin2);

this.ZEO.Pin_Set(pin1);

 

break;

case 2:

this.ZEO.Pin_Reset(pin3);

this.ZEO.Pin_Set(pin2);

break;

case 3:

this.ZEO.Pin_Reset(pin4);

this.ZEO.Pin_Set(pin3);

break;

default:

break;

}

 

iStatus = (++iStatus)%4;

}

}

}

 

 

 

전체 코드 Visual C# 2008 용


 다운로드




출처: http://whiteat.com/154626



 

Posted by WhiteAT

댓글을 달아 주세요

 

ZEO-S 모듈의 I/O를 실험할 수 있는 보드 입니다.

INPUT, OUTPUT, PWM 등을 실험할 수 있습니다.

 

 

ZEO-S 를 장착하지 않은 상태

 

 

 

 

ZEO-S 를 장착한 상태

 

 

 

ZEO-S 의 연결 핀

 

IO 보드

ZEO-S

스위치

SW1

PA12

SW2

PA13

SW3

PA14

SW4

PA15

SW5

PB12

SW6

PB13

SW7

PB14

SW8

PB15

LED

D1

PA0

D2

PA1

D3    

PA2

D4

PA3

D5

PA4

D6

PA5

D7

PA6

D8

PA7

D9

PA8

D10

PA9

D11

PA10

D12

PA11

D13

PA16

D14

PB0

D15

PB1

D16

PB2

D17

PB3

D18

PB4

D19

PB5

D20

PB6

D21

PB7

D22

PB8

D23

PB9

D24

D25

PB10

PB11

 

 

 

 

 

원문: http://whiteat.com/87092 

 

Posted by WhiteAT

댓글을 달아 주세요

 

다운로드

매뉴얼: WAT-IO_ADC매뉴얼.pdf  

펌웨어 소스코드: EX_09_03.zip

   

 

 

 

 

제품 소개

   

WAT-IO&ADC 모듈은 AVR, Cortex-M3, PIC 등의 MCU와 10P Flat 케이블을 연결하여 Input/Output을 실험할 수 있는 모듈입니다. FND, LED, BUZZER 을 제어할 수 있으며 가변저항, CDS(빛의 밝기), 딥 스위치, 로터리 스위치의 값을 읽을 수 있는 제품입니다.

 

 

특징

 

항목

내용

FND

4 digit

LED

8 port

BUZZER

1 port (5V)

가변저항

5K

CDS

CDS

딥 스위치

8 channel

로터리 스위치

10R

크기

85 mm x 85 mm

인터페이스

Digital Input/Output

 

 

구조

    

   

 

 

외형

 

 

 

 

 

 

 

 

회로도

 

 

 

외부 인터페이스

 

 

커넥터

 

 

 

 

번호

핀명

설명

1

D0

DATA (bit 0)

2

D1

DATA (bit 1)

3

D2

DATA (bit 2)

4

D3

DATA (bit 3)

5

D4

DATA (bit 4)

6

D5

DATA (bit 5)

7

D6

DATA (bit 6)

8

D7

DATA (bit 7)

9

VCC

전원 ( DC 5V)

10

GND

그라운드

< FND DATA >

 

번호

핀명

설명

1

RO0

로터리 스위치 핀 0

2

RO1

로터리 스위치 핀 1

3

RO2

로터리 스위치 핀 2

4

RO3

로터리 스위치 핀 3

5

FND0

FND 0 선택 핀

6

FND1

FND 1 선택 핀

7

FND2

FND 2 선택 핀

8

FND3

FND 3 선택 핀

9

VCC

전원 ( DC 5V)

10

GND

그라운드

< FND SELECT, ROTARY SWITCH >

 

번호

핀명

설명

1

LED0

LED 0 제어 핀

2

LED1

LED 1 제어 핀

3

LED2

LED 2 제어 핀

4

LED3

LED 3 제어 핀

5

LED4

LED 4 제어 핀

6

LED5

LED 5 제어 핀

7

LED6

LED 6 제어 핀

8

LED7

LED 7 제어 핀

9

VCC

전원 ( DC 5V)

10

GND

그라운드

< LED >

 

 

 

번호

핀명

설명

1

AVCC

ADC 컨버터용 전압

2

AREF

ADC 컨버터용 기준 전압

3

CDS

CDS 센서 연결 핀

4

VR

가변저항 연결 핀

5

   

6

   

7

   

8

BUZ

부저 연결 핀

9

VCC

전원 ( DC 5V)

10

GND

그라운드

< ADC >

 

번호

핀명

설명

1

DIP0

딥스위치 1번 핀

2

DIP1

딥스위치 2번 핀

3

DIP2

딥스위치 3번 핀

4

DIP3

딥스위치 4번 핀

5

DIP4

딥스위치 5번 핀

6

DIP5

딥스위치 6번 핀

7

DIP6

딥스위치 7번 핀

8

DIP7

딥스위치 8번 핀

9

VCC

전원 ( DC 5V)

10

GND

그라운드

< DIP SWITCH >

 

 

ATMEGA128 모듈에 연결

 

WAT-AVR128 모듈의 PORTA는 LED, PORTB는 DIP SWITCH, PORTC는 FND SELECT, PORTE는 FND DATA, PORTE는 ADC 에 연결하여 PC 프로그램에서 제어 및 상태를 실시간으로 모니터링 하는 예제입니다.

 

 

 

WAT-AVR128 모듈

WAT-IO&ADC 모듈

PORTA

FND DATA

PORTB

 

PORTC

FND SELECT, ROTARY SWITCH

PORTD

DIP SWITCH

PORTE

LED

PORTF

ADC

 

 

ATEMGA128 펌웨어 코드

  /*

    EX_09_03.c

 

    USART0 로보드의상태PC로전송

    PC에서LED, BUZZER, FND 제어

    AVRStudio 4.18

*/

 

#include <avr/io.h>

#include "WAT128.h"

 

BYTE g_FNDData[4]={1,2,3,4};

BYTE g_BUZZER = 0;

BYTE g_LED = 0;

 

UINT16 g_adcCDS;    // CDS 값보관

UINT16 g_adcVR;    // 가변저항값보관

 

void OperDisplayFND()

{

    DisplayFND4(g_FNDData[0],g_FNDData[1],g_FNDData[2],g_FNDData[3]);

}

 

INT16 g_byteOperPCTXTimer = 0;

void OperPCTX()

{

    if(--g_byteOperPCTXTimer>0)

        return;

 

    PutChar0(0x02);                        // 0 시작신호

    PutChar0(PIND);                        // 1 DIP SWITCH

    PutChar0(GetRotaryInt());             // 2 ROTARY

    PutChar0(g_adcCDS>>8);                // 3 CDS 상위값

    PutChar0(g_adcCDS);                // 4 CDS 하위값

    PutChar0((g_adcVR)>>8 &0xFF); // 5 가변저항상위값

    PutChar0(g_adcVR&0xFF);                // 6 가변저항하위값

    PutChar0(0x03); // 7

    PutChar0(0xCC);                        // 8 체크섬

    PutChar0(0x03);                        // 9 끝신호

 

    g_byteOperPCTXTimer = 20;

 

}

 

// 가변저항, CDS 값을ADC로읽기

void OperReadADC()

{

    INT16 uiTemp; // 임시변수

 

    g_adcCDS = 0;

    // 노이즈를생각해서값을번읽어평균을낸다.

 

    for(uiTemp = 0; uiTemp<16;uiTemp++)

    {

        ADMUX=0x40 | 0x00;

        ADCSRA = 0xD7;

        while((ADCSRA & 0x10) != 0X10);

        g_adcCDS += ADCL + (ADCH*256);

    }

 

    g_adcCDS>>=4;

 

    g_adcVR = 0;

    // 노이즈를생각해서값을번읽어평균을낸다.

 

    for(uiTemp = 0; uiTemp<16;uiTemp++)

    {

        ADMUX=0x40 | 0x01;

        ADCSRA = 0xD7;

        while((ADCSRA & 0x10) != 0X10);

        g_adcVR += ADCL + (ADCH*256);

    }

 

    g_adcVR>>=4;

}

 

int main()

{

 

    BUZZER_INIT; // BUZZER 초기화

    OpenSCI0(115200);    // USART 0 열기

 

    InitFND4(); // FND 초기화

 

    InitADC();    // ADC 초기화

 

    DisplayFND4(3,4,5,6);

    InitRotary();

    

    DDRD = 0x00; // 딥스위치를입력으로설정

    DDRE = 0xFE; // LED

 

 

    while(1)

    {

        BUZZER_OFF;

        OperDisplayFND();

        OperReadADC();

        

        OperPCTX();

 

        if(0x02 ==GetByte0())

        {

            UINT16 uiData = 0;

            uiData = GetByte0(); //1

            uiData<<=8;

            uiData += GetByte0(); //2

 

            //buzzer

            g_BUZZER = GetByte0();

 

                

            g_LED =    GetByte0(); //4

            GetByte0(); //5

            GetByte0(); //6

            GetByte0(); //7

            if(0xCC == GetByte0() && 0x03 == GetByte0() )

            {

                if( g_BUZZER)

                {

                    BUZZER_ON;

                    DelayMS(2);

                }

 

                // PC에서받은LED 값을출력

                PORTE =~((g_LED)&0xFC);

 

                // FND 표시

                g_FNDData[0]=((uiData/1000)%10);

                g_FNDData[1]=((uiData/100)%10);

                g_FNDData[2]=((uiData/10)%10);

                g_FNDData[3]=(uiData%10);

            }

        }    

    }

} 

 

윈도우 코드(통신 처리 부분)

private void tmrRxData_Tick(object sender, EventArgs e)

{

btnRxSignal.BackColor = Color.White;

 

 

if (null == m_serialPort) return;

if (!m_serialPort.IsOpen) return;

 

int iRecSize = m_serialPort.BytesToRead; // 수신된 데이터 갯수

 

 

// AVR에서 10바이트식 보내는데 10바이트 이상이 들어 왔는지 체크

if (iRecSize >= 10)

{

byte[] buff = new byte[iRecSize]; // 임시 변수

 

// 시리얼 포트에서 데이터를 가져오자.

m_serialPort.Read(buff, 0, iRecSize);

 

// 맨앞의 값이 0x02 인지 체크

if (buff[0] !=0x02 )

{

for(int i=0;i<iRecSize-1;i++)

{

buff[i] = buff[i+1];

}

}

 

 

if (buff[0] == 0x02 && buff[8] == 0xCC && buff[9] == 0x03)

{

this.txbRotaryValue.Text = buff[2].ToString();

 

this.btnDIP1.BackColor = ((buff[1] & 0x01) == 0x01) ? Color.White : Color.Green;

this.btnDIP2.BackColor = ((buff[1] & 0x02) == 0x02) ? Color.White : Color.Green;

this.btnDIP3.BackColor = ((buff[1] & 0x04) == 0x04) ? Color.White : Color.Green;

this.btnDIP4.BackColor = ((buff[1] & 0x08) == 0x08) ? Color.White : Color.Green;

this.btnDIP5.BackColor = ((buff[1] & 0x10) == 0x10) ? Color.White : Color.Green;

this.btnDIP6.BackColor = ((buff[1] & 0x20) == 0x20) ? Color.White : Color.Green;

this.btnDIP7.BackColor = ((buff[1] & 0x40) == 0x40) ? Color.White : Color.Green;

this.btnDIP8.BackColor = ((buff[1] & 0x80) == 0x80) ? Color.White : Color.Green;

 

 

this.trbCDS.Value = (Convert.ToInt32(buff[3]) << 8) + (Convert.ToInt32(buff[4]) << 0);

this.trbCDS.BackColor = Color.FromArgb((1024-this.trbCDS.Value) / 4, (1024-this.trbCDS.Value) / 4, (1024-this.trbCDS.Value) / 4);

this.trbVR.Value = (Convert.ToInt32(buff[5]) << 8) + (Convert.ToInt32(buff[6]) << 0);

 

 

 

btnRxSignal.BackColor = Color.Green;

}

}

 

// AVR 모드로 명령 전송

this.SendToBoard();

 

}

 

 

윈도우 프로그램에서 FND에 5634, LED 모두 OFF 값을 전송하며 ATMEGA128 보드에서 딥 스위치4번 OFF, CDS값 최대, 가변저항 값 최소, 로터리 스위치 값 3을 전송되면 아래와 같이 됩니다.

< WAT-IO&ADC에 연결한 윈도우 프로그램 >

윈도우 프로그램에서 FND에 5667, LED 3,5,7번 ON 값을 전송하며 ATMEGA128 보드에서 딥 스위치1,3,5,7,번 ON, CDS값 최대, 가변저항 값 최대, 로터리 스위치 값 9을 전송되면 아래와 같이 됩니다.


원문: http://whiteat.com/57035


 

Posted by WhiteAT

댓글을 달아 주세요

 

STM32F103xx IO

 

STM32F103 시리즈는 최대 72Mhz까지 동작합니다. 그렇다고 모든 기능이 72Mh로 동작하는 것은 아니고, 각 기능마다 약간씩 다릅니다. 그 중에서 I/O 토글링은 18Mhz까지 제어할 수 있습니다.

 

 

 

 

While 사용

 

 

 

 

위와 같이 기본값을 설정하고 main 에서 while문으로 PORTE의 4번핀을 토글하게 되면

18Mhz로 동작할거 같은데 실제로는 아래처럼 3.13Mhz 로 파형이 나옵니다.

 

 

 

 

 

 

 

Optimizations

 

 

이는 컴파일 옵션에서 옵티마이즈가 None으로 되어 있어서 그런 겁니다.

아래처럼 옵션에서 High(Speed)로 지정하면 됩니다.

 

 

 

 

그러면 약 8Mhz까지 나옵니다.

 

 

 

 

왜 8Mhz 까지만 나올까요?

그것은 while(1) 때문입니다. 아래 2줄을 수행한 후 while문을 검사해야 하기 때문에 8Mhz 이상이 나오지 않는 겁니다.

GPIOE->BSRR = GPIO_Pin_4;
GPIOE->BRR = GPIO_Pin_4;

 

 

 

 

그렇다면 어떻게 해야 18Mhz 를 얻을 수 있을까요?

While(1)을 사용하지 않으면 될텐데…. While(1)을 사용하지 않는다면 프로그램은 무한히 실행되지 않을 겁니다.

 

그냥 while(1) 문 안에 무한히 토글해주면 됩니다.

 

 

while(1){

GPIOE->BSRR = GPIO_Pin_4;

GPIOE->BRR = GPIO_Pin_4;

GPIOE->BSRR = GPIO_Pin_4;

GPIOE->BRR = GPIO_Pin_4;

}

13.0902Mhz

 

 

 

 

while(1){

GPIOE->BSRR = GPIO_Pin_4;

GPIOE->BRR = GPIO_Pin_4;

GPIOE->BSRR = GPIO_Pin_4;

GPIOE->BRR = GPIO_Pin_4;

GPIOE->BSRR = GPIO_Pin_4;

GPIOE->BRR = GPIO_Pin_4;

}

13.4992Mhz

 

 

 

 

아래처럼 하면 거의 18Mhz에 가까워 집니다.

 

 

 

출처 : http://whiteat.com/56416

 

 

'[STM32] > 정리' 카테고리의 다른 글

STM32F103xx 시리즈 18Mhz로 토글  (0) 2012.03.13
Posted by WhiteAT

댓글을 달아 주세요