Busan IT/AVR 컨트롤러2015. 4. 21. 12:38

타이머를  활용한 7-segment count up


학습목표

- 내부 타이머와 인터럽트를 활용하여 1초에 한번 숫자가 올라가는 카운트 업 회로와 코드를 만들 수 있다.


타이머(timer)와 카운터(counter)의 차이

타이머는 주로 컴퓨터 내부 클록(clock)을 사용하고, 카운터는 외부 클록을 사용한다.

 

<타이머>

타이머는 작동 방식은 주어진 비트 수의 최대숫자까지를 클록을 활용한 신호로 숫자를 센 다음에 최대자리수를 초과한 수가 되면 0으로 다시 초기화되면서 내부 인터럽트(interrupt)를 발생시킨다.

 

*** 1초 내부 카운터를 만들어 보기 ***

 

우리가 사용하는 ATmega256016MHz이다. 이 말은 1초에 16000000번의 클럭이 나온다는 것이다. 1번의 클럭이 나오는 시간을 계산해 보면,

1/16000000 = 0.0000000625

알아보기 쉽게 하기 위하여,

0.0000000625 * 1000 = 0.0000625ms(밀리 세컨)

0.0000625 * 1000 = 0.0625us(마이크로 세컨)

0.0625 * 1000 = 62.5ns(나노 세컨)

 

여기에 분주비(pre-scaler)1024로 설정하고 8bit임으로 카운터가 256까지 가능함으로,

 

62.5ns * 1024(분주비) * 256(8비트 카운터) = 0.016384

 

이것을 일초로 한번 카운터를 하려면,

 

1/0.016384 = 61.03515625 에 한번 카운터가 작동하게 해야 한다다.

 

지난 시간에 사용했던 코드에 이 숫자를 사용하여 카운터가 1초인지 확인해 보자!

 

I. 서술

 

내부 인터럽트가 0.016384만에 한번 일어나는 것을 착안하여. 1초에 한번 LED에 불을 켜기 위해서는 카운터를 활용하여 내부 인터럽트가 31(61/2)번 발생할 때 발생할 때 LED에 값을 반전 시키면 불이 1초마다 한 번씩 들어오게 된다.

 

주의할 점은 interrupt안에 카운터 변수 값을 초기화해주는 명령어를 넣으면 카운터가 올라가지 않기 때문에 전역변수로 선언하여 카운터를 올려야 한다.

 

II. 코딩

1. 지난 번에 사용했던 코드에서 인터럽트 안에 카운터를 사용하여 1초에 한번 불이 들어오도록 카운터 값을 31로 넣어준다.

 

/*** 코드 ***/

<main.c>

#include <atm2560.h>
#include "SMART.h"

unsigned char LED=0xFF;
volatile unsigned int uiCnt;
unsigned char ucCnt=0;

int main(void)
{
  /*** 포트 설정 ***/

  DDRC = 0xFF;
  PORTC = LED;
  unsigned char ucCnt=0;
  


  /*** 타이머 카운터를 위한 설정 ***/

  SREG &= 0x7F;  //Global interrupt
  TIMSK0 = 0x01;  //Timer 0 overflow
  TCCR0A = 0x00;  //Timer Mode : 일반 모드
  TCCR0B = 0x05;  //분주비 1024
  TCNT0 = 0x00;  //Timer Counter 초기화
  SREG |= 0x80;  //Global Interrupt 
  
  while(1)
  {

    ;
    /*for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    
    while(TCNT0!=0);*/

          
  }
  
  return 0;
}

void __vector_23(void)
{    
    ++ucCnt;

    if(ucCnt==31)
    {
      LED ^= 0xFF;
      PORTC = LED;
      ucCnt=0;
    }
}

<smart.h>

#ifndef __SMART_H__
#define __SMART_H__

/**** General Purpose Register A - L ****/

#define  PORTA (*((volatile unsigned char*)0x22))
#define   DDRA  (*((volatile unsigned char*)0x21))
#define   PINA  (*((volatile unsigned char*)0x20))

#define  PORTB (*((volatile unsigned char*)0x25))
#define   DDRB  (*((volatile unsigned char*)0x24))
#define   PINB  (*((volatile unsigned char*)0x23))

#define  PORTC (*((volatile unsigned char*)0x28))
#define   DDRC  (*((volatile unsigned char*)0x27))
#define   PINC  (*((volatile unsigned char*)0x26))

#define  PORTD (*((volatile unsigned char*)0x2B))
#define   DDRD  (*((volatile unsigned char*)0x2A))
#define   PIND  (*((volatile unsigned char*)0x29))

#define  PORTE (*((volatile unsigned char*)0x2E))
#define   DDRE  (*((volatile unsigned char*)0x2D))
#define   PINE  (*((volatile unsigned char*)0x2C))

#define  PORTF (*((volatile unsigned char*)0x31))
#define   DDRF  (*((volatile unsigned char*)0x30))
#define   PINF  (*((volatile unsigned char*)0x2F))

#define  PORTG (*((volatile unsigned char*)0x34))
#define   DDRG  (*((volatile unsigned char*)0x33))
#define   PING  (*((volatile unsigned char*)0x32))

#define  PORTH (*((volatile unsigned char*)0x102))
#define   DDRH  (*((volatile unsigned char*)0x101))
#define   PINH  (*((volatile unsigned char*)0x100))

#define  PORTJ (*((volatile unsigned char*)0x105))
#define   DDRJ  (*((volatile unsigned char*)0x104))
#define   PINJ  (*((volatile unsigned char*)0x103))

#define  PORTK (*((volatile unsigned char*)0x108))
#define   DDRK  (*((volatile unsigned char*)0x107))
#define   PINK  (*((volatile unsigned char*)0x106))

#define  PORTL (*((volatile unsigned char*)0x10B))
#define   DDRL  (*((volatile unsigned char*)0x10A))
#define   PINL  (*((volatile unsigned char*)0x109))


/* 인터럽트 사용을 위한 레지스터 */

#define EICRA (*((volatile unsigned char*)0x69))
#define EICRB (*((volatile unsigned char*)0x6A))
#define EIMSK (*((volatile unsigned char*)0x3D))
#define EIFR  (*((volatile unsigned char*)0x3C))
#define SREG (*((volatile unsigned char*)0x5F)) 

/* PCINT 사용을 위한 레지스터 */

#define PCICR (*((volatile unsigned char*)0x68))
#define PCIFR (*((volatile unsigned char*)0x3B))
#define PCMSK2 (*((volatile unsigned char*)0x6D))
#define PCMSK1 (*((volatile unsigned char*)0x6C))
#define PCMSK0 (*((volatile unsigned char*)0x6B))

/* 타이머 오버 플로우 */

// General Timer/counter Control Register
#define GTCCR (*((volatile unsigned char*)0x43)) 

// Register for Timer/Counter 0
#define OCR0A   (*((volatile unsigned char*)0x47)) // 타이머 카운터 비교 레지스터
#define OCR0B   (*((volatile unsigned char*)0x48))
#define TCCR0A   (*((volatile unsigned char*)0x44))
#define TCCR0B   (*((volatile unsigned char*)0x45))
#define TCNT0   (*((volatile unsigned char*)0x46))
#define TIFR0   (*((volatile unsigned char*)0x35))
#define TIMSK0   (*((volatile unsigned char*)0x6E))


/* CPU 동작시간을 맞춰주기 위한 Dealy문과 값 지정 */

#define  Delay(x)    for(uiCnt=0; uiCnt<(dNum1); ++uiCnt)

#define  dNum1 50000
#define  dNum2 300000
#define  dNum3 10000000

/* 함수의 원형 */

void __vector_23(void)__attribute__((signal,used,externally_visible));


#endif //__SMART_H__



해당 코드를 완성하였으면 FND를 활용하여 시계를 만들어 보자!


I. 서술

예전에 짜 놓았던 7segment카운트 업 코드를 삽입하여 1초에 1번씩 올라가는 카운터에 맞춰 시계를 만들어 보자.


II. 작업 나누기

0. 우선 새로운 소일거리를 위한 새로운 폴더를 만든다.

- 코드

- 회로

1. 과거에 짜 놓았던 7segment 코딩을 넣어 붙힌다.

2. 내부 인터럽트가 발생하면 FND가 1씩 증가하고 0이 되면 다시 리셋이 되는 코드를 넣어준다.

4. 프로테우스로 회로를 작성하여 해당 코드를 넣고 작동하는지 확인한다.

3. 프로테우스에서 작동된 것이 확인 되면 브레드보드와 7segment에 연결하여 작동하는지 확인한다.



/*** 코드 ***/

#include <atm2560.h>
#include "SMART.h"

unsigned char FND[10= {0x400x790x240x300x190x120x020x580x000x10};
volatile unsigned int uiCnt;
unsigned char ucCnt=0, ucCnt2=0;

int main(void)
{
  /*** 포트 설정 ***/

  DDRC = 0xFF;
  PORTC = 0xFF;

  /*** 타이머 카운터를 위한 설정 ***/

  SREG &= 0x7F;  //Global interrupt
  TIMSK0 = 0x01;  //Timer 0 overflow
  TCCR0A = 0x00;  //Timer Mode : 일반 모드
  TCCR0B = 0x05;  //분주비 1024
  TCNT0 = 0x00;  //Timer Counter 초기화
  SREG |= 0x80;  //Global Interrupt 
  
  while(1)
  {

    ;
          
  }
  
  return 0;
}

void __vector_23(void)
{    
    ++ucCnt;

    if(ucCnt==61)
    {
      PORTC=FND[ucCnt2%10];
      ++ucCnt2;
      ucCnt=0;
      if(ucCnt2==250)
        ucCnt2=0;
    }
}


 



반응형
Posted by newind2000
Busan IT/공장내 Network2015. 4. 20. 17:49

다중 포인터 & 라즈베리파이 사용자 계정으로 root계정 변환

 

학습목표

 

- 다중 포인터의 문법과 내용을 이해한다.

- 라즈베리파이의 사용자 계정을 root계정으로 변환 시킬 수 있다.


더블 포인터를 활용한 포인터 값의 변환

지난 시간 수업 내용과 동일. 

자세한 내용은 교재 참조.


라즈베리 파이 명령어

//chown, chgrp ??? 이야기만 꺼내고 설명은 하지 않은 명령어

// chown: 파일과 디렉토리의 소유주와 소유그룹 변경 ex) chown 파일명 권한


계정 바꾸기: su - 계정

관리자 계정으로 바꾸기: su -

맨 밑에서 아랫줄

newind2000(id):x(비밀번호 표시 안함):0(계정번호, root=0):0(그룹번호, root=0):,,,(계정과 관련한 신상정보):/home/newind2000(시작 경로):/bin/bash(사용하는 쉘)

 

운영체제의 핵심을 커널(kenel)이라 부르고 그 주위를 함수 또는 명령어로 쌓여져 있고 그 주변을 쉘이 감싸고 있어 커널을 이용하려면 함수 또는 명령어 아니면 쉘로 접근 가능하다.

 

//bash(bone again shell)

 

//hash함수는 인자와 결과 값이 중복되지 않고 하나의 값만 갖는 함수

 

비밀번호가 저장된 파일을 여는 명령어: sudo -nano /etc/shadow

비밀번호가 암호화 된 형태로 적혀있다


nano /etc/group 입력 후 자신의 아이디가 있는 자리의 정보를 삭제해준다.

저장 후 나온다.

 

Ctrl + D로 로그 아웃 후

 

su - 자신의 아이디 를 치면 root계정으로 이동하는 것을 알 수 있다.

짜잔!


반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 20. 13:35

타이머/카운터

 

학습목표 - 타이머 오버플로우에 관련한 레지스터들에 대해 이해하고 코딩을 할 수 있다.

 

타이머 오버플로우를 이용하여 코딩을 해보자.

 

p/176, 타이머/카운터 일반 제어 레지스터(GTCCR)

 

GTCCR(general Timer/Counter Control register)

0,1 그리고 7번 비트를 사용하는데 비트 7TSM(Timer/Counter Synchronization Mode)은 모든 타이머/카운터들을 동기화시키는 기능을 수행한다. , 이를 1로 하면 PSRASY PSRSYNC 비트에 라이트한 값을 유지하여 이에 대응하는 프리스케일러 리셋 신호를 발생하고, 이는 해당 타이머/카운터의 동작을 정지시켜 이것들을 똑같은 초기값으로 설정할 수 있도록 해준다.

 

//동기와 비동기의 차이. 내부 클럭을 같이 쓰면 - 동기식, 내부 클럭을 같이 쓰지 않으면 - 비동기식

 

OCR0A/OCR0B

 

TCCR0A/TCCR0B


AVR교재, p/175 참조TCCR일반모드 사용

 

TCNT0

 

타이머카운터 값을 저장하고 있는 레지스터

동작 중에 수정을 하면 안된다. 비교 매치 기능에 문제가 발생할 수 있음으로 동작 중에 수정하면 안된다.

 

TIFR0

 

TIMSK0

타이머 인터럽트 마스크 레지스터

타이머의 속도를 맞추고 싶으면 TCCR0nTCNTn을 조절하면 된다.

 

전자시계의 내부 타이머를 제대로 맞춰주지 않은 경우에 후에 시간차가 나게 된다.

 

 

I. 서술

 

타이머 카운터를 작동시키는 코드를 작성해 보자. ATmega2560을 활용한다. 우선 코딩을 한 후 해당 포트에 high/low 값이 어떻게 출력되는지 살펴보자.

 

우리가 사용하는 클럭은 16MHz(0.0000000625s)이고 이것은 62.5ms이다. 카운터가 0 - 255가 되었을 때 overflow가 발생하기 때문에 0.000016가 걸린다. 1초에 한번 이것을 작동 시키기 위해서는 62500번 이것이 작동한 후 카운터가 되는 알고리즘을 만들어 주어야 한다.

 

II. 코딩 나누기

 

1. 타이머/카운터과 관련된 레지스터들의 설정 방법을 알아보고 원하는 방식으로 설정해준다.

 

2. 1초에 한번 카운터를 맞추기 위해 클럭속도를 계산하여 지연 코딩을 해준다.

 

 

 

 

 

III. 코드

 

/*** main.c ***/

#include <atm2560.h>
#include "SMART.h"

unsigned char LED=0xFF;
volatile unsigned int uiCnt;

int main(void)
{
  /*** 포트 설정 ***/

  DDRC = 0xFF;
  PORTC = LED;
  


  /*** 타이머 카운터를 위한 설정 ***/

  SREG &= 0x7F;  //Global interrupt
  TIMSK0 = 0x01;  //Timer 0 overflow
  TCCR0A = 0x00;  //Timer Mode : 일반 모드
  TCCR0B = 0x05;  //분주비 1
  TCNT0 = 0x00;  //Timer Counter 초기화
  SREG |= 0x80;  //Global Interrupt 
  
  while(1)
  {
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    for(uiCnt=0; uiCnt<62500; ++uiCnt)
      TCNT0 = 0x01;
    
    while(TCNT0!=0);
          
  }
  
  return 0;
}

void __vector_23(void)
{    
    LED ^= 0xFF;
    PORTC = LED;
}

 

/*** SMART.h ***/

#ifndef __SMART_H__
#define __SMART_H__

/**** General Purpose Register A - L ****/

#define  PORTA (*((volatile unsigned char*)0x22))
#define   DDRA  (*((volatile unsigned char*)0x21))
#define   PINA  (*((volatile unsigned char*)0x20))

#define  PORTB (*((volatile unsigned char*)0x25))
#define   DDRB  (*((volatile unsigned char*)0x24))
#define   PINB  (*((volatile unsigned char*)0x23))

#define  PORTC (*((volatile unsigned char*)0x28))
#define   DDRC  (*((volatile unsigned char*)0x27))
#define   PINC  (*((volatile unsigned char*)0x26))

#define  PORTD (*((volatile unsigned char*)0x2B))
#define   DDRD  (*((volatile unsigned char*)0x2A))
#define   PIND  (*((volatile unsigned char*)0x29))

#define  PORTE (*((volatile unsigned char*)0x2E))
#define   DDRE  (*((volatile unsigned char*)0x2D))
#define   PINE  (*((volatile unsigned char*)0x2C))

#define  PORTF (*((volatile unsigned char*)0x31))
#define   DDRF  (*((volatile unsigned char*)0x30))
#define   PINF  (*((volatile unsigned char*)0x2F))

#define  PORTG (*((volatile unsigned char*)0x34))
#define   DDRG  (*((volatile unsigned char*)0x33))
#define   PING  (*((volatile unsigned char*)0x32))

#define  PORTH (*((volatile unsigned char*)0x102))
#define   DDRH  (*((volatile unsigned char*)0x101))
#define   PINH  (*((volatile unsigned char*)0x100))

#define  PORTJ (*((volatile unsigned char*)0x105))
#define   DDRJ  (*((volatile unsigned char*)0x104))
#define   PINJ  (*((volatile unsigned char*)0x103))

#define  PORTK (*((volatile unsigned char*)0x108))
#define   DDRK  (*((volatile unsigned char*)0x107))
#define   PINK  (*((volatile unsigned char*)0x106))

#define  PORTL (*((volatile unsigned char*)0x10B))
#define   DDRL  (*((volatile unsigned char*)0x10A))
#define   PINL  (*((volatile unsigned char*)0x109))


/* 인터럽트 사용을 위한 레지스터 */

#define EICRA (*((volatile unsigned char*)0x69))
#define EICRB (*((volatile unsigned char*)0x6A))
#define EIMSK (*((volatile unsigned char*)0x3D))
#define EIFR  (*((volatile unsigned char*)0x3C))
#define SREG (*((volatile unsigned char*)0x5F)) 

/* PCINT 사용을 위한 레지스터 */

#define PCICR (*((volatile unsigned char*)0x68))
#define PCIFR (*((volatile unsigned char*)0x3B))
#define PCMSK2 (*((volatile unsigned char*)0x6D))
#define PCMSK1 (*((volatile unsigned char*)0x6C))
#define PCMSK0 (*((volatile unsigned char*)0x6B))

/* 타이머 오버 플로우 */

// General Timer/counter Control Register
#define GTCCR (*((volatile unsigned char*)0x43)) 

// Register for Timer/Counter 0
#define OCR0A   (*((volatile unsigned char*)0x47)) // 타이머 카운터 비교 레지스터
#define OCR0B   (*((volatile unsigned char*)0x48))
#define TCCR0A   (*((volatile unsigned char*)0x44))
#define TCCR0B   (*((volatile unsigned char*)0x45))
#define TCNT0   (*((volatile unsigned char*)0x46))
#define TIFR0   (*((volatile unsigned char*)0x35))
#define TIMSK0   (*((volatile unsigned char*)0x6E))


/* CPU 동작시간을 맞춰주기 위한 Dealy문과 값 지정 */

#define  Delay(x)    for(uiCnt=0; uiCnt<(dNum1); ++uiCnt)

#define  dNum1 50000
#define  dNum2 300000
#define  dNum3 10000000

/* 함수의 원형 */

void __vector_23(void)__attribute__((signal,used,externally_visible));


#endif //__SMART_H__

 

 

반응형
Posted by newind2000
Busan IT/공장내 Network2015. 4. 17. 17:36

포인터와 3차원 배열

 

학습목표 - 포인터를 활용한 3차원 배열의 값과 주소를 알 수 있다.

 

배열에서의 교환법칙에 대하여 배워본다.

ex) A[2]; 2[A]; 의 값은 같다.

p/346 2차원 배열 예제

 

배열에 값을 넣지 않을 때 빈자리는 0으로 채워짐을 알 수 있다.

 

 

 

 

p/351 삼차원 배열 예제

 

 

 

p/358 Ch. 17. 포인터의 포인터에 대한 이해

 

포인터 변수를 선언할 때 쓰인 별의 수만큼 별을 삽입하여 사용할 수 있다.

p/359 예제

 

 

p/361 예제

p/361 예제

라즈베리파이 회로도 훑어보기

 

https://www.raspberrypi.org/model-b-revision-2-0-schematics/



반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 17. 13:45

다중 인터럽트를 활용한 카운트 업/다운

 

학습목표 - 다중 인터럽트를 활용한 카운트 업/다운 회로를 만들 수 있다.

 

다중 인터럽트

 

2개 이상의 인터럽트를 만드는데 그 내용이 서로 상이하여 구분할 수 있게 만들어 보자.

INT0count down, INT4count up을 만든다.

 

 

I. 서술

 

사용한 코드(7segment digital roulette)에서 인터럽트(interrupt)를 추가적으로 하나 더 달아주고 INT0count down, INT4count up을 사용하자.

 

II. 덩어리 나누기

 

1. 인터럽트 추가

- INT0INT4를 쓴다.

- 설정 코딩은 전에 했던 것들을 복사해서 쓴다.

*입력은 PIN을 사용하는 것을 잊지 말자.

 

2. 추가한 인터럽트에 카운트 업, 카운트다운 코딩

- ++--를 사용하여 간단하게 카운트 업/다운을 해준다.

 

 

III. 회로를 만들어 주기

 



 

코딩한 내용을 프로테우스로 실행시켜 확인해 보자!

 

 

 

 

 

 

 

AVR 교재 p/139

 

(2) 인터럽트의 동작에서 SREG 레지스터의 글로벌 인터럽트 허용 비트가 잠정적으로 0으로 되었다가 인터럽트가 종료되면 다시 1로 복구되는데 이중 인터럽트를 허용하기 위해서는 인터럽트가 동작되자 마자 이 레지스터를 1로 설정해 주어야 한다.

 

인터럽트를 허용시키는 코드!

 

SREG |= 0x80//이중 인터럽트 허용 코드

 

코드의 아래와 같다.

 

/*** main.c ***/

#include <atm128.h>
//#include <avr/interrupt.h>
#include "SMART.h"

unsigned char ucCnt=50;
volatile unsigned int uiCnt;

int main(void)
{
  /*** 숫자 표시를 위한 FND 입력값 ***/

  unsigned char FND[10= {0x400x790x240x300x190x120x020x580x000x10};
  unsigned char ucCnt=0;

  /*** Delay를 위한 변수 입력 ***/

  volatile unsigned long uiCnt;

  /*** 사용할 PORT 설정 ***/

  DDRC  = 0xFF;  //PORT C 모두 출력 사용
  DDRD  = 0XFE;  //PORTD 1번 핀 입력 사용
  DDRE  = 0xEF;  //PORT E의 5번 핀 입력 사용 
  
    
  /*** 인터럽트 설정 ***/

  SREG &= 0x7F;  //interrupt disable, 설정 중 오동작을 막기 위해
  EICRA = 0X00;  //스위치의 트리거 방식 설정 - 하강 에지 방식 
  EICRB = 0x00;  //스위치의 트리거 방식 설정 - 하강 에지 방식 
  EIMSK = 0x11;  //외부 인터럽트 허용 레지스터 - 인터럽트 0 외부 인터럽트 허용 
  SREG |= 0x80
  
  while(1)
  {
    
    ;
          
  }
  
  return 0;
}

void __vector_1(void)
{
  /*** count down ***/
  unsigned char FND[10= {0x400x790x240x300x190x120x020x580x000x10};
  
  while(1)
  {
    SREG |= 0x80;
    PORTC = FND[ucCnt%10];
    Delay(2000);    
    --ucCnt;
    if(ucCnt==0x00|100)
      ucCnt==50;
      

    if(PIND==0x01)
      break;
  }

  

}
void __vector_5(void)
{
  /*** count up ***/
  unsigned char FND[10= {0x400x790x240x300x190x120x020x580x000x10};
  
  while(1)
  {
    SREG |= 0x80;
    PORTC = FND[ucCnt%10];
    Delay(2000);    
    ++ucCnt;

    if(ucCnt==0x00|100)
      ucCnt==50;

    if(PINE==0x10)
      break;


    
  }


}

 

 

/*** SMART.h ***/

#ifndef __SMART_H__
#define __SMART_H__

/**** General Purpose Register A - L ****/

#define  PORTA (*((volatile unsigned char*)0x22))
#define   DDRA  (*((volatile unsigned char*)0x21))
#define   PINA  (*((volatile unsigned char*)0x20))

#define  PORTB (*((volatile unsigned char*)0x25))
#define   DDRB  (*((volatile unsigned char*)0x24))
#define   PINB  (*((volatile unsigned char*)0x23))

#define  PORTC (*((volatile unsigned char*)0x28))
#define   DDRC  (*((volatile unsigned char*)0x27))
#define   PINC  (*((volatile unsigned char*)0x26))

#define  PORTD (*((volatile unsigned char*)0x2B))
#define   DDRD  (*((volatile unsigned char*)0x2A))
#define   PIND  (*((volatile unsigned char*)0x29))

#define  PORTE (*((volatile unsigned char*)0x2E))
#define   DDRE  (*((volatile unsigned char*)0x2D))
#define   PINE  (*((volatile unsigned char*)0x2C))

#define  PORTF (*((volatile unsigned char*)0x31))
#define   DDRF  (*((volatile unsigned char*)0x30))
#define   PINF  (*((volatile unsigned char*)0x2F))

#define  PORTG (*((volatile unsigned char*)0x34))
#define   DDRG  (*((volatile unsigned char*)0x33))
#define   PING  (*((volatile unsigned char*)0x32))

#define  PORTH (*((volatile unsigned char*)0x102))
#define   DDRH  (*((volatile unsigned char*)0x101))
#define   PINH  (*((volatile unsigned char*)0x100))

#define  PORTJ (*((volatile unsigned char*)0x105))
#define   DDRJ  (*((volatile unsigned char*)0x104))
#define   PINJ  (*((volatile unsigned char*)0x103))

#define  PORTK (*((volatile unsigned char*)0x108))
#define   DDRK  (*((volatile unsigned char*)0x107))
#define   PINK  (*((volatile unsigned char*)0x106))

#define  PORTL (*((volatile unsigned char*)0x10B))
#define   DDRL  (*((volatile unsigned char*)0x10A))
#define   PINL  (*((volatile unsigned char*)0x109))


/* 인터럽트 사용을 위한 레지스터 */

#define EICRA (*((volatile unsigned char*)0x69))
#define EICRB (*((volatile unsigned char*)0x6A))
#define EIMSK (*((volatile unsigned char*)0x3D))
#define EIFR  (*((volatile unsigned char*)0x3C))
#define SREG (*((volatile unsigned char*)0x5F)) 

/* PCINT 사용을 위한 레지스터 */

#define PCICR (*((volatile unsigned char*)0x68))
#define PCIFR (*((volatile unsigned char*)0x3B))
#define PCMSK2 (*((volatile unsigned char*)0x6D))
#define PCMSK1 (*((volatile unsigned char*)0x6C))
#define PCMSK0 (*((volatile unsigned char*)0x6B))


/* CPU 동작시간을 맞춰주기 위한 Dealy문과 값 지정 */

#define  Delay(x)    for(uiCnt=0; uiCnt<(dNum1); ++uiCnt)

#define  dNum1 50000
#define  dNum2 300000
#define  dNum3 10000000

void __vector_1(void)__attribute__((signal,used,externally_visible));
void __vector_5(void)__attribute__((signal,used,externally_visible));

#endif //__SMART_H__

 

 

 

 

PCINT를 사용하여 인터럽트를 걸어보자!

 

PCINT에서 PCPin Change의 약자이다.

 

 

 

/*** 펌웨어 설계 시 유의해야 할 부분 ***/

 

1. 출력 PORT의 초기화를 가장 우선으로 했는가?

2. Stack Point의 번지지정에는 이상이 없는가?

3. Stack 영역의 할당은 적절한가?

4. RAM Clear SubroutineCall하는가?

5. RAM ClearInterrup가 발생하는가?

6. Vector TableAddress Label 정의는 정확한가?

7. /출력 port의 입/출력 모드 registor의 설정은 정확한가?

8. /출력 port의 초기화를 했는가?

 

 

/*** 외부 인터럽트 학습 ***/

 

외부 인터럽트(INT0 - 7)의 특징

- 외부 인터럽트는 INT 0 - 7핀의 입력으로 인해 인터럽트가 발생한다.

- 입력 방식의 신호를 선택할 수 있다. ex) low/high/상승&하강 에지

- 외부 인터럽트는 INT0 - 7핀의 입/출력 방향에 관계없이 인터럽트가 발생한다.

- INT 0 - 3 은 비동기적 검출이 가능하다.(슬립모드를 깨울 때 이용되기도 한다.)

- INT 4 - 7 I/O클럭이 있어야만 사용가능하다.

 

외부인터럽트를 사용하려면 관련 레지스터와 그 레지스터의 제어방법을 알아야 한다.

 

1. SREG(Status Register)

- MCU의 현 상태 및 최근 수치 명령 실행에 대한 결과를 포함한다.

- 상태 레지스터는 모든 ALU 연산을 수행 후 갱신된다.

- Bit7, I (Global Interrupt Enable): 모든 인터럽트 활성화 비트

 

2. EIMSK(External Interrupt Mask Register)

- Bit7 0 - INT 7~0 Q 비트를 SET(1) 시키면 해당 외부 인터럽트 핀이 활성화 된다.

- , SREGI비트가 1SET된 상태여야 한다.

 

3. EICRA(External Interrupt Control Register A)

- 외부 인터럽트의 트리거 방식을 선택하는 레지스터



 

4. EICRB(External Interrupt Control Register B)

- 외부 인터럽트의 트리거 방식을 선택하는 레지스터

 

5. EIFR(External interrupt Flag Register)

- 인터럽트가 요청되면 해당 비트가 1이 된다. 그 후에 인터럽트 루틴이 실행될 때 해당 비트가 clear(0)된다.

반응형
Posted by newind2000
Busan IT/공장내 Network2015. 4. 16. 17:35

포인터를 활용한 1/2차원 배열의 값과 주소

 

학습목표

 

1차원 배열의 값과 주소에 대해 이해하고 여러 가지 형태를 사용하여 출력할 수 있다.

2차원 배열의 값과 주소에 대해 이해하고 여러 가지 형태를 사용하여 출력할 수 있다.

 

지난 시간에 이어 2차원 배열에 대하여 수업을 해 보아요. \=_=/ \=_=/

시간이 남아 퓨전...(드래곤볼 참조)

 

... \=_=/ \=_=/

... o-(=_=)o- -o(=_=)-o

... /=_=/ \=_=\

 

 

배열에서 배열의 이름자체는 배열의 주소 값을 나타낸다.

ex) A[5]; printf("%p", A); -> A의 주소 출력

 

 

int A[5]라는 배열이 있다고 하면,


A는 주소 값으로써 상수이고 p는 주소 변수이다.

 

p가 변수임을 확인해 보자.


p는 대입연산자(=)를 활용하여 그 값을 변할 수 있는 주소 변수임을 알 수 있다.

하지만 배열 A 또는 B는 주소 값을 나타내는 주소 상수로써 값을 변화 시킬 수 없다.

변수와 상수의 차이라는 점을 제외하고는 배열의 이름과 주소 상수는 똑같이 사용할 수 있다.

 

/*** 네트워크 삼천포 ***/





natservice가 있을 때 이것을 삭제해야 컴퓨터가 정상적으로 가동한다.

 

삭제하는 방법 http://todaki.tistory.com/2646

 

각설! 네트워크 삼천포 break;

--------------------------------------------------------------------------

 

배열의 타입은 int[X]이다. // X는 선언 시 입력한 상수.

 

const를 어떻게 쓰느냐에 따라 고정되는 값이 다르다.

 

 

포인터 변수 int * p에서,

 

const* 앞에 붙이면 *가 가리키는 값을 수정할 수 없고,

const를 변수명 바로 앞에 붙이면 가리키는 주소 값을 바꿀 수 없게 된다.


 

2차원 배열로 넘어가서,

 

우선 for문을 사용하여 값과


 

차원수만큼의 대괄호([])가 있으면 그것은 값을 뜻한다.

차원수만큼의 포인터(*)가 있으면 그것은 값을 뜻한다.

그러므로 대괄호의 역할을 포인터가 할 수 있다. 또한 포인터의 역할을 대괄호가 할 수 있다.

정리하면 대괄호의 수 + 포인터의 수 = 차원수 가 되면 값을 뜻한다.

대괄호의 수와 포인터의 수가 차원수보다 작게 되면 그것은 주소를 뜻한다.

 

코드와 결과 값!

 

/*** 2dimArry.c ***/

#include <stdio.h>

int main(void)
{
  /*** 사용자의 가독성을 생각한 배열 코딩 ***/

  int A[2][3]= {  {1,2,3},
      {4,5,6}
               };
  int iCnt1;  //행의 출력을 위한 카운터   
  int iCnt2;  //열의 출력을 위한 카운터

  for(iCnt1=0; iCnt1<2; ++iCnt1)
  {
    for(iCnt2=0; iCnt2<3; ++iCnt2)
    {
      printf("[%d]", A[iCnt1][iCnt2]);    
    }
    putchar('\n');
  }

  putchar('\n');
  
  for(iCnt1=0; iCnt1<2; ++iCnt1)
  {
    for(iCnt2=0; iCnt2<3; ++iCnt2)
    {
      printf("[%08X]"&A[iCnt1][iCnt2]);    
    }
    putchar('\n');
  }
  putchar('\n');

  printf("A[0][0]의 값은    [%d]입니다.\n", A[0][0]);
  printf("*(A[0]+0)의 값은  [%d]입니다.\n", *(A[0]+0));
  printf("*((*A+0)+0)의 값은  [%d]입니다.\n", *((*A+0)+0));
  printf("*(A[0])의 값은    [%d]입니다.\n", *(A[0]));
  printf("**A의 값은    [%d]입니다.\n\n", **A);

  printf("A[1][2]의 값은    [%d]입니다.\n", A[1][2]);
  printf("*(A[1]+2)의 값은  [%d]입니다.\n", *(A[1]+2));
  printf("*((*A+2)+3)의 값은  [%d]입니다.\n\n", *((*A+2)+3));

  printf("A[0][0]의 주소는  [%08X]입니다.\n"&A[0][0]);
  printf("(A[0]+0)의 주소는  [%08X]입니다.\n", (A[0]+0));
  printf("((A+0)+0)의 주소는  [%08X]입니다.\n", ((A+0)+0));


  return 0;

}

 


 


 

 

 

반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 16. 11:38

인터럽트(Interrupt)와 전자 룰렛

 

학습목표 - Interrupt를 활용하여 LED전자 룰렛을 만들 수 있다

 

인터럽트를 활용하여 좌우의 끝으로 이동하는 LED 전구를 멈추게 하는 코딩을 해보자.

 

/*** 코딩 절차 ***/

I. 문장으로 표현

II. 큰 덩어리로 코딩할 부분 나누기

III. 덩어리로 나눈 부분 세부화

IV. 코딩

V. 실행

VI. 디버깅

 

 

I. 문장으로 표현

 

LED전구 8개에 불이 하나씩만 번갈아 가면서 켜지게 하고 한쪽 끝으로 이동하고 나면 다시 반대 방향으로 이동하게 하는 코드를 짜보자.

 

인터럽트(Interrupt)를 활용하여 버튼(pull-up상태)이 눌러져 있을 때 전구의 이동이 멈추게 만들어보자.

 

인터럽트는 INT4를 활용하고 인터럽트 벡터 no.AVR교재 p/137을 참조한다.

 

외부 인터럽트는 레지스터 설정은 low level일 때 발생한다.

 

II. 큰 덩어리로 코딩할 부분 나누기

1. LED 이동 코딩

2. 스위치를 넣으면 인터럽트가 작동하여 이동이 멈추는 코딩

 

III. 덩어리로 나눈 부분 세부화

 

1. LED 이동 코딩

- 8개의 LED전구에 좌에서 우로 전구의 불이 이동하게 한다.

- 우측 끝으로 이동했을 때, 좌측으로 이동하게 한다.

- 좌측 끝으로 이동했을 때, 우측으로 이동하게 한다.

 

2. 스위치를 넣으면 인터럽트가 작동하여 이동이 멈추는 코딩

- INT4를 활용하도록 포트를 설정해 준다. 교재 p/137를 참고하자.

- 외부 인터럽트 컨트롤 레지스터의 이름이 무엇인지 확인한다.

- 외부 인터럽트 컨트롤 레지스터의 설정 값을 확인하고, low level일 때 인터럽트 가동하게 설정해준다.

 

 

우선 회로도를 그려주자.

 

/*** 설정 ***/

 

PORT: C는 출력, Einterrupt 입력

 

스위치는 pull-up

 

LED 전구는 common anode type으로 연결하여 low 값이 입력 되었을 때 LED on

 



 

LED가 좌우로 움직이는 코딩을 마친 후 인터럽트 설정을 해주자.

 



 

EICRA0x02, low level로 설정해주자.

INT4을 사용하기 때문에 아래와 설정을 해주어야 한다.

 

EICRB = 0x02; //low level 동작 설정

EIMSK = 0x10; //외부 인터럽트 허용 레지스터 - 인터럽트 4번 외부 인터럽트 허용

 

소스는 아래와 같다.

 

/*** main.c ***/


#include <atm2560.h>
//#include <avr/interrupt.h>
#include "SMART.h"

int main(void)
{
  /*** LED 입력 값을 넣어줄 변수 만들기 ***/

  unsigned char ucLED=0xFE;

  /*** Delay를 위한 변수 입력 ***/

  volatile unsigned int uiCnt;

  /*** 사용할 PORT 설정 ***/
  
  DDRC  = 0xFF;  //PORT C 모두 사용
  DDRE  = 0xEF;  //PORT E의 5번째 핀 사용 

  /*** 인터럽트 설정 ***/

  SREG &= 0x7F;  //interrupt disable, 설정 중 오동작을 막기 위해
  EICRB  = 0x02;  //low level 동작 설정 
  EIMSK  = 0x10;  //외부 인터럽트 허용 레지스터 - 인터럽트 4번 외부 인터럽트 허용 
  SREG  |= 0x80;  //0B 1000 0000 핀만 1을 넣어주고 나머지는 그대로  

  while(1)
  {
    /*** LED불 좌에서 우 이동 코드 ***/
    PORTC= ucLED;
    Delay();
    ucLED = ucLED << 1;
    ucLED |= 0x01;

    /*** LED불 우 끝으로 갔을 때 좌로 이동 코드 ***/
    while(ucLED==0xFF)
    {
      ucLED = 0x7F;
      PORTC = ucLED;
      Delay();
      
      while(1)
      {
        ucLED=ucLED >> 1;
        ucLED |= 0x80;
        PORTC = ucLED;
        Delay();
        if(ucLED==0xFE)
          break;
      }
    }
          
  }
  
  return 0;
}

void __vector_5(void)
{
  /*** PINE가 0x00일때 잡아 놓아라 ***/
  while(1)
  {
    while(PINE==0x00);

    break;
  }
}


/*** SMART.h ***/


#ifndef __SMART_H__
#define __SMART_H__

/**** General Purpose Register A - L ****/

#define  PORTA (*((volatile unsigned char*)0x22))
#define   DDRA  (*((volatile unsigned char*)0x21))
#define   PINA  (*((volatile unsigned char*)0x20))

#define  PORTB (*((volatile unsigned char*)0x25))
#define   DDRB  (*((volatile unsigned char*)0x24))
#define   PINB  (*((volatile unsigned char*)0x23))

#define  PORTC (*((volatile unsigned char*)0x28))
#define   DDRC  (*((volatile unsigned char*)0x27))
#define   PINC  (*((volatile unsigned char*)0x26))

#define  PORTD (*((volatile unsigned char*)0x2B))
#define   DDRD  (*((volatile unsigned char*)0x2A))
#define   PIND  (*((volatile unsigned char*)0x29))

#define  PORTE (*((volatile unsigned char*)0x2E))
#define   DDRE  (*((volatile unsigned char*)0x2D))
#define   PINE  (*((volatile unsigned char*)0x2C))

#define  PORTF (*((volatile unsigned char*)0x31))
#define   DDRF  (*((volatile unsigned char*)0x30))
#define   PINF  (*((volatile unsigned char*)0x2F))

#define  PORTG (*((volatile unsigned char*)0x34))
#define   DDRG  (*((volatile unsigned char*)0x33))
#define   PING  (*((volatile unsigned char*)0x32))

#define  PORTH (*((volatile unsigned char*)0x102))
#define   DDRH  (*((volatile unsigned char*)0x101))
#define   PINH  (*((volatile unsigned char*)0x100))

#define  PORTJ (*((volatile unsigned char*)0x105))
#define   DDRJ  (*((volatile unsigned char*)0x104))
#define   PINJ  (*((volatile unsigned char*)0x103))

#define  PORTK (*((volatile unsigned char*)0x108))
#define   DDRK  (*((volatile unsigned char*)0x107))
#define   PINK  (*((volatile unsigned char*)0x106))

#define  PORTL (*((volatile unsigned char*)0x10B))
#define   DDRL  (*((volatile unsigned char*)0x10A))
#define   PINL  (*((volatile unsigned char*)0x109))


/* 인터럽트 사용을 위한 레지스터 */

#define EICRA (*((volatile unsigned char*)0x69))
#define EICRB (*((volatile unsigned char*)0x6A))
#define EIMSK (*((volatile unsigned char*)0x3D))
#define EIFR  (*((volatile unsigned char*)0x3C))
#define SREG (*((volatile unsigned char*)0x5F)) 


/* CPU 동작시간을 맞춰주기 위한 Dealy문과 값 지정 */

#define  Delay(x)    for(uiCnt=0; uiCnt<(dNum1); ++uiCnt)

#define  dNum1 50000
#define  dNum2 300000
#define  dNum3 10000000

/* 함수 원형 선언 */ 
void __vector_5(void)__attribute__((signal,used,externally_visible));


#endif //__SMART_H__







반응형
Posted by newind2000
Busan IT/공장내 Network2015. 4. 15. 17:45

다차원 배열의 값과 주소

 

학습목표 - 다차원 배열의 값과 그 주소 값의 결과를 이해할 수 있다.

 

p/338 Ch.16. 다차원 배열

 

행렬에서 행은 가로줄, 을 쓸 때 -부터 쓰고 가로로 움직인다. 가로줄

열은 세로줄, 을 쓸 때 위에서 아래로 세로로 움직인다. 세로줄

 

p/339의 예제

 

(가로 입력 값 * 세로 입력 값) * 변수형의 크기 임을 알 수 있다.

 

p/342 예제

Define을 컴파일 시 지정하여 컴파일 할 수 있다. 명령어는

‘/D‘#define의 역할을 한다.

띄우지 않고 ‘define을 원하는 변수명 = 넣고 싶은 값을 넣으면 #define 형태의 명령어를 컴파일 시 삽입할 수 있는 것이다.

 

 

이중 for문을 활용하여 사람이 이해하기 쉬운 형태의 배열로 표현해 보자.

 

NM의 값을 입맛대로 바꿔서 코딩해보자.

 

2차원 배열의 주소는 메모리상에 연속으로 만들어진다.

 


 

배열에서 주소 값이 똑같은 것

 

배열이름

대괄호 하나의 주소값




 

배열이름에 + XX만큼 줄 이동

배열[] + XX만큼 칸 이동

 

** 칸 이동은 선언된 변수형의 크기만큼 된다.

 

배열에 &를 붙이면 배열 전체의 주소를 뜻한다. 때문에 해당 주소 값에 1을 붙이면 배열의 마지막 주소에서 선언된 변수의 크기만큼의 값이 더해지는 주소 값이 나오게 된다.

 

정리해보면, 2차원 배열에서

 

&배열 이름 - 배열 전체의 주소

배열 이름 - 배열 1

배열[] - 배열 1

&배열[][] - 배열 1

 

 

 

1차원 배열에서는

 

&A + 1 - 1차원 배열 크기만큼 이동

A +1 - 한 칸 이동

 

&*이 만나면 서로 상쇄되어 본래의 값이 된다.

 

*A = *&A[0]

*A = A[0]

 

*(A+1) = A[1]

 

배열의 값을 표현하는 방식은 2가지이다.

 

배열자체의 이름을 출력하는 방법과 포인터를 사용하여 출력하는 방식이 있다.

 

복잡해 보이지만 이해하는 방법은 간단하다.

 

배열자체를 적으면 그것은 주소를 뜻한다. 때문에 거기에 포인터(*)붙혀주면 해당 값을 찾아가게 되는데 &*이 붙으면 그 값은 상쇄되어 값을 도출하게 된다.

 

1차원 배열에서 A+1은 배열의 가장 처음에서 한 칸을 이동한 주소 값을 가지게 된다. 여기에 포인터를 붙이면 *&는 상쇄되어 해당 값을 가지게 된다.





 

 

 

 

 

 

 

 

반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 15. 12:44

AVR 컨트롤러 - Interrupt와 난수를 활용한 주사위 만들기

 

학습목표 - Interrupt와 난수를 활용한 주사위를 만들 수 있다.

 

Interrupt를 활용한 주사위 던지기

 

순서

 

1. 회로를 만든다.

- ATmega128a로 스위치와 7segment(common anode)를 이용한다.(PORT A 사용)

- switch를 활용하여 interrupt를 만든다.

 

2. 코딩을 한다.

- switch를 누르고 있는 동안 8표시

- switch를 떼면 무작위 숫자(rand()%6)+1 출력

 

! 입력핀은 PIN *, 출력은 PORT *

 


코드


/**** main.c ****/



#include
 <atm128.h>
//#include <avr/interrupt.h>
#include "SMART.h"
#include <Turboc.h>

int main(void)
{
  unsigned char FND[10= {0x400x790x240x300x190x120x020x580x000x10};
  volatile unsigned int uiCnt;


  DDRA = 0xFF;  //포트 A 전부 출력 
  DDRD = 0xFE;  //포트 D 1번 핀만 입력
  DDRC = 0xFF;  //포트 C 전부 출력
  
  SREG &= 0x7F;  //interrupt disable, 설정 중 오동작을 막기 위해
  EICRA = 0x02;  //스위치의 트리거 방식 설정 - 하강 에지 방식 
  EIMSK = 0x01;  //외부 인터럽트 허용 레지스터 - 인터럽트 0 외부 인터럽트 허용 
  SREG |= 0x80

  while(1)
  {

      
    while(PIND==1)
    {
      
      PORTA = FND[8];
      PORTC = 0x01;
    
    }

    
  }
        

  return 0;
}


void __vector_1(void)
{
  volatile unsigned int uiCnt;

  unsigned char FND[10= {0x400x790x240x300x190x120x020x580x000x10};

  while(1)
  {

    while(PIND==1)
    {
      while(1)
      {
          
        PORTA = FND[8];
        PORTC = 0x01;
        
          if(PIND==0)
            break;
      }

      PORTA = FND[((random(6))+1)];
      PORTC = 0x01;

      if(PIND==1)
        break;
        
      
        
      }
      

  }

  

      
}  

/*** SMART.h ***/


#ifndef __SMART_H__
#define __SMART_H__

/**** General Purpose Register A - L ****/

#define  PORTA  (*((volatile unsigned char*)0x3B))
#define   DDRA   (*((volatile unsigned char*)0x3A))

#define  PORTC  (*((volatile unsigned char*)0x35))
#define   DDRC  (*((volatile unsigned char*)0x34))
#define   PINC  (*((volatile unsigned char*)0x33))

#define  PORTD  (*((volatile unsigned char*)0x32))
#define   DDRD  (*((volatile unsigned char*)0x31))
#define   PIND   (*((volatile unsigned char*)0x30))

#define  PORTG  (*((volatile unsigned char*)0x65))
#define   DDRG   (*((volatile unsigned char*)0x64))
#define   PING   (*((volatile unsigned char*)0x63))


/* 인터럽트 사용을 위한 레지스터 */

#define EICRA  (*((volatile unsigned char*)0x6A))
#define EICRB  (*((volatile unsigned char*)0x5A))
#define EIMSK  (*((volatile unsigned char*)0x59))
#define EIFR    (*((volatile unsigned char*)0x58))
#define SREG    (*((volatile unsigned char*)0x5F)) 


/* CPU 동작시간을 맞춰주기 위한 Dealy문과 값 지정 */

#define  Delay(x)    for(uiCnt=0; uiCnt<(x); ++uiCnt)

void __vector_1(void)__attribute__((signal,used,externally_visible));

/* 난수 출력  */

#define randomize() srand((unsigned)time(NULL))
#define random(n) (rand() % (n))


#endif //__SMART_H__



 

반응형
Posted by newind2000
Busan IT/공장내 Network2015. 4. 14. 17:37

구조체와 사용자 정의 자료형

 

학습목표

 

- 구조체, 공용체, 열거형을 이해하고 사용할 수 있다.

 

 

/*** Linux 기초***/

 



---------------------------------------------------------------------------------




 

호출 시 포인터를 활용하면 reference방식이라 하고 호출 시 값을 사용하면 value방식이라 한다.

 

복잡한 구조체를 복사하는 것보다 포인터를 활용하여 해당 주소 값을 가리켜주면 메모리를 적게 차지하고 속도도 향상되는 장점이 있다. reference방식으로 코딩을 해보자.


compiler는 변수를 만들 때 메모리의 크기를 알 수 없으면 변수를 만들 수 없다.

하여 중첩 구조체를 만들 때 이미 선언된 구조체를 다음에 만들어주어야 한다.

공용체는 union이라는 키워드를 사용해서 정의한다. 문법은 구조체와 동일하고 뒤에 사용되는 변수의 값이 이전의 있던 변수 값에 덮어 씌어지게 된다.

p/489 예제

유니온은 주소 값이 동일하다!

 

p/489 예제






다음 시간에는 2차원 배열에 대해서 배운다!


 

반응형
Posted by newind2000