import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class Music extends Activity {
    MediaPlayer iu;
    MediaPlayer miss;
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // MediaPlayer 객체 생성
        iu = MediaPlayer.create(this, R.raw.iyou);
        miss = MediaPlayer.create(this, R.raw.missa);
       
        // 음악 버튼 핸들러 등록
        Button btn = (Button)findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
           
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                new AlertDialog.Builder(Music.this)
                .setTitle("음악선택")
                .setMessage("아이유?미스A?")
                .setPositiveButton("아이유", mClick)
                .setNegativeButton("미스A", mClick)
                .show();
            }
        });
       
        // 정지 버튼 핸들러 등록
        Button stop = (Button)findViewById(R.id.btn1);
        stop.setOnClickListener(new View.OnClickListener() {
           
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if(iu.isPlaying()) {
                    iu.pause();
                    iu.seekTo(0);
                }
                if(miss.isPlaying()) {
                    miss.pause();
                    miss.seekTo(0);
                }
                Toast.makeText(Music.this, "정지되었습니다", Toast.LENGTH_SHORT).show();
            }
        });
    }

    // 다른 액티비티가 호출 될 때(뒤로 버튼을 눌렀을 때)
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();   
        iu.stop();
        miss.stop();
        Toast.makeText(this, "정지되었습니다", Toast.LENGTH_SHORT).show();
    }
   
    // Dialog 핸들러
    DialogInterface.OnClickListener mClick = new DialogInterface.OnClickListener() {
       
        @Override
        public void onClick(DialogInterface dialog, int which) {
            // TODO Auto-generated method stub
            switch(which) {
            case DialogInterface.BUTTON1:
                if(miss.isPlaying()) {
                    miss.pause();
                    miss.seekTo(0);
                }
                iu.start();
                break;
            case DialogInterface.BUTTON2:
                if(iu.isPlaying()) {
                    iu.pause();
                    iu.seekTo(0);   
                }
                miss.start();
                break;
            }
        }
    };
}
// 음악 버튼을 누르면 다이얼로그가 뜬다. 거기서 아이유/미스A를 선택할 수 있는데, 각 버튼을 누르면 해당 노래가 플레이 된다.
// MediaPlayer의 stop() 멤버 함수를 이용하여 음악을 중지시킬 경우 다시 재생시 재생이 되지 않았다. 그래서 pause() 멤버 함수를 이용하여 음악을 중지시키는 걸로 해결했다.


   기본 자료 타입

 식별자
: 프로그램을 작성하다 보면 클래스나 메소드 변수 등에 직접 이름을 주어야 하는 경우가 생긴다. 이러한 클래스 이름, 메소드 이름, 변수 등과 같은 이름을 식별자라고 한다.

<< 식별자 명명 규칙
- 영문자(A~Z, a~z)와 숫자(0~9)와 '_', '$'의 조합으로 만들어진다.
- 첫 글자는 반드시 영문자나 '_'로 시작하여야 한다. 숫자로 시작해서는 안 된다.
- 식별자는 철자가 같다고 해도 대소문자를 구분하기 때문에 조심해야 한다.
- 자바에서 사용되는 예약어는 식별자로 사용할 수 없다.
- 식별자는 가급적이면 자기 역할에 맞는 이름을 부여한다.

 자바 자료 타입

자료 타입

디폴트

크기

정수

byte

0

8 bit

short

0

16 bit

Int

0

32 bit

long

0

64 bit

실수

float

0.0

32 bit

double

0.00

64 bit

true/false

boolean

False

1 bit

유니코드

char

U0000

16 bit


 문자형
자바에서 char형은 문자를 표현하기 위해 16비트 유니코드(Unicode) 문자 체계를 사용한다.


   기본 입출력

 자바의 기본 출력
출력을 위한 메소드는 println(), print(), printf()와 같이 3가지 형태로 제공된다.

 간단한 출력 예제
public class Test {

  /**
   * @param args
   */

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    System.out.println("println()");
    System.out.print("print()");
    System.out.printf("%s\n""printf()");
  }
}


 자바의 기본 입력
자바에서는 표준 입력 장치인 키보드에 대해서 System 클래스에 in라는 객체를 마련해 두었다. System.in 객체로 read() 메소드를 호출하여 키보드에서 데이터를 입력 받을 수 있다.
public abstract int read() throws 

 간단한 입력 예제 - 키보드에서 문자 한개 입력받기
import java.io.*;

public class Test {

  /**
   * @param args
   */

  public static void main(String[] args) throws IOException{
    // TODO Auto-generated method stub
    int data = 0;
    System.out.print("Input Character : ");
    data = System.in.read();
    System.out.println(data);
    System.out.println((char)data);
  }
}


 간단한 입력 예제 - Scanner 클래스를 사용하여 키보드에서 정수 입력받기
import java.util.*;

public class Exam {

  /**
   * @param args
   */

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner input = new Scanner(System.in);
    int a, b, c;
    System.out.print("정수 데이터 2개 입력 >> ");
    a = input.nextInt();
    b = input.nextInt();
    c = a + b;
    System.out.printf("%3d + %3d = %4d", a, b, c);
  }
}



    연산자

 산술 연산자

구분

연산자

의미

단항 산술 연산자

+

-

이항 산술 연산자

+

-

*

/

나눗셈

%

나머지


연산자

연산자 호칭

설명

++

++x

전위 증가 연산자

연산 전에 x 증가

x++

후위 증가 연산자

연산 후에 x 증가

--

--x

전위 감소 연산자

연산 전에 x 감소

x--

후위 감소 연산자

연산 후에 x 감소


 관계 연산자

> 

op1 > op2

op1 op2보다 크다

>=

op1 >= op2

op1 op2보다 크거나 같다

< 

op1 < op2

op1 op2보다 작다

<=

op1 <= op2

op1 op2보다 작거나 같다

==

op1 == op2

op1 op2 같다

!=

op1 != op2

op1 op2 같지 않다

Instanceof

op1 instanceof op2

op1 op2 인스턴스이다


 논리 연산자

&&

op1 && op2

op1 op2 모드 true이면 true, 그렇지 않으면 false

||

op1 || op2

op1 op2 하나 이상이 true이면 true, 모두 false 이면 false

!

!op

op true이면 false, false이면 true


 비트 연산자

&

op1 & op2

op1 op2 비트 단위의 논리곱

|

op1 | op2

op1 op2 비트 단위의 논리합

^

op1 ^ op2

op1 op2 비트 단위의 배타적 논리곱

~

~op

비트 단위의 1 보수

>> 

op1 >> op2

op1 op2만큼 오른쪽으로 이동

<< 

op1 << op2

op1 op2만큼 왼쪽으로 이동

>>> 

op1 >>> op2

op1 op2만큼 오른쪽으로 이동

왼쪽에는 항상 부호에 상관없이 0 채워진다







   윈도우 기반 직렬통신

 윈도우 기반 직렬 통신을 위해 먼저 Virtual Serial Port Driver 프로그램을 설치했다. 크로스 연결된 2개의 가상 포트를 생성할 수 있다.

 



설정이 끝나고 장치관리자를 보면 위와 같이 뜬다.

 직렬 통신 절차


 송신 프로그램
#include <stdio.h>
#include <iostream>
#include <windows.h>
using namespace std;

int main(void)
{
  char szPort[15];

  wsprintf(szPort, "COM%d"2);

  HANDLE m_hComm = NULL;
  m_hComm = CreateFile(szPort,
            GENERIC_READ | GENERIC_WRITE,
            0, NULL, OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL, NULL);    // 통신 포트 열기
  
  if(m_hComm == INVALID_HANDLE_VALUE)
  {
    printf("(!) Failed to create a Comm Device file");
    return FALSE;
  }
  DCB dcb;
  dcb.DCBlength = sizeof(DCB);

  GetCommState(m_hComm, &dcb);  // 기본 통신 상태 읽기

  // 통신 속도 상태 설정
  dcb.BaudRate = 9600;
  dcb.ByteSize = 8;
  dcb.Parity = 0;
  dcb.StopBits = 0;

  SetCommState(m_hComm, &dcb);

  // 통신 이벤트 객체 생성
  OVERLAPPED osWrite;
  osWrite.Offset = 0;
  osWrite.OffsetHigh = 0;
  osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  char buf[100= "Hello world \r\n";
  while(1)
  {
    cout << "Input : ";
    cin >> buf;
    printf("send:%s\n", buf);
    WriteFile(m_hComm, buf, strlen(buf), NULL, &osWrite);  // 데이터 전송

    if((buf[0== '-'&& (buf[1== '1'))
      break;
    //Sleep(1000);
  }
  CloseHandle(m_hComm);

  return 0;
}

 수신 프로그램
#include <stdio.h>
#include <windows.h>
#include <iostream>
using namespace std;

int main(void)
{
  char szPort[15];

  wsprintf(szPort, "COM%d"3);

  HANDLE m_hComm = NULL;
  m_hComm = CreateFile(szPort,
            GENERIC_READ | GENERIC_WRITE,
            0, NULL, OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL, NULL);  // 통신 포트 열기
  
  if(m_hComm == INVALID_HANDLE_VALUE)
  {
    printf("(!) Failed to create a Comm Device file");
    return FALSE;
  }
  DCB dcb;
  dcb.DCBlength = sizeof(DCB);

  GetCommState(m_hComm, &dcb);  // 기본 통신 설정 상태 읽기

  // 통신 속도 상태 설정
  dcb.BaudRate = 9600;
  dcb.ByteSize = 8;
  dcb.Parity = 0;
  dcb.StopBits = 0;

  SetCommState(m_hComm, &dcb);

  // 통신 이벤트 객체 생성
  OVERLAPPED osRead;
  osRead.Offset = 0;
  osRead.OffsetHigh = 0;
  osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  DWORD size;
  char buf[100];
  while(1)
  {
    ReadFile(m_hComm, buf, 100&size, &osRead);  // 데이터 수신
    buf[size] = '\0';
    printf("recv:%s\n", buf);
    if((buf[0== '-'&& (buf[1== '1'))
      break;
  }
  CloseHandle(m_hComm);

  return 0;
}
// COM2, COM3는 가상 포트로 두 포트는 연결되어 있는 상태이다.
// 송신 프로그램에서 전송할 문자를 입력한 뒤 엔터를 치면 데이터를 전송한다.
// -1를 입력하면 송신 프로그램 수신 프로그램 모두 종료 된다.



   A/D 컨버터(Analog Digital Converter)

 AT91SAM7S256은 8채널 10비트 또는 8비트 분해능의 축자비교형 A/D 컨버터를 가지고 있다. 각 채널의 입력은 내부의 아날로그 멀티플렉서에 의하여 선택되며, 이들 8채널의 아날로그 입력신호 중에서 AD0~AD3은 병렬 I/O 포트와 겸용으로 사용하고 있고, AD4~AD7은 전용핀을 가지고 있다.

 A/D 컨버터에서 사용하는 클럭의 주파수는 ADC_MR 레지스터의 PRESCAL 필드에 의하여 MCK/2/(PRESCAL+1)로 결정되므로 MCK/2 ~ MCK/128의 범위가 된다. 10비트 분해능을 사용할 때는 A/D 클럭으로 5MHz 이하를 사용해야 하며, 8비트 분해능을 사용할 때는 A/D 클럭으로 8MHz 이하를 사용해야 한다.
 각 채널에서 10비트 또는 8비트 분해능으로 A/D 변환을 수행하는데는 ADC_MR 레지스터에서 SHTIM 필드로 지정한 샘플/홀드에 필요한 클럭 주기와 10주기의 A/D 변환 클럭 사이클이 소요 된다. 샘플/홀드 시간은 최소 600ns 이상이 필요하다.
ex) 10비트 분해능 5MHz 클럭에서 최소 3주기의 샘플/홀드 시간과 10주기의 A/D 변환 시간이 소요  
      : 최대 384kSPS(sampling/sec)
       8비트 분해능 8MHz 클럭에서 최소 5주기의 샘플/홀드 시간과 10주기의 A/D 변환 시간이 소요  
      : 최대 533kSPS(sampling/sec)

 A/D 컨버터에는 외부 단자 ADVREF를 통하여 기준전압이 공급되어야 한다. 이 기준전압은 2.6V ~ VDDIN의 범위를 가져야 하며, 이에 따라 각 채널에서의 아날로그 신호 입력의 범위는 0.0V ~ ADVREF로 결정된다.

 8비트 분해능을 사용할 경우에는 이중에서 하위 8비트만 유효하며 사용하지 않는 상위 2비트는 0으로 읽혀진다.

 A/D 컨버터가 변환을 완료하면 상태 레지스터 ADC_SR 에서 EOCx 비트와 DRDY 비트가 1로 세트된다. 사용자 프로그램으로 ADC_CDRx 레지스터를 읽으면 EOCx 비트는 0으로 클리어되며, ADC_LCDR 레지스터를 읽으면 EOCx 비트와 DRDY 비트가 모두 0으로 클리어 된다.

 새로운 A/D 변환이 왼료될 때까지 ADC_CDRx 레지스터에 저장되어 있는 이전의 A/D 변환 결과를 읽지 않으면 오버런 에러가 되고 ADC_SR 레지스터에서 대응하는 채널의 OVREx 비트가 세트된다. 마찬가지로 ADC_LCDR 레지스터를 읽지 않아 오버런 에러가 발생하면 ADC_SR 레지스터에서 GOVRE 비트가 세트된다. 이들 에러 비트는 ADC_SR 레지스터를 읽으면 자동으로 클리어된다.

 A/D 변환 트리거는 여러 개의 채널을 사용하더라도 오직 1번만을 필요로 한다. 즉 A/D 변환을 시작하도록 트리거하면 동작이 허용된 모든 채널에서 A/D 변환이 시작된다.

 A/D 컨버터를 슬립 모드로 하면 클럭의 공급을 차단하고 동작을 저지시킴으로써 소비전력을 크게 절약할 수 있다. A/D 컨버터가 슬립 모드에 있더라도 A/D 컨버터 내부의 로직 회로는 정상으로 동작하여 모든 I/O 레지스터의 액세스가 가능하다.

 // ADC 예제 소스
#include "MyArm.h"

//--------- Global Variable�

void Delayms(unsigned int ms) //Delay Function..

  volatile unsigned int count, countmax = (MASTERCLOCK / 10000) * ms;

  for(count = 0; count < countmax; count++);
}

void DBGU_write(char *d)
{
  while(0 != *d)
  {
    while(0 == (DBGU_SR & 0x0002));
    DBGU_THR = *d;
    ++d;
  }
}

void intToChar(char *buf, unsigned int num)
{
  int i, j;
  int target;    // 각 자리수
  int value = 1;  // 숫자 크기 확인
  
  while(value <= num)
  {
    value *= 10;
  }  
  
  for(i = 0, j = value/10 ; j >= 10 ; j /= 10)
  {
    target = num / j;
    num = num % j;
    buf[i++] = target + 48;    // buf에 문자값 저장
  }
  buf[i++] = num + 48;
  buf[i] = '\0';
}

int main(void)
{  
  unsigned int data;
  unsigned int tmp;
  char buf[10];
  
  DBGU_CR = (1 << P2) | (1 << P3);  // TX,RX reset & disable
  
  // PMC setting
  PMC_PCER = (1 << PID4);

  // PIO setting
  PIO_PDR = (1 << P10);
  PIO_ASR = (1 << P10);
  
  // DBGU setting
  DBGU_MR = (1 << P11);        // No Parity
  DBGU_BRGR = 313;          // Baud rate = 9600
  DBGU_CR = (1 << P6);        // TX enable
  
  // ADC setting
  ADC_MR = (23 << P8) | (1 << P4) | (1 << P24);  // PRESCAL = 23(1Mhz), 8 bit Low Resolution, SHTIM = 1
  ADC_CHER = (1 << P4);              // Channel 4

  while(1)
  {
    ADC_CR = (1 << P1);            // Start Conversion
    while(0 == (ADC_SR & (1 << P16)));
    data = ADC_LCDR;
    intToChar(buf, data);
    DBGU_write(buf);
    DBGU_write("\r\n");
    Delayms(50);
    tmp = ADC_SR;
  }
  
  return 0;
// End Main...
// 변환 값 입력에 가변저항을 연결하여 저항을 바꿔가면서 입력값에 변화를 준다.
// 이때 입력된 아날로그 신호에 대응하는 변환된 디지털 값들을 시리얼 통신을 이용하여 PC의 터미널에 보여준다.
// ADC_CR 에 START 비트는 변환할 때마다 1로 세트 해주어야 한다.
   PIT(주기적인 시간간격 타이머)
 PIT(Periodic Interval Timer)는 운영체제의 스케쥴러에게 주기적인 인터럽트를 발생시키기 위하여 사용하는 타이머이다. 여기서는 효율적인 관리가 중요하며, 시간의 정확성을 높이기 위하여 슬로우 클럭이 아니라 마스터 클럭을 사용한다.

 주기적인 시간간격 타이머는 마스터 클럭을 16분주한 MCK/16의 주파수로 동작하며, 20비트 증가형 카운터 CPIV와 12비트 증가형 카운터 PICNT로 구성된다. 이것이 동작하려면 PIT_MR 레지스터에서 PITEN 비트를 인에이블시켜야 한다.
 
 20비트 카운터 CPIV는 0부터 증가하다가 PIT_MR 레지스터의 PIV 값에 이르게 되면 그 다음 주기에서 자동으로 0으로 클리어 되면서 12비트 카운터 PICNT를 1만큼 증가시키게 되며, 이는 또한 인터럽트를 요청할 수 있다. 따라서, 인터럽트 주기는 PIV+1클럭 사이클이 된다.

 PIT_MR 레지스터의 PIV 값을 변경하기 위하여 새로 라이트하더라도 카운터를 리셋하거나 리스타트하지는 않는다.

 CPIV 값이나 PICNT 값을 확인하기 위하여 PIT_PIVR 레지스터를 읽으면 PICNT 값이 0으로 클리어되고 PIT_SR 레지스터의 PITS 비트도 클리어되어 인터럽트 신호를 종료시킨다. 그러나, PIT_PIIR 레지스터를 읽으면 PICNT 값이나 PIT_SR 레지스터의 PITS 비트를 클리어하지 않는다.

 // PIT(Periodic Inteval Timer)
#include "MyArm.h"

#define INTERR    0x00000100
#define LED      0x00000010 

//--------- Global Variable?
int c = 0;
int cnt = 0;

void DBGU_write(char *d)
{
  while(0 != *d)
  {
    while(0 == (DBGU_SR & 0x0002));
    DBGU_THR = *d;
    ++d;
  }
}

void intToChar(char *buf, int num)
{
  int i, j;
  int target;    // 각 자 리수
  int value = 1;  // 숫자 크기 확인
  
  while(value <= num)
  {
    value *= 10;
  }  
  
  for(i = 0, j = value/10 ; j >= 10 ; j /= 10)
  {
    target = num / j;
    num = num % j;
    buf[i++] = target + 48;    // buf에 문자값 저장
  }
  buf[i++] = num + 48;
  buf[i] = '\0';
}

void SysControlISR()
{  
  unsigned int tmp;
  char tx[10];
  tmp = PIT_PIVR;        // Interrupt Reset
  cnt++;

  if(1000 == cnt)  
  {
    intToChar(tx, c);
    DBGU_write(tx);
    c++;
    cnt = 0;
  }
}

int main(void)
{  
  DBGU_CR = (1 << P2) | (1 << P3);  // TX,RX reset & disable
  AIC_IDCR = (1 << P1);        // System Controller Interrupt Disable
  
  // PIO setting
  PIO_PDR = (1 << P9) | (1 << P10);  // PA9, PA10 Disable
  PIO_ASR = (1 << P9) | (1 << P10);  // PA9, PA10 Peripheral A select
  
  // DBGU setting
  DBGU_MR = (1 << P11);        // No Parity
  DBGU_BRGR = 313;          // Baud rate = 9600
  DBGU_CR = (1 << P6);        // TX enable
  
  // PIT setting
  PIT_MR = (0xBB7) | (1 << P25) | (1 << P24);    // PIV = 2999, PITIEN enable
  
  // AIC setting
  AIC_SMR[1= (1 << P5) | (1 << P2) | (1 << P0);  // Positive edge, Priority = 5;
  AIC_SVR[1= (unsigned int)SysControlISR;    // System Controller ISR
  AIC_IECR = (1 << P1);        // System Controller Interrupt Enable

  while(1)
  {

  }  
  
  return 0;
// End Main...
// 1초마다 숫자를 카운트해서 그 숫자를 시리얼 통신으로 전송하는 예제이다.
// 인터럽트 처리 루틴에서 PIT_PIVR 값을 읽어서 인터럽트를 리셋을 해준다.
// MASTERCLOCK에서 16분주 한 클럭으로 카운트를 하므로 PIV 값을 2999를 주면 1ms 가 만들어진다.(인터럽트는 PIV+1일 때 발생한다)
// 48M / 16 = 3M -> 3M / 3000 = 1K  : 1초에 1000번을 카운트 함으로 1ms마다 인터럽트가 발생하게 된다.

 // MyArm.h
//----------------------------------------------------------------------------------------------------------                              
#define FIQ      0  //AIC = Advanced Interrupt Controller(FIQ)
#define SYS      1  //SYS = System Controller
#define PID2    2  //PIOA
//#define PID3    3  //reserved
#define PID4    4  //ADC = Analog to Digital Converter
#define PID5    5  //SPI = Serial Peripheral Interface
#define PID6    6  //US0 = USART0
#define PID7    7  //US1 = USART1
#define PID8    8  //SSC = Synchronous Serial Controller
#define PID9    9  //TWI = Two-Wire Interface
#define PID10    10  //PWMC= PWM Controller
#define PID11    11  //UDP = USB Device Port
#define PID12    12  //TC0 = Timer/Conuter 0
#define PID13    13  //TC1 = Timer/Conuter 1
#define PID14    14  //TC2 = Timer/Conuter 2
/*            
#define PID15    15  //reserved
#define PID16    16
#define PID17    17
#define PID18    18
#define PID19    19
#define PID20    20
#define PID21    21
#define PID22    22
#define PID23    23
#define PID24    24
#define PID25    25
#define PID26    26
#define PID27    27
#define PID28    28
#define PID29    29
*/

#define PID30    30  //AIC = Advanced Interrupt Controller (IRQ0)
#define PID31    31  //AIC = Advanced Interrupt Controller (IRQ1)
//----------------------------------------------------------------------------------------------------------                              
#define P0      0
#define P1      1
#define P2      2
#define P3      3
#define P4      4
#define P5      5
#define P6      6
#define P7      7
#define P8      8
#define P9      9
#define P10      10
#define P11      11
#define P12      12
#define P13      13
#define P14      14
#define P15      15
#define P16      16
#define P17      17
#define P18      18
#define P19      19
#define P20      20
#define P21      21
#define P22      22
#define P23      23
#define P24      24
#define P25      25
#define P26      26
#define P27      27
#define P28      28
#define P29      29
#define P30      30
#define P31      31
//----------------------------------------------------------------------------------------------------------                              
//DBGU
#define RXEN    4
#define TXEN    6
#define RSTSTA    8

#define DRXD    9  //Debug Receive Data
#define DTXD    10  //Debug Transmit Data

#define RXRDY    0
#define TXRDY    1
//----------------------------------------------------------------------------------------------------------                              
//PIO  = Parallel  Input/Output  Controller
#define PIO_PER    (*(volatile unsigned int *) 0xFFFFF400) //PIO  Enable               Register
#define PIO_PDR    (*(volatile unsigned int *) 0xFFFFF404) //PIO  Disable              Register
#define PIO_OER    (*(volatile unsigned int *) 0xFFFFF410) //PIO  Output     Enable         Register
#define PIO_ODR    (*(volatile unsigned int *) 0xFFFFF414) //PIO  Output     Disable        Register
#define PIO_IFER  (*(volatile unsigned int *) 0xFFFFF420) //PIO  Glitch  Input  Filter  Enable  Register
#define PIO_SODR  (*(volatile unsigned int *) 0xFFFFF430) //PIO  Controller   Set    Output Data Register
#define PIO_CODR  (*(volatile unsigned int *) 0xFFFFF434) //PIO  Controller   Clear   Output Data Register
#define PIO_IER    (*(volatile unsigned int *) 0xFFFFF440) //PIO  Interrupt   Enable        Register
#define PIO_IDR    (*(volatile unsigned int *) 0xFFFFF444) //PIO  Interrupt   Disable        Register
#define PIO_ISR    (*(volatile unsigned int *) 0xFFFFF44C) //PIO  Interrupt   Status        Register
#define PIO_PUDR  (*(volatile unsigned int *) 0xFFFFF460) //PIO  Pull-Up   Disable        Register
#define PIO_PUER  (*(volatile unsigned int *) 0xFFFFF464) //PIO  Pull-Up   Enable        Register
#define PIO_ASR    (*(volatile unsigned int *) 0xFFFFF470) //PIO  Peripheral  A  Select      Register
#define PIO_BSR    (*(volatile unsigned int *) 0xFFFFF474) //PIO  Peripheral  B  Select      Register
//----------------------------------------------------------------------------------------------------------                      
//AIC  = Advance Interrupt Controller
#define AIC_SMR    ( (volatile unsigned int *) 0xFFFFF000)  //(Address of) AIC Source Mode       Register
#define AIC_SVR    ( (volatile unsigned int *) 0xFFFFF080)  //(Address of) AIC Vector         Register
#define AIC_IECR  (*(volatile unsigned int *) 0xFFFFF120)  //AIC  Interrupt  Enable  Command    Register
#define AIC_IDCR  (*(volatile unsigned int *) 0xFFFFF124)  //AIC  Interrupt  Disable  Command    Register
#define AIC_ICCR  (*(volatile unsigned int *) 0xFFFFF128)  //AIC  Interrupt  Clear  Command    Register
//----------------------------------------------------------------------------------------------------------
//DBGU  = Debug Unit
#define DBGU_CR    (*(volatile unsigned int *) 0xFFFFF200)  //DBGU  Control              Register
#define DBGU_MR    (*(volatile unsigned int *) 0xFFFFF204)  //DBGU  Mode              Register
#define DBGU_SR    (*(volatile unsigned int *) 0xFFFFF214)  //DBGU  Status              Register
#define DBGU_RHR  (*(volatile unsigned int *) 0xFFFFF218)  //DBGU  Receive    Holding        Register
#define DBGU_THR  (*(volatile unsigned int *) 0xFFFFF21C)  //DBGU  Transmit  Holding        Register
#define DBGU_BRGR  (*(volatile unsigned int *) 0xFFFFF220)  //DBGU  Baud Rate  Generator Control  Register
#define DBGU_IER  (*(volatile unsigned int *) 0xFFFFF208)  //DBGU  Interrupt  Enable        Register
#define DBGU_IDR  (*(volatile unsigned int *) 0xFFFFF20C)  //DBGU  Interrupt  Disalbe        Register
#define DBGU_IMR  (*(volatile unsigned int *) 0xFFFFF210)  //DBGU  Interrupt  Disalbe        Register
//----------------------------------------------------------------------------------------------------------
//TC  = Timer Counter
#define TC0_CCR    (*(volatile unsigned int *) 0xFFFA0000)  //TC  Channel    Control        Register
#define TC0_CMR    (*(volatile unsigned int *) 0xFFFA0004)  //TC  Channel    Mode        Register
#define TC0_CV    (*(volatile unsigned int *) 0xFFFA0010)  //TC  Counter    Value        Register
#define TC0_RA    (*(volatile unsigned int *) 0xFFFA0014)  //TC  Register A            Register
#define TC0_RB    (*(volatile unsigned int *) 0xFFFA0018)  //TC  Register B            Register
#define TC0_RC    (*(volatile unsigned int *) 0xFFFA001C)  //TC  Register C            Register
#define TC0_SR    (*(volatile unsigned int *) 0xFFFA0020)  //TC  Status              Register
//----------------------------------------------------------------------------------------------------------
//PM  = Power Management Controller
#define PMC_PCER  (*(volatile unsigned int *) 0xFFFFFC10)  //PMC Syetem Clock Enable         Register
#define PMC_PCDR  (*(volatile unsigned int *) 0xFFFFFC14) //PMC System clock Disable        Register
#define MASTERCLOCK 48000000
//----------------------------------------------------------------------------------------------------------


 // 타이머 카운터를 이용해서 LED 컨트롤
#include "MyArm.h"

#define INTERR    0x00000100
#define LED      0x00000010 

//--------- Global Variable

void Delayms(unsigned int ms) //Delay Function..

  volatile unsigned int count, countmax = (MASTERCLOCK / 10000) * ms;

  for(count = 0; count < countmax; count++);
}

int main(void)
{  
  int flag = 1;  // flag
  int cnt = 0;  // count flag

  // PMC setting
  PMC_PCER = (unsigned int)1 << PID12;  // Peripheral 12 clock Enable
  
  // PIO setting
  PIO_PDR = (1 << P0) | (1 << P1);    // PA0, PA1 PIO disable  
  PIO_BSR = (1 << P0) | (1 << P1);    // Peripheral B select
  
  // TC setting
  TC0_CCR = (1 << P0) | (1 << P2);    // Software Trigger, Counter Clock Enable
  TC0_CMR = (1 << P15) | (1 << P16) | (1 << P19) | (1 << P24) | (1 << P27) | (1 << P10)
 | (1 << P2); // (MCK / 32), Waveform mode
  TC0_RA = 0x0000;
  TC0_RB = 0xF906;
  TC0_RC = 0xFFFF;
  
  while(1)
  {
    if(flag)
    {
      TC0_RA += 0xFF;
      TC0_RB -= 0xFF;
      cnt++;
      if(cnt >= 250)
      {
        flag = 0;
      }
    }
    else
    {
      TC0_RA -= 0xFF;
      TC0_RB += 0xFF;      
      cnt--;
      if(cnt <= 0)
      {
        flag = 1;
      }
    }
    Delayms(10);
  }
  
  return 0;
// End Main....
// 타이머 카운터를 이용하여 2개의 클럭 신호를 만들어 낸다. 한쪽 LED는 밝은 상태에서 점차 어두워지고, 다시 점차 밝아지는 동작을 반복한다. 나머지 한쪽은 그 반대로 동작한다.
// 처음에는 저번 시간과 같은 방법으로 셋팅을 했는데 TIOB0으로 신호가 나오지 않았다. 나중에 EEVT 필드 값을 01로 셋팅하자 TIOB0으로 신호가 나오기 시작했다. TIOB0으로 디폴트로 입력으로 설정 되어 있는 것 같았다.
// TCCLKS 필드를 (MASTERCLOCK / 2) 로 셋팅 했을 때, 출력이 동기화가 되지 않았다. 한쪽이 어두워지면 한쪽은 밝아져야 하는데, 한쪽 출력이 먼저 일어나고 그 다음 다른쪽이 출력되는걸로 보였다. 이는 TCCLKS 필드를 (MASTERCLOCK / 32) 즉 카운터 클럭을 낮추니 TIOA0과 TIOB0에서 제대로된 신호가 나왔다.

ARM

타이머 카운터0
AT91SAM7S256에는 동일한 구조와 기능의 16비트 타이머/카운러채널 (TC0~TC2)를 가지고 있다. 이들 3개의 채널은 서로 독립적으로 동작하며 이벤트카운트, 주파수 측정, 시간간격측정,시간지연, 펄스 발생 PWM출력등의 기능을 수행할 수 있다.

실습
TC0를 이용하여 파형발생 모드로 led를 깜박이기

사용레지스터

채널 콘트롤 레지스터 클럭을 인가할때 사용한다.


채널 모드 설정 wave=1로 하면 파형출력 모드를 사용한다.

파형 모드 설정

ACPA  RA 값을 비교하여 TIOA를 설정한다.
ACPC RC 값을 비교하요 TIOA를 설정한다.


TC0_CV 실시간으로 카운터 값을 저장한다.
TC0_RA 실시간을로 RA값을 저장한다.
TC0_RC 실시간을로 RC값을 저장한다.



분주비



#include "MyArm.h"

#define MASTERCLOCK 48000000
#define INTERR    0x00000100
#define LED      0x00000010 

//--------- 전역 변수

void Delayms(unsigned int ms) //딜레이 함 수..

  volatile unsigned int count, countmax = (MASTERCLOCK / 10000) * ms;

  for(count = 0; count < countmax; count++);
}

int main(void)
{  
  // PMC setting
  PMC_PCER = (unsigned int)1 << PID12;  // 장치 PID12번에 클럭 공급
  
  // PIO setting
  PIO_PDR = (1 << P0) | (1 << P1);    // PA0, PA1 Disable
  PIO_BSR = (1 << P0) | (1 << P1);    // PA0, PA1 장치 B Select
  
  // TC setting
  TC0_CCR = (1 << P0) | (1 << P2);    // TC enalbe
  TC0_CMR = (1 << P15) | (1 << P16) | (1 << P19) | (1 << P2);  // RA compare set, RC compare clear, clock=48Mhz/1024
  TC0_RA = 0x000F;
  TC0_RC = 0xF000;
  
  while(1)
  {

  }
  
  return 0;
// End Main....
// 타이머 카운터를 이용하여 일정 클럭 신호를 만들어서, LED로 확인해 보는 예제이다.

   시리얼 통신(DBGU) 인터럽트

 // 인터럽트를 이용한 echo 예제
//---------- 디버그 유닛 관련 I/O 제어 레지스터

#define DBGU_CR   (*(volatile unsigned int *) 0xFFFFF200)  // DBGU Control Register
#define DBGU_MR   (*(volatile unsigned int *) 0xFFFFF204)  // DBGU Mode Register
#define DBGU_IER  (*(volatile unsigned int *) 0xFFFFF208)  // DBGU Interrupt Enable Register
#define DBGU_IDR  (*(volatile unsigned int *) 0xFFFFF20C)  // DBGU Interrupt Disalbe Register
#define DBGU_IMR  (*(volatile unsigned int *) 0xFFFFF210)  // DBGU Interrupt Disalbe Register
#define DBGU_SR   (*(volatile unsigned int *) 0xFFFFF214)  // DBGU Status Register
#define DBGU_RHR  (*(volatile unsigned int *) 0xFFFFF218)  // DBGU Receive Holding Register
#define DBGU_THR  (*(volatile unsigned int *) 0xFFFFF21C)  // DBGU Transmit Holding Register
#define DBGU_BRGR (*(volatile unsigned int *) 0xFFFFF220)  // DBGU Baud Rate Generator Register


//---------- 인터럽트 제어기 IO설정 

#define AIC_IECR (*(volatile unsigned int *) 0xFFFFF120)  // 인터럽트 허 용 레지스터
#define AIC_IDCR (*(volatile unsigned int *) 0xFFFFF124)  // 인터럽트 금지 레지스터
#define AIC_ICCR (*(volatile unsigned int *) 0xFFFFF128)  // 인터럽트 클리어 레지스터
#define AIC_ISCR (*(volatile unsigned int *) 0xFFFFF12C)  // 인터럽트 세트 레지스터
#define AIC_SMR  ((volatile unsigned int *) 0xFFFFF000)    // AIC 소스 모드 레지스터
#define AIC_SVR  ((volatile unsigned int *) 0xFFFFF080)    // AIC 소 스 벡터 레지스터


//---------- 입출 력 IO설정 


#define PIO_PUDR (*(volatile unsigned int *) 0xFFFFF460)  // PIO Pull-Up Disable Register
#define PIO_PUER (*(volatile unsigned int *) 0xFFFFF464)  // PIO Pull-Up Enable Register

#define PIO_IER  (*(volatile unsigned int *) 0xFFFFF440)  // PIO Interrupt Enable Register
#define PIO_IDR  (*(volatile unsigned int *) 0xFFFFF444)  // PIO Interrupt Disable Register
#define PIO_IMR  (*(volatile unsigned int *) 0xFFFFF448)  // PIO Interrupt Mask Register
#define PIO_ISR  (*(volatile unsigned int *) 0xFFFFF44C)  // PIO Interrupt Status Register

#define PIO_ASR  (*(volatile unsigned int *) 0xFFFFF470)  // PIO Peripheral A Select Register
#define PIO_BSR  (*(volatile unsigned int *) 0xFFFFF474)  // PIO Peripheral B Select Register

#define PIO_IFER (*(volatile unsigned int *) 0xFFFFF420)  // PIO Glitch Input Filter Enable Register
#define PIO_IFDR (*(volatile unsigned int *) 0xFFFFF424)  // PIO Glitch Input Filter Disable Register

#define PIO_SODR (*(volatile unsigned int *) 0xFFFFF430) //출력 
#define PIO_CODR (*(volatile unsigned int *) 0xFFFFF434) //출력 하지 않음
#define PIO_OER  (*(volatile unsigned int *) 0xFFFFF410) //출력 방향 설정
#define PIO_ODR  (*(volatile unsigned int *) 0xFFFFF414) //출력 방향 설정
#define PIO_PER  (*(volatile unsigned int *) 0xFFFFF400) //병렬 입출력 제 어 레지스터 병렬 입출력 포트로 사용한다.
#define PIO_PDR  (*(volatile unsigned int *) 0xFFFFF404) //병렬 입출력 제어 레지스터 병렬 입출력 포트로 사용한다.


//---------- 전력 제어 설정

#define PMC_PCER (*(volatile unsigned int *) 0xFFFFFC10)
#define PMC_PCDR (*(volatile unsigned int *) 0xFFFFFC14)

 
#define MASTERCLOCK 48000000
#define INTERR    0x00000100
#define LED      0x00000010 

//--------- 전역 변수
unsigned char data;

void Delayms(unsigned int ms) //딜레이 함 수..

  volatile unsigned int count, countmax = (MASTERCLOCK / 10000) * ms;

  for(count = 0; count < countmax; count++);
}

void DBGU_write(char d)  // 송신 함수
{
  while(0 == (DBGU_SR & 0x0002));
  DBGU_THR = d;
}

void DBGU_read()    // 인 터럽트 처리 루틴
{
  // echo 기능
  data = DBGU_RHR;
  DBGU_write(data);
}

int main(void)
{  
  // PMC setting
  PMC_PCER = (unsigned int)1 << 2;    // PMC_PCER = (unsigned int)1 << 2;

  DBGU_CR = (1<<2)|(1<<3);      // 송수신부 리셋 및 금지  
  AIC_IDCR = (1<<1);          //인터럽트 금지
  
  // PIO setting
  PIO_PDR = (1<<9)|(1<<10);  // 병렬 포트 사용 금지
  PIO_ASR = (1<<9)|(1<<10);  // 장치 A 사용
  PIO_BSR = 0;        // 장치 B 사용 금지

  // DBGU setting
  DBGU_IER = (1 << 0);    // RXRDY enable
  DBGU_MR = (1<<11);      // Parity 사용하 지 않음
  DBGU_BRGR = 313;      // Baud rate = 9600
  DBGU_CR = (1<<6)|(1<<4);  // tx, rx enable
  
  // AIC setting.
  AIC_SMR[1= (1<<5)|(1<<6)|(1<<2)|(1<<0);  // Positive edge trigger, Prior = 5
  AIC_SVR[1= (unsigned int)DBGU_read;  // 인터럽트 처리 루틴
  AIC_ICCR = (1<<1);
  AIC_IECR = (1<<1);    // 인터럽트 활성화
  
  while(1)
  {
  }
  
  return 0;
// End Main....
// 일반적으로 시리얼 통신에서 데이터를 전송하는 시점은 정해져 있다. 반면 데이터를 수신하는 시점은 정해져 있는 것이 아니기때문에 인터럽트는 보통 RXRDY만을 사용한다.
// DBGU(디버그 유닛)은 System Controller로 장치 PID1를 사용한다.

 // 시리얼 통신으로 LED를 ON시키는 예제
//---------- 디버그 유닛 관련 I/O 제어 레지스터

#define DBGU_CR   (*(volatile unsigned int *) 0xFFFFF200)  // DBGU Control Register
#define DBGU_MR   (*(volatile unsigned int *) 0xFFFFF204)  // DBGU Mode Register
#define DBGU_IER  (*(volatile unsigned int *) 0xFFFFF208)  // DBGU Interrupt Enable Register
#define DBGU_IDR  (*(volatile unsigned int *) 0xFFFFF20C)  // DBGU Interrupt Disalbe Register
#define DBGU_IMR  (*(volatile unsigned int *) 0xFFFFF210)  // DBGU Interrupt Disalbe Register
#define DBGU_SR   (*(volatile unsigned int *) 0xFFFFF214)  // DBGU Status Register
#define DBGU_RHR  (*(volatile unsigned int *) 0xFFFFF218)  // DBGU Receive Holding Register
#define DBGU_THR  (*(volatile unsigned int *) 0xFFFFF21C)  // DBGU Transmit Holding Register
#define DBGU_BRGR (*(volatile unsigned int *) 0xFFFFF220)  // DBGU Baud Rate Generator Register


//---------- 인터럽트 제어기 IO설정 

#define AIC_IECR (*(volatile unsigned int *) 0xFFFFF120)  // 인터럽트 허 용 레지스터
#define AIC_IDCR (*(volatile unsigned int *) 0xFFFFF124)  // 인터럽트 금지 레지스터
#define AIC_ICCR (*(volatile unsigned int *) 0xFFFFF128)  // 인터럽트 클리어 레지스터
#define AIC_ISCR (*(volatile unsigned int *) 0xFFFFF12C)  // 인터럽트 세트 레지스터
#define AIC_SMR  ((volatile unsigned int *) 0xFFFFF000)    // AIC 소스 모드 레지스터
#define AIC_SVR  ((volatile unsigned int *) 0xFFFFF080)    // AIC 소 스 벡터 레지스터


//---------- 입출 력 IO설정 


#define PIO_PUDR (*(volatile unsigned int *) 0xFFFFF460)  // PIO Pull-Up Disable Register
#define PIO_PUER (*(volatile unsigned int *) 0xFFFFF464)  // PIO Pull-Up Enable Register

#define PIO_IER  (*(volatile unsigned int *) 0xFFFFF440)  // PIO Interrupt Enable Register
#define PIO_IDR  (*(volatile unsigned int *) 0xFFFFF444)  // PIO Interrupt Disable Register
#define PIO_IMR  (*(volatile unsigned int *) 0xFFFFF448)  // PIO Interrupt Mask Register
#define PIO_ISR  (*(volatile unsigned int *) 0xFFFFF44C)  // PIO Interrupt Status Register

#define PIO_ASR  (*(volatile unsigned int *) 0xFFFFF470)  // PIO Peripheral A Select Register
#define PIO_BSR  (*(volatile unsigned int *) 0xFFFFF474)  // PIO Peripheral B Select Register

#define PIO_IFER (*(volatile unsigned int *) 0xFFFFF420)  // PIO Glitch Input Filter Enable Register
#define PIO_IFDR (*(volatile unsigned int *) 0xFFFFF424)  // PIO Glitch Input Filter Disable Register

#define PIO_SODR (*(volatile unsigned int *) 0xFFFFF430) //출력 
#define PIO_CODR (*(volatile unsigned int *) 0xFFFFF434) //출력 하지 않음
#define PIO_OER  (*(volatile unsigned int *) 0xFFFFF410) //출력 방향 설정
#define PIO_ODR  (*(volatile unsigned int *) 0xFFFFF414) //출력 방향 설정
#define PIO_PER  (*(volatile unsigned int *) 0xFFFFF400) //병렬 입출력 제 어 레지스터 병렬 입출력 포트로 사용한다.
#define PIO_PDR  (*(volatile unsigned int *) 0xFFFFF404) //병렬 입출력 제어 레지스터 병렬 입출력 포트로 사용한다.


//---------- 전력 제어 설정

#define PMC_PCER (*(volatile unsigned int *) 0xFFFFFC10)
#define PMC_PCDR (*(volatile unsigned int *) 0xFFFFFC14)

 
#define MASTERCLOCK 48000000
#define INTERR    0x00000100
#define LED      0x00000010 

//--------- 전역 변수
char data[20];
int index = 0;

void Delayms(unsigned int ms) //딜레이 함수..

  volatile unsigned int count, countmax = (MASTERCLOCK / 10000) * ms;

  for(count = 0; count < countmax; count++);
}

int atoi(char *c)      // Charter to Integer
{
  int result = 0;
  int val = 1;
  int i;
  char *tmp = c;

  while(*tmp != '\0')
  {
    val *= 10;
    tmp++;
  }

  tmp = c;
  for(i = (val / 10) ; 1 <= i ; i /= 10)
  {
    result += ((*tmp - 48) * i);
    tmp++;
  }

  return result;
}

void LED_Decode()    // 신 호 decode
{
  int num;
  num = atoi(data);
  
  switch(num)
  {
    case 1:
      PIO_CODR = 0xFF;
      break;
    case 10:
      PIO_CODR = 0xFF;
      PIO_SODR = 0x1;
      break;
    case 100:
      PIO_CODR = 0xFF;
      PIO_SODR = 0x3;
      break;
    case 1000:
      PIO_CODR = 0xFF;
      PIO_SODR = 0x7;
      break;      
    default:
      break;
  }      
}

void DBGU_write(char d)    // 송신 함수
{
  while(0 == (DBGU_SR & 0x0002));
  DBGU_THR = d;
}

void DBGU_read()    // 수 신 함수
{
  char buf;
  buf = DBGU_RHR;
  
  if(buf != '\r')
  {
    data[index++] = buf;
  }
  else
  {
    data[index] = '\0';
    index = 0;
    LED_Decode();
  }
}

int main(void)
{  
  // PMC setting
  PMC_PCER = (unsigned int)1 << 2;    // PMC_PCER = (unsigned int)1 << 2;

  DBGU_CR = (1<<2)|(1<<3);      // 송수신부 리셋 및 금지
  AIC_IDCR = (1<<1);          //인터럽트 금지
  
  // PIO setting
  PIO_PER = 0xFF;        // Pin0 ~ Pin7 병렬포트 사용
  PIO_OER = 0xFF;        // Pin0 ~ Pin7 출력으로 설정
  PIO_PDR = (1<<9)|(1<<10);  // 병렬 포트 사용 금지
  PIO_ASR = (1<<9)|(1<<10);  // 장치 A 사용
  PIO_BSR = 0;        // 장치 B 사용 금지

  // DBGU setting
  DBGU_IER = (1 << 0);    // RXRDY enable
  DBGU_MR = (1<<11);      // Parity 사용하 지 않음
  DBGU_BRGR = 313;      // Baud rate = 9600
  DBGU_CR = (1<<6)|(1<<4);  // tx, rx enable
  
  // AIC setting.
  AIC_SMR[1= (1<<5)|(1<<6)|(1<<2)|(1<<0);  // Positive edge trigger, Prior = 5
  AIC_SVR[1= (unsigned int)DBGU_read;    // 인터럽트 처리 루틴
  AIC_ICCR = (1<<1);
  AIC_IECR = (1<<1);      // 인터럽트 활성화
  
  while(1)
  {

  }
  
  return 0;
// End Main....
// PC 터미널에서 각각 1, 10, 100, 1000을 입력하고 Enter를 입력하면 LED를 ON,OFF 시킨다.
// 1 : 모든 LED OFF / 10 : LED 1개 ON / 100 : LED 2개 ON / 1000 : LED 3개 ON
// 이 예제는 전역 변수를 여러 함수가 공유하고 있다. 이는 공유데이터 문제를 야기할 수 있다. 하나의 함수가 공유 데이터를 사용하고 있는 도중에 다른 함수가 그 값을 바꾸면 문제가 발생한다.

   시리얼 통신

 ECHO 예제
//---------- 디버그 유닛 관련 I/O 제어 레지스터

#define DBGU_CR   (*(volatile unsigned int *) 0xFFFFF200)  // DBGU Control Register
#define DBGU_MR   (*(volatile unsigned int *) 0xFFFFF204)  // DBGU Mode Register
#define DBGU_IER  (*(volatile unsigned int *) 0xFFFFF208)  // DBGU Interrupt Enable Register
#define DBGU_IDR  (*(volatile unsigned int *) 0xFFFFF20C)  // DBGU Interrupt Disalbe Register
#define DBGU_IMR  (*(volatile unsigned int *) 0xFFFFF210)  // DBGU Interrupt Disalbe Register
#define DBGU_SR   (*(volatile unsigned int *) 0xFFFFF214)  // DBGU Status Register
#define DBGU_RHR  (*(volatile unsigned int *) 0xFFFFF218)  // DBGU Receive Holding Register
#define DBGU_THR  (*(volatile unsigned int *) 0xFFFFF21C)  // DBGU Transmit Holding Register
#define DBGU_BRGR (*(volatile unsigned int *) 0xFFFFF220)  // DBGU Baud Rate Generator Register


//---------- 인터럽트 제어기 IO설정 

#define AIC_IECR (*(volatile unsigned int *) 0xFFFFF120)  // 인터럽트 허용 레지스터
#define AIC_IDCR (*(volatile unsigned int *) 0xFFFFF124)  // 인터럽트 금지 레지스터
#define AIC_ICCR (*(volatile unsigned int *) 0xFFFFF128)  // 인터럽트 클리어 레지스터
#define AIC_ISCR (*(volatile unsigned int *) 0xFFFFF12C)  // 인터럽트 세트 레지스터
#define AIC_SMR  ((volatile unsigned int *) 0xFFFFF000)    // AIC 소스 모드 레지스터
#define AIC_SVR  ((volatile unsigned int *) 0xFFFFF080)    // AIC 소스 벡터 레지스터


//---------- 입출력 IO설정 


#define PIO_PUDR (*(volatile unsigned int *) 0xFFFFF460)  // PIO Pull-Up Disable Register
#define PIO_PUER (*(volatile unsigned int *) 0xFFFFF464)  // PIO Pull-Up Enable Register

#define PIO_IER  (*(volatile unsigned int *) 0xFFFFF440)  // PIO Interrupt Enable Register
#define PIO_IDR  (*(volatile unsigned int *) 0xFFFFF444)  // PIO Interrupt Disable Register
#define PIO_IMR  (*(volatile unsigned int *) 0xFFFFF448)  // PIO Interrupt Mask Register
#define PIO_ISR  (*(volatile unsigned int *) 0xFFFFF44C)  // PIO Interrupt Status Register

#define PIO_ASR  (*(volatile unsigned int *) 0xFFFFF470)  // PIO Peripheral A Select Register
#define PIO_BSR  (*(volatile unsigned int *) 0xFFFFF474)  // PIO Peripheral B Select Register

#define PIO_IFER (*(volatile unsigned int *) 0xFFFFF420)  // PIO Glitch Input Filter Enable Register
#define PIO_IFDR (*(volatile unsigned int *) 0xFFFFF424)  // PIO Glitch Input Filter Disable Register

#define PIO_SODR (*(volatile unsigned int *) 0xFFFFF430) //출력 
#define PIO_CODR (*(volatile unsigned int *) 0xFFFFF434) //출력 하지 않음
#define PIO_OER  (*(volatile unsigned int *) 0xFFFFF410) //출력 방향 설정
#define PIO_ODR  (*(volatile unsigned int *) 0xFFFFF414) //출력 방향 설정
#define PIO_PER  (*(volatile unsigned int *) 0xFFFFF400) //병렬 입출력 제어 레지스터 병렬 입출력 포트로 사용한다.
#define PIO_PDR  (*(volatile unsigned int *) 0xFFFFF404) //병렬 입출력 제어 레지스터 병렬 입출력 포트로 사용한다.


//---------- 전력 제어 설정

#define PMC_PCER (*(volatile unsigned int *) 0xFFFFFC10)
#define PMC_PCDR (*(volatile unsigned int *) 0xFFFFFC14)

 
#define MASTERCLOCK 48000000
#define INTERR    0x00000100
#define LED      0x00000010 

//--------- 전역 변수

void Delayms(unsigned int ms) //딜레이 함수..

  volatile unsigned int count, countmax = (MASTERCLOCK / 10000) * ms;

  for(count = 0; count < countmax; count++);
}

void DBGU_write(char d)  // 송신 함수
{
  while(0 == (DBGU_SR & 0x0002));
  DBGU_THR = d;
}

unsigned char DBGU_read()  // 수신 함수
{
  while(0 == (DBGU_SR & 0x0001));
  return DBGU_RHR;
}

int main(void)
{
  unsigned char data;
  
  // PMC setting
  PMC_PCER = (unsigned int)1 << 2;    // PMC_PCER = (unsigned int)1 << 2;

  DBGU_CR = (1<<2)|(1<<3);      // 송수신부 리셋 및 금지
    
  // PIO setting
  PIO_PDR = (1<<9)|(1<<10);  // 병렬 포트 사용 금지
  PIO_ASR = (1<<9)|(1<<10);  // 장치 A 사용
  PIO_BSR = 0;        // 장치 B 사용 금지

  // DBGU setting
  DBGU_MR = (1<<11);      // Parity 사용하지 않음
  DBGU_BRGR = 313;      // Baud rate = 9600
  DBGU_CR = (1<<6)|(1<<4);  // tx, rx enable

  while(1)
  {
    data = DBGU_read();
    DBGU_write(data);
  }
  
  return 0;
// End Main....

// DBGU를 이용하여 간단한 시리얼 통신을 해보았다. PC 터미널에서 신호를 날리면 그 신호가 그대로 다시 돌아와서 PC 터미널에 찍히게 된다.

 // 정수형 데이터를 문자로 변환하여 전송하는 프로그램
//---------- 디버그 유닛 관련 I/O 제어 레지스터

#define DBGU_CR   (*(volatile unsigned int *) 0xFFFFF200)  // DBGU Control Register
#define DBGU_MR   (*(volatile unsigned int *) 0xFFFFF204)  // DBGU Mode Register
#define DBGU_IER  (*(volatile unsigned int *) 0xFFFFF208)  // DBGU Interrupt Enable Register
#define DBGU_IDR  (*(volatile unsigned int *) 0xFFFFF20C)  // DBGU Interrupt Disalbe Register
#define DBGU_IMR  (*(volatile unsigned int *) 0xFFFFF210)  // DBGU Interrupt Disalbe Register
#define DBGU_SR   (*(volatile unsigned int *) 0xFFFFF214)  // DBGU Status Register
#define DBGU_RHR  (*(volatile unsigned int *) 0xFFFFF218)  // DBGU Receive Holding Register
#define DBGU_THR  (*(volatile unsigned int *) 0xFFFFF21C)  // DBGU Transmit Holding Register
#define DBGU_BRGR (*(volatile unsigned int *) 0xFFFFF220)  // DBGU Baud Rate Generator Register


//---------- 인터럽트 제어기 IO설정 

#define AIC_IECR (*(volatile unsigned int *) 0xFFFFF120)  // 인터럽트 허 용 레지스터
#define AIC_IDCR (*(volatile unsigned int *) 0xFFFFF124)  // 인터럽트 금지 레지스터
#define AIC_ICCR (*(volatile unsigned int *) 0xFFFFF128)  // 인터럽트 클리어 레지스터
#define AIC_ISCR (*(volatile unsigned int *) 0xFFFFF12C)  // 인터럽트 세트 레지스터
#define AIC_SMR  ((volatile unsigned int *) 0xFFFFF000)    // AIC 소스 모드 레지스터
#define AIC_SVR  ((volatile unsigned int *) 0xFFFFF080)    // AIC 소 스 벡터 레지스터


//---------- 입출 력 IO설정 


#define PIO_PUDR (*(volatile unsigned int *) 0xFFFFF460)  // PIO Pull-Up Disable Register
#define PIO_PUER (*(volatile unsigned int *) 0xFFFFF464)  // PIO Pull-Up Enable Register

#define PIO_IER  (*(volatile unsigned int *) 0xFFFFF440)  // PIO Interrupt Enable Register
#define PIO_IDR  (*(volatile unsigned int *) 0xFFFFF444)  // PIO Interrupt Disable Register
#define PIO_IMR  (*(volatile unsigned int *) 0xFFFFF448)  // PIO Interrupt Mask Register
#define PIO_ISR  (*(volatile unsigned int *) 0xFFFFF44C)  // PIO Interrupt Status Register

#define PIO_ASR  (*(volatile unsigned int *) 0xFFFFF470)  // PIO Peripheral A Select Register
#define PIO_BSR  (*(volatile unsigned int *) 0xFFFFF474)  // PIO Peripheral B Select Register

#define PIO_IFER (*(volatile unsigned int *) 0xFFFFF420)  // PIO Glitch Input Filter Enable Register
#define PIO_IFDR (*(volatile unsigned int *) 0xFFFFF424)  // PIO Glitch Input Filter Disable Register

#define PIO_SODR (*(volatile unsigned int *) 0xFFFFF430) //출력 
#define PIO_CODR (*(volatile unsigned int *) 0xFFFFF434) //출력 하지 않음
#define PIO_OER  (*(volatile unsigned int *) 0xFFFFF410) //출력 방향 설정
#define PIO_ODR  (*(volatile unsigned int *) 0xFFFFF414) //출력 방향 설정
#define PIO_PER  (*(volatile unsigned int *) 0xFFFFF400) //병렬 입출력 제 어 레지스터 병렬 입출력 포트로 사용한다.
#define PIO_PDR  (*(volatile unsigned int *) 0xFFFFF404) //병렬 입출력 제어 레지스터 병렬 입출력 포트로 사용한다.


//---------- 전력 제어 설정

#define PMC_PCER (*(volatile unsigned int *) 0xFFFFFC10)
#define PMC_PCDR (*(volatile unsigned int *) 0xFFFFFC14)

 
#define MASTERCLOCK 48000000
#define INTERR    0x00000100
#define LED      0x00000010 

//--------- 전역 변수

void Delayms(unsigned int ms) //딜레이 함 수..

  volatile unsigned int count, countmax = (MASTERCLOCK / 10000) * ms;

  for(count = 0; count < countmax; count++);
}

void DBGU_write(char *d)    // 문자열 송신 함수
{
  while(0 != *d)
  {
    while(0 == (DBGU_SR & 0x0002));
    DBGU_THR = *d;
    ++d;
  }
}

unsigned char DBGU_read()    // 수신 함수
{
  while(0 == (DBGU_SR & 0x0001));
  return DBGU_RHR;
}

void intToChar(char *buf, int num)  // int 형을 Char형으로 변환
{
  int i, j;
  int target;    // 각 자 리수
  int value = 1;  // 숫자 크기 확인
  
  while(value < num)
  {
    value *= 10;
  }  
  
  for(i = 0, j = value/10 ; j >= 10 ; j /= 10)
  {
    target = num / j;
    num = num % j;
    buf[i++] = target + 48;    // buf에 문자값 저장
  }
  buf[i++] = num + 48;
  buf[i] = '\0';
}

int main(void)
{
  int num = 0;
  char buf[20];
  
  // PMC setting
  PMC_PCER = (unsigned int)1 << 2;    // PMC_PCER = (unsigned int)1 << 2;

  DBGU_CR = (1<<2)|(1<<3);      // 송수신부 리셋 및 금지  
  
  // PIO setting
  PIO_PDR = (1<<9)|(1<<10);  // 병렬 포트 사용 금지
  PIO_ASR = (1<<9)|(1<<10);  // 장치 A 사용
  PIO_BSR = 0;        // 장치 B 사용 금지

  // DBGU setting
  DBGU_MR = (1<<11);      // Parity 사용하 지 않음
  DBGU_BRGR = 313;      // Baud rate = 9600
  DBGU_CR = (1<<6)|(1<<4);  // tx, rx enable

  intToChar(buf, num);
  
  while(1)
  {
    intToChar(buf, num++);
    DBGU_write(buf);
    if(num == 9)
      num = 0;
  }
  
  return 0;
// End Main....
// 정수형을 문자로 전송하기 위해서 intToChar함수를 따로 작성하였다. 송신 함수도 문자열을 전송할 수 있게 수정하였다.


+ Recent posts