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/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/AVR 컨트롤러2015. 4. 14. 13:45

인터럽트를 활용한 LED전구 불켜기

 

학습목표 - 인터럽트를 활용하여 나열된 LED전구를 하나씩만 돌아가며 켤 수 있다.

 

인터럽트를 활용한 LED전구 옮기기를 해보자.

 

우선 하드웨어 세팅!

 


 

소스

 

/*** Main.c ***/

/*** 인터럽트 함수 예제 ***/
#include <atm2560.h>
//#include <avr/interrupt.h>
#include "SMART.h"


unsigned char LED = 0xFF;  //

/*ISR(INT0_vect)
{
  PORTD ^= 0x01;
  return;
}*/


int main(void)
{

  SREG &= 0x7F;  //interrupt disable, 설정 중 오동작을 막기 위해

  DDRD  = 0xFE;  //PORT D의 0번만 빼고 다 출력.
  DDRA  = 0xFF;  //PORT A를 모두 출력.


  PORTA   = LED;
  
  EICRA  = 0x02;  //스위치의 트리거 방식 설정 - 하강 에지 방식 
  EIMSK  = 0x01;  //외부 인터럽트 허용 레지스터 - 인터럽트 0 외부 인터럽트 허용 
  
  SREG  |= 0x80;  //0B 1000 0000 핀만 1을 넣어주고 나머지는 그대로  
  
  


  while(1)
  {
    ;
  }
  
  return 0;
}


void __vector_1(void)
{

  unsigned char ucCnt=0;
  if(ucCnt==0)
    PORTA=0xFE;
  LED   = LED << 1//porta의 0번 핀을 누를때마다 한칸씩 이동 시키는 코드
  LED |= 0x01;
  if(LED==0xFF)
    LED=0xFE;
  PORTA = LED;
  EIFR    = 0x01;  //인터럽트 인출 후 강제로 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))

/* PORT 사용별 이름 지정 */

#define  LCD_CTL      PORTG
#define  LCD_BUS    PORTA  

#define  LCD_CTL_DDR  DDRG
#define  LCD_BUS_DDR  DDRA


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

#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)) 

/* LCD PIN */

#define  LCD_RS  0
#define  LCD_RW  1
#define  LCD_EN  2




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

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

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

/* LCD 제어 명령어 */

#define  LCD_CLR   0x01  //화면 지우기, 커서홈 -0B 0000 0001
#define  LCD_HOME   0x02  //커서 처음 위치로 이동 - OB 0000 001
#define  LCD_ENR   0x06  //어드레스 자동증가/감소(I/D) = 1(증가), 표시 쉬프트(s)=1(표시) - 0B 0000 0111
#define  LCD_DSP   0x0F  //디스플레이(D)=1(표시), 커서(C)=1(표시), 깜빡임(B) on/off=1(on) - 0B 0000 1111
#define  LCD_CUR   0x14  //표시=1(표시), 커서 이동=1(오른쪽으로 쉬프트) - OB 0001 11--
#define  LCD_FUNC   0x38  //인터페이스(DL) = 1(8비트), 라인수(N)=1(2라인), 문자폰트(F)=0(5*8) - OB 0011 10--

/* LCD Write mode 초기화 설정 */
// RS : High = data register, Low = Instruction Register
// R/W : High = read, Low = write


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


#endif //__SMART_H__


 

 

 

 

 

반응형

'Busan IT > AVR 컨트롤러' 카테고리의 다른 글

인터럽트(Interrupt)와 전자 룰렛  (0) 2015.04.16
Interrupt와 난수를 활용한 주사위 만들기  (0) 2015.04.15
인터럽트(Interrupt)  (0) 2015.04.13
7 Segment 카운터 만들기 2  (0) 2015.04.10
7 semgemnt 카운터  (0) 2015.04.09
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 13. 13:47

AVR 컨트롤러 - 인터럽트(Interrupt)

 

학습목표

 

- 인터럽트의 개념을 이해하고 LED를 활용하여 코딩을 할 수 있다.

 

P/131, Interrupt

 

정상적인 프로그램의 실행순서를 변경하기 보다 수행이 시급한 작업을 수행한 후에 원래의 프로그램으로 복귀하는 것을 Interrupt라 한다.

 

인터럽트의 종류

 

인터럽트를 나누는 방법은 총 3가지이다. 3가지 방법과 중요한 인터럽트는 다음과 같다.

 

1. 인터럽트 발생 원인에 따른 분류 - 외부 인터럽트

2. 인터럽트 발생시 마이크로프로세서의 반응 방식에 따른 분류 - 차단 가능 인터럽트

3. 인터럽트를 요구한 입/출력 기기를 확인하는 방법에 따른 분류 - 벡터형 인터럽트

 

외부 인터럽트: 외부 마이크로 프로세서에서 신호가 들어와 인터럽트가 수행되는 방식이다.

 

//DMA: Direct Memory Access

 

차단 가능 인터럽트: 인터럽트가 걸린 상태에서 다른 인터럽트가 수행되는 것을 허용하지 않는 인터럽트이다.

 

벡터형 인터럽트:

 

인터럽트도 실행우선순위를 설정하여 실행시킬 수 있다.

 

인터럽트의 처리 과정

 

1. 인터럽트 요청 신호의 검출

 

2. 인터럽트 우선순위 제어 및 허용 여부 판단

 

3. 인터럽트 처리루틴의 시작 번지 확인

 

4. 복귀주소 및 레지스터를 저장

 

5. 인터럽트 서비스 루틴을 실행

 

6. 인터럽트 서비스 루틴을 종료하고 원래의 주프로그램으로 복귀

 








 

 

 

SREG &= 0x7F;

=> SREG = SREG & 0x7F;

 

 

EIMSK를 셋해준다.

 

define작업부터 우선 해주자.

 

SREG = 0x5F;

EICRA = 0x69;

EICRB = 0x6A;

EIMSK = 0x3D;

DDRD = 0x0E;

DDRA = 0xFF;

 

 

트리거 방식(p/145)

 

스위치를 뗄 때 입력 값이 들어가도록 해보자.

 

/*** & 리셋 코딩 ***/

 

마스크(리셋)

 

&= 0xFF

 

해당 비트만 변동

 

|= 0x(원하는 비트에 1)

 

interrupt는 외부요인에 작동하기 때문에 메인함수에서 따로 호출할 필요가 없다.







<코    드>


/**** Main.c ****/


/*** 인터럽트 함수 예제 ***/

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



/*ISR(INT0_vect)
{
  PORTD ^= 0x01;
  return;
}*/


int main(void)
{
  SREG &= 0x7F;  //interrupt disable, 설정 중 오동작을 막기 위해

  DDRD  = 0xFE;  //PORT D의 0번만 빼고 다 출력.
  DDRA  = 0xFF;  //PORT A를 모두 출력.
  //DDRB  = 0x00;  //PORT B는 출력 포트로 사용한다. 

  PORTA   = 0x01;
  
  EICRA  = 0x02;  //스위치의 트리거 방식 설정 - 하강 에지 방식 
  EIMSK  = 0x01;  //외부 인터럽트 허용 레지스터 - 인터럽트 0 외부 인터럽트 허용 
  
  SREG  |= 0x80;  //0B 1000 0000 핀만 1을 넣어주고 나머지는 그대로  
  


  while(1)
  {
    ;
  }
  
  return 0;
}

 

/*** SMART.h ***/



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


#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))  

 

 

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

AVR 컨트롤러 - 7 Segment 카운터 만들기 2

 

학습목표

 

ATmega25607segment 3개를 가지고 999까지의 카운터를 만들 수 있다.

 

99에서 100으로 넘어갈 때 십의 자리가 표시되지 않고 백의 자리는 1이 되어야 하는데 0으로 표시 되었다.

 

이것은 백의 자리 올림 조건이 99가 되어야 하는데 십의 자리 리셋 조건 9와 겹쳐서 99가 되지 않는 상황이 발생하였다.

 

하여 리셋조건을 없애고 나머지 값을 활용하여 간단하게 코드를 짰다.

 

 /**** Main.c ****/

#include "SMART.h"


int main(void)
{
  volatile unsigned int uiCnt;
  unsigned char cntD1=0, cntD2=0, cntD3=0;  //카운팅을 위한 카운터 변수들
  unsigned char FND[10= {0x400x790x240x300x190x120x020x580x000x10};


  DDRA = 0xFF;
  DDRB= 0x07;
  
  
  while(1)  

  {
  
    
      /**** 출력 ****/
      
      
        PORTA = FND[cntD1%10];   //PORTA에 FND배열에 cntD1을 넣어 출력
        PORTB= 0x01;    //3//1번째 자리 포트에만 불을 켜라
        for(uiCnt=0; uiCnt <= 5000; ++uiCnt); 
    
        
        PORTA = FND[cntD2%10];   //PORTA에 FND배열에 cntD2을 넣어 출력
        PORTB= 0x02;    //3//2번째 자리 포트에만 불을 켜라
        for(uiCnt=0; uiCnt <= 5000; ++uiCnt);

        PORTA = FND[cntD3%10];   //PORTA에 FND배열에 cntD3을 넣어 출력
        PORTB= 0x04;    //3//3번째 자리 포트에만 불을 켜라
        for(uiCnt=0; uiCnt <= 5000; ++uiCnt);

      
      
      /**** 올림 ****/
      ++cntD3;
      if(cntD3%10==0)      //9상태면 십의 자리에 올림을 해주어라 
        ++cntD2;
      if(cntD3%10==0&cntD2%10==0)      //99상태면 백의 자리에 올림을 해주어라
        ++cntD1;
      
    
      

          
  }
    
  return 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))

/* PORT 사용별 이름 지정 */

#define  LCD_CTL      PORTG
#define  LCD_BUS    PORTA  

#define  LCD_CTL_DDR  DDRG
#define  LCD_BUS_DDR  DDRA




/* LCD PIN */

#define  LCD_RS  0
#define  LCD_RW  1
#define  LCD_EN  2




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

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

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

/* LCD 제어 명령어 */

#define  LCD_CLR   0x01;  //화면 지우기, 커서홈 -0B 0000 0001
#define  LCD_HOME   0x02;  //커서 처음 위치로 이동 - OB 0000 001
#define  LCD_ENR   0x06;  //어드레스 자동증가/감소(I/D) = 1(증가), 표시 쉬프트(s)=1(표시) - 0B 0000 0111
#define  LCD_DSP   0x0F;  //디스플레이(D)=1(표시), 커서(C)=1(표시), 깜빡임(B) on/off=1(on) - 0B 0000 1111
#define  LCD_CUR   0x14;  //표시=1(표시), 커서 이동=1(오른쪽으로 쉬프트) - OB 0001 11--
#define  LCD_FUNC   0x38;  //인터페이스(DL) = 1(8비트), 라인수(N)=1(2라인), 문자폰트(F)=0(5*8) - OB 0011 10--

/* LCD Write mode 초기화 설정 */
// RS : High = data register, Low = Instruction Register
// R/W : High = read, Low = write





#endif //__SMART_H__




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

7segment 카운터

 

학습목표

 

7segmentATmega128a를 활용하여 0 - 999카운터를 만들 수 있다.


<7segment(FND)를 활용한 제품 - 디지털 온도 계측기>

 

온도계측에 사용되는 대표적인 ICLM35Thermo coupler(TC)가 있다.

 

보일러 컨트롤러를 뜯어보면 Thermistor를 볼 수 있다. 괜히 뜯으면 엄마한테 빚자루로 맞는다. 에어컨 리모컨 안에도 있다.

 

Thermistor5k, 10k, 200k를 주로 쓰는데 이것은 이 수치는 온도 25도에서의 저항 값이다.

 

코딩한 내용을 AVR1280segment에 넣어보자.

 

FND500common cathode 타입임으로 기존의 코딩을 변경해주자.

/**** Main.c ****/


#include "SMART.h"


int main(void)
{
  volatile unsigned int uiCnt;
  unsigned char cntD1=0, cntD2=0, cntD3=0;  //카운팅을 위한 카운터 변수들
  unsigned char FND[10= {0x400x790x240x300x190x120x020x580x000x10};



  DDRA = 0xFF;
  DDRB= 0x07;
  
  
  while(1)  

  {

    
      if(cntD1==10&cntD2==10&cntD3==10)  //999상태면 D1의 값을 0으로 리셋 
        cntD3=0;

      if(cntD1==10&cntD2==10)      //99상태면 천의 자리에 올림을 해주어라
        ++cntD3;

      PORTA = FND[cntD3];   //PORTA에 FND배열에 cntD1을 넣어 출력
      PORTB= 0x04;    //3//1번째 자리 포트에만 불을 켜라
      for(uiCnt=0; uiCnt<(5000); ++uiCnt);
      

      if(cntD2==10&cntD1==10//99상태면 D2의 값을 0으로 리셋 
        cntD2=0;

      if(cntD1==10)      //9상태면 백에 자리에 올림을 해주어라 
        ++cntD2;

      PORTA = FND[cntD2];   //PORTA에 FND배열에 cntD2을 넣어 출력
      PORTB= 0x02;    //3//2번째 자리 포트에만 불을 켜라
      for(uiCnt=0; uiCnt<(5000); ++uiCnt);

      if(cntD1==10)       //9상태면 D3의 값을 0으로 리셋 
        cntD1=0;

      PORTA = FND[cntD1];   //PORTA에 FND배열에 cntD3을 넣어 출력
      PORTB= 0x01;    //3//3번째 자리 포트에만 불을 켜라
      for(uiCnt=0; uiCnt<(5000); ++uiCnt);
      ++cntD1;
      

    
          
  }
    
  return 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))

/* PORT 사용별 이름 지정 */

#define  LCD_CTL      PORTG
#define  LCD_BUS    PORTA  

#define  LCD_CTL_DDR  DDRG
#define  LCD_BUS_DDR  DDRA




/* LCD PIN */

#define  LCD_RS  0
#define  LCD_RW  1
#define  LCD_EN  2




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

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

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

/* LCD 제어 명령어 */

#define  LCD_CLR   0x01;  //화면 지우기, 커서홈 -0B 0000 0001
#define  LCD_HOME   0x02;  //커서 처음 위치로 이동 - OB 0000 001
#define  LCD_ENR   0x06;  //어드레스 자동증가/감소(I/D) = 1(증가), 표시 쉬프트(s)=1(표시) - 0B 0000 0111
#define  LCD_DSP   0x0F;  //디스플레이(D)=1(표시), 커서(C)=1(표시), 깜빡임(B) on/off=1(on) - 0B 0000 1111
#define  LCD_CUR   0x14;  //표시=1(표시), 커서 이동=1(오른쪽으로 쉬프트) - OB 0001 11--
#define  LCD_FUNC   0x38;  //인터페이스(DL) = 1(8비트), 라인수(N)=1(2라인), 문자폰트(F)=0(5*8) - OB 0011 10--

/* LCD Write mode 초기화 설정 */
// RS : High = data register, Low = Instruction Register
// R/W : High = read, Low = write





#endif //__SMART_H__








반응형

'Busan IT > AVR 컨트롤러' 카테고리의 다른 글

인터럽트(Interrupt)  (0) 2015.04.13
7 Segment 카운터 만들기 2  (0) 2015.04.10
Linux 무선 네트워크 설정  (0) 2015.04.08
7 Segment를 활용한 숫자 이동 및 카운터  (0) 2015.04.08
7 Segment 카운트다운  (0) 2015.04.07
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 8. 16:21

Linux 무선 네트워크 설정

 

학습목표

 

- 라즈베리파이에 무선 랜 설정을 할 수 있다.

- 무선랜을 활용하여 라즈베리 파이를 원격 조정할 수 있다.

 

컴퓨터의 설정을 바꾸기 위해서는 관리자 권한으로 명령어를 실행하여야 한다. 관리자로 접속하는 명령어는 sudo su - 이다. sudo는 관리자 명령어를 실행하기 위한 기본명령어이고 susubstitution의 약자이다.

 

root계정으로 들어간 후 개인적으로 사용할 ID를 만들겠다. 계정을 만드는 명령어는 adduser이고 한 칸 띄운 후 만들고 싶은 계정의 이름을 치면 된다.

 

/*** 리눅스 명령어 ***/

 

pwd - 현재 디렉토리 위치 보기

cd - 디렉토리 변경

cd_.. - 상위 디렉토리로 이동

cd_/ - 절대 경로(시작점)로 이동

cd_~ - 홈디렉토리로 이동

ls -al - 현재 모든 디렉토리 보기

cp_'a'_'b' - ab로 복사

raspi_config(root 계정에서) - 설정

reboot(root 계정에서) - 재부팅

halt(root 계정에서) - 종료

/*** ------------ ***/

 

//Linux는 상위 디렉토리와 하위 디렉토리를 슬레쉬(/)로 구분한다.

 

 

sudo /etc/network/interfaces 으로 들어가 무선 랜 설정을 해주자.

 

 

라즈베리파이에서 원격 접속을 가능하도록 설정해 주자.

 

root계정에서 raspi-config입력 -> advance -> SSH server enable 설정

 

www.putty.org 접속하여 putty.exe파일을 다운로드 받는다.

 

위의 주소로 접속하고 비번과 ID를 입력한다.

 

접속창에서 그래픽 환경으로 원격접속하기 위한 파일을 업데이트한다.

 

apt-get update를 입력하여 최신 패키지를 확인 한다.

apt-get install xrdp를 입력하여 XRDP 서버를 설치한다.



 

원격 접속 성공!













 

 

반응형

'Busan IT > AVR 컨트롤러' 카테고리의 다른 글

7 Segment 카운터 만들기 2  (0) 2015.04.10
7 semgemnt 카운터  (0) 2015.04.09
7 Segment를 활용한 숫자 이동 및 카운터  (0) 2015.04.08
7 Segment 카운트다운  (0) 2015.04.07
ATmega2560 LCD 사용을 위한 코딩  (0) 2015.04.03
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 8. 13:13

7 Segment를 활용한 숫자 이동 및 카운터

 

 

 

7 segment를 활용하여 금일 코딩할 내용,

 

- 출력하고 싶은 숫자를 3개의 7 segment에 시간차를 두고 이동시키면서 출력시킨다.

 

- 1 - 100까지 카운트 업/다운을 한다.

 

 

ULN2803이란,

 

Transistor8개 있는 회로이다.

 

어제(4/7) 코딩한 내용에서는 우측 상단에 VCC가 입력되었다. VCCPORT B를 활용하여 출력 값을 7 segment 전압 입력 값에 각 각 넣어준다.

이 놈이 안되서 다른 IC를 사용한다.

하나씩 넘어간다. 코드는 아래와 같다.


/**** Main.c ****/

#include "SMART.h"


int main(void)
{
  volatile unsigned int uiCnt;
  unsigned int uiCnum;
  
  unsigned char FND[] = {0x100x000x580x020x120x190x300x240x790x40};



  DDRA = 0xFF;
  DDRB = 0x07;
  
  while(1)  

  {
    

    for(uiCnum = 0; uiCnum <= 9; ++uiCnum)
    {

      PORTA = FND[uiCnum];

      PORTB = 0x01;
      Delay(1000);
      PORTB = 0x02;
      Delay(1000);
      PORTB = 0x04;
      Delay(1000);
    }
    

  }
    
    
    
    

    

  return 0;

}

 

 






반응형

'Busan IT > AVR 컨트롤러' 카테고리의 다른 글

7 semgemnt 카운터  (0) 2015.04.09
Linux 무선 네트워크 설정  (0) 2015.04.08
7 Segment 카운트다운  (0) 2015.04.07
ATmega2560 LCD 사용을 위한 코딩  (0) 2015.04.03
ATmega2560 사용환경 설정  (0) 2015.04.02
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 7. 13:38

AVR 컨트롤러 - 7 Segment 카운트다운

 

학습목표 - ATmega25607 Segment를 활용하여 카운트 다운을 만들 수 있다.

 

 

ATmega2560을 활용하여 7 segmet에 숫자를 넣는 코딩을 해보자.

 

전압은 common anode sync 타입으로 한다.

 

평소에 pull-up이기 때문에 0V가 인가되어야 해당 LED에 불이 들어오는 방식을 취한다.

 

0부터 9까지 다 띄워보자!


소스

#include "SMART.h"


int main(void)
{
  volatile unsigned int uiCnt;
  unsigned int uiCnum;
  
  unsigned char FND[] = {0x100x000x580x020x120x190x300x240x790x40};

  DDRA = 0xFF;
  
  while(1)  

  {
    for(uiCnum = 0; uiCnum <= 10; ++uiCnum)
    {
      PORTA=FND[uiCnum];
      Delay(dNum3);

    }

  }

      
  

  return 0;

}




 

 

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

ATmega2560 LCD 사용을 위한 코딩

 

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))

/* PORT 사용별 이름 지정 */

#define  LCD_CTL      PORTG
#define  LCD_BUS    PORTA  

#define  LCD_CTL_DDR  DDRG
#define  LCD_BUS_DDR  DDRA




/* LCD PIN */

#define  LCD_RS  0
#define  LCD_RW  1
#define  LCD_EN  2




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

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

#define  dNum1 = 500;
#define  dNum2 = 3000;
#define  dNum3 = 3500;

/* LCD 제어 명령어 */

#define  LCD_CLR   0x01;  //화면 지우기, 커서홈 -0B 0000 0001
#define  LCD_HOME   0x02;  //커서 처음 위치로 이동 - OB 0000 001
#define  LCD_ENR   0x06;  //어드레스 자동증가/감소(I/D) = 1(증가), 표시 쉬프트(s)=1(표시) - 0B 0000 0111
#define  LCD_DSP   0x0F;  //디스플레이(D)=1(표시), 커서(C)=1(표시), 깜빡임(B) on/off=1(on) - 0B 0000 1111
#define  LCD_CUR   0x14;  //표시=1(표시), 커서 이동=1(오른쪽으로 쉬프트) - OB 0001 11--
#define  LCD_FUNC   0x38;  //인터페이스(DL) = 1(8비트), 라인수(N)=1(2라인), 문자폰트(F)=0(5*8) - OB 0011 10--



/* LCD Write mode 초기화 설정 */
// RS : High = data register, Low = Instruction Register
// R/W : High = read, Low = write

void LCD_Inst(unsigned char ucInst)
{
  LCD_BUS = ucInst;
  
  Delay(dNum1);  //초기 전압 인가시  지연
  
  LCD_CTL=(0<<LCD_RS)|(0<<LCD_RW)|(0<<LCD_EN); //  DC 영역
  Delay(dNum1);  //40ns 지연

  LCD_CTL=(0<<LCD_RS)|(0<<LCD_RW)|(1<<LCD_EN); //  enable 입력
  Delay(dNum2);  //enable 후 230ns 지연

  LCD_CTL=(0<<LCD_RS)|(0<<LCD_RW)|(0<<LCD_EN); //  
  Delay(dNum3);  //Tc(500) - Tw(230) = 270ns 지연

}

void LCD_AVR_Pin_Init(void)
{
  LCD_CTL_DDR = 0xFF;  //모든 입력값 열어줌(8개)
  LCD_BUS_DDR = 0x07;  //모든 입력값 열어줌(3개)

}

void LCD_Init(void)
{

  volatile unsigned int uiCnt;

  LCD_AVR_Pin_Init();

  Delay(dNum1);

  LCD_Inst(LCD_FUNC);
  
  
}


#endif //__SMART_H__

 

Main.c

#include "SMART.h"



{

  volatile unsigned int uiCnt;  

  /***** 다이오드에 불 깜빡거리게 만들기 *****/
  DDRA = 0xFF; //PORTA 값이 전부 입력가능하도록 DDRA를 다 열어줌
  DDRB = 0xFF; //PORTA 값이 전부 입력가능하도록 DDRA를 다 열어줌

  while(1)
  {

    Delay(dNum);
    /* PORTA on & PORTB off*/
    PORTA = 0x01;
    PORTB = 0x00;
    
    Delay(dNum);
    /* PORTB off & PORTA on*/
    PORTA = 0x00;
    PORTB = 0x01;    

  }      
  

  return 0;

}


반응형

'Busan IT > AVR 컨트롤러' 카테고리의 다른 글

7 semgemnt 카운터  (0) 2015.04.09
Linux 무선 네트워크 설정  (0) 2015.04.08
7 Segment를 활용한 숫자 이동 및 카운터  (0) 2015.04.08
7 Segment 카운트다운  (0) 2015.04.07
ATmega2560 사용환경 설정  (0) 2015.04.02
Posted by newind2000