Busan IT/AVR 컨트롤러2015. 5. 18. 13:30

16 bit PC PWM

 

================================ Outline ====================================

16bit PC PWM

- LED를 활용한 dimming

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

Duty rate를 변경하여 LED를 제어해보자.

GPIO를 버튼 2개에 활용하여 updown을 설정하고 LED의 불 밝기를 조절해 보자.

 

 

/*** 소스 ***/

 

<main.c>


#include "SMART.h"

int main(void)
{
  /*** 변수 선언 ***/
  int duty=0;
  char i=0;
  
  /*** 포트 설정 ***/
  DDRB = 0xFF;  //PORT B의 모든 핀 출력 설정
  DDRA = 0xFC;  //PORT A의 모든 핀 입력 설정
  
  
  /*** PC PWM  설정 ***/
  TCCR1A = 0x81;  //Phase Correct PWM 0b 1000 0001
  TCCR1B = 0x02;  // 0b 0001 0001, 1분주
  


  while(1)
  {
    while(PINA==0x01)
    {
      if(PINA==0x00)
      {
          duty +=51;
          ++i;
                  
          if(i>5)
          {            
            OCR1A=duty=255;
            i = 6;
          }
          OCR1A = duty;
              
      }

    }
              
    
    
    while(PINA==0x02)
    {
      if(PINA==0x00)
      {
          
          duty -=51;  
          --i;
                  
          if(duty<=50)
          {
            
            i=duty=0;
            
          }
          OCR1A = duty;  
        
      }
              
    }  
          
  }
  
  return 0;
}



 

반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 5. 15. 13:29

16비트 타이머 카운터 CTC모드, STOPWATCH 만들기

 

================================ Outline ====================================

16비트 타이머 카운터 CTC모드

STOPWATCH 만들기

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

<16비트 타이머 카운터 CTC모드>

 

일반 모드는 할당된 비트로 표현할 수 있는 값을 넘어가는 경우(overflow) 그 값이 다시 0으로 초기화되면서 인터럽트가 발생한다.

 

 

이에 반해 CTC(Clear Timer on Compare Match mode)TCNTnOCRnA 값을 비교하여 두 값이 일치할 때 인터럽트를 발생하도록 설정하는 방식이다.

 

일반 모드에서 TCNT모드를 설정할 때는 0이 아닌 숫자에게 카운터를 시작할 경우 그 값으로 도달하는데 클럭이 소모됨으로 따로 계산이 필요하다. CTC모드를 사용하면 이러한 번거로움을 막을 수 있다.

 

비교 모드를 사용하여 1초를 맞추는 공식,

 

1/16000000 * 분주비 * X = 1

 

X = 62500

 

OCRnX = X - 1 (0부터 숫자를 세기 때문에 -1을 해주어야 한다.)

 

 

 

<STOPWATCH 만들기>

 

표준시간에 근접하여 작동하는 16비트 타이머/카운터를 활용하여 STOPWATCH를 만들어 보자.

 

밀리초까지 표현해 주어야 하기 때문에 분주비를 1초에 100으로 만든다.

 

1/16000000 * 분주비 * X = 100

 

X = 625

 

OCRnX = X - 1 (0부터 숫자를 세기 때문에 -1을 해주어야 한다.)

 

그러므로 OCR0A = 624이다.

 

** interrupt 설정을 위한 레지스터 코딩에 유의하자!

 

/*** 소스 ***/

<main.c>

#include "SMART.h"
#include "LCD.h"

#define init 48

// 시간 define하여 입력 //

unsigned char ucMin2 = init;
unsigned char ucMin1= init;
unsigned char ucSec2 = init;
unsigned char ucSec1 = init;
unsigned char ucMSec2 = init;
unsigned char ucMSec1 = init;

int main(void)
{
  /* 변수 설정 */

  
  /* PORT 설정 */
  DDRE = 0xCF;
  DDRC = 0xFF;
  DDRG = 0xFF;


  /*  레지스터 설정 */

  // 16 BIT Timer/Counter //

  TCCR1A   = 0X00;//0B 0000 0000 -> CTC MODE, NO PWM MODE
  TCCR1B   = 0X0C;//0B 0000 1001 -> FALLING EDGE, CTC MODE, 1 분주
  TCCR1C  = 0X00;//0B 0000 0000 -> BLOCK COMPARE MODE
  OCR1AH = 0X02;//0B 0000 0010
  OCR1AL  = 0X70;// 0B 0111 0000 
  TCNT1H  = 0X00;//0B 0000 0000 -> START FROM 0
  TCNT1L  = 0X00;//0B 0000 0000 -> START FROM 0
  TIMSK1   = 0X02;// 0B 0000 0011 -> Compare mode REGISTER ENABLE
  TIFR1  = 0X00;// 0B 0000 0000 ->BIT CLEAR, FLACK BIT CLEAR
  

  TCNT1H = TCNT1L >> 8;

  EIMSK = 0x30;
  EICRA = 0x00;
  EICRB = 0x0F;

  SREG   |=0X80;// 0B 1000 0000 -> GLOBAL INTERRUPT ENABLE
  while(1)
  {  

    ;
    
  }

  return 0;
}

void __vector_5(void)
{
  SREG &= 0x7F;
  TIMSK1 ^= 0x02;
  SREG |= 0x80;

}

void __vector_6(void)
{
  ucMin2 = init;
  ucMin1= init;
  ucSec2 = init;
  ucSec1 = init;
  ucMSec2 = init;
  ucMSec1 = init;;

}
void __vector_17(void)
{
  LCD_Init();
  LCD_PRINT("    STOP WATCH");
  LCD_INST(0xC0);
  LCD_Data(' ');
  LCD_Data(' ');
  LCD_Data(' ');
  
  LCD_Data('[');
  LCD_Data(ucMin2);
  LCD_Data(ucMin1);
  LCD_Data(':');
  LCD_Data(ucSec2);
  LCD_Data(ucSec1);
  
  LCD_Data(':');

  LCD_Data(ucMSec2);
  LCD_Data(ucMSec1);
  LCD_Data(']');  
  
  ++ucMSec1;
  
  if(ucMSec1==58)
    ++ucMSec2;
  
  if((ucMSec1==58& (ucMSec2 ==58))
    ++ucSec1;

  if(ucSec1==58)
    ucSec2++;
  
  if((ucSec2 == 54& (ucSec1 == 58))
    ++ucMin1;
  
  if(ucMin1 == 58)
    ++ucMin2;
  

  if(ucMin2==54)
    ucMin2=48;
  
  if(ucMin1==58)
    ucMin1=48;
  
  if(ucSec2 == 54)
    ucSec2=48;

  if(ucSec1==58)
    ucSec1=48;
  
  if(ucMSec2==58)
    ucMSec2=48;
  
  if(ucMSec1 == 58)
    ucMSec1=48;

  

}

** SMART.h에 인터럽트의 prototype을 추가한 것을 제외하고는 기존 파일과 동일하다.

 

/*** 동영상 ***/




 

반응형

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

16 bit PC PWM  (0) 2015.05.18
16비트 타이머/카운터 시계  (0) 2015.05.14
16비트 타이머/카운터  (2) 2015.05.13
스위치 입력 시간에 따른 차등 실행  (0) 2015.05.12
AVR 인공호흡법, 아날로그 비교기  (0) 2015.05.08
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 5. 14. 11:50

6비트 타이머/카운터 시계

================================ Outline ====================================

16비트 타이머/카운터 시계

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

 

지난 시간에 이어 시간 부분까지 코딩을 하여 디지털 시계를 만들어보자.


 

TCNT레지스터와 분주비를 활용하여 인터럽트를 동작 시간을 설정하고 나면 시계 동작에 대한 코딩은 이미 학습한 내용임으로 간단하다.

 

/*** 코딩 ***/

#include "SMART.h"
#include "LCD.h"

#define init 48 //48 = '0', 50 = '2', 52 = '4', 54 = '6',  57 = '9'
#define hour2 49
#define hour1 49
#define min2 56
#define min1 51



// 시간 define하여 입력 //

unsigned char ucHour2 = hour2;
unsigned char ucHour1= hour1;
unsigned char ucMin2 = min2;
unsigned char ucMin1 = min1;
unsigned char ucSec2 = init;
unsigned char ucSec1 = init;




int main(void)
{
  /* 변수 설정 */

  
  /* PORT 설정 */
  DDRC = 0xFF;
  DDRG = 0xFF;


  /*  레지스터 설정 */

  // 16 BIT Timer/Counter //

  TCCR1A   = 0X00;//0B 0000 0000 -> NORMAL MODE, NO PWM MODE
  TCCR1B   = 0X84;//0B 1000 0001 -> FALLING EDGE, NORMAL MODE, 1 분주
  TCCR1C  = 0X00;//0B 0000 0000 -> BLOCK COMPARE MODE
  TCNT1H  = 0X00;//0B 0000 0000 -> START FROM 0
  TCNT1L  = 0X00;//0B 0000 0000 -> START FROM 0
  TIMSK1   = 0X01;// 0B 0000 0001 -> OVERFLOW REGISTER ENABLE
  TIFR1  = 0X00;// 0B 0000 0000 ->BIT CLEAR, FLACK BIT CLEAR
  SREG   |=0X80;// 0B 1000 0000 -> GLOBAL INTERRUPT ENABLE

  TCNT1H = TCNT1L >> 8;

    
  
  while(1)
  {  

    ;
    
  }

  return 0;
}

void __vector_20(void)
{
  LCD_Init();
  LCD_PRINT("   DIGITAL WATCH");
  LCD_INST(0xC3);
 
  LCD_Data('[');
  LCD_Data(ucHour1);
  LCD_Data(ucHour2);
  
  LCD_Data(':');
  LCD_Data(ucMin1);
  LCD_Data(ucMin2);
  
  LCD_Data(':');
  LCD_Data(ucSec1);
  LCD_Data(ucSec2);
  LCD_Data(']');  

  ++ucSec2;
  
  if(ucSec2==58)
    ++ucSec1;
  
  if((ucSec1==54& (ucSec2 ==58))
    ++ucMin2;

  if(ucMin2==58)
    ucMin1++;
  
  if((ucMin1 == 54& (ucMin2 == 58))
    ++ucHour2;
  
  if(ucHour2 == 58)
    ++ucHour1;
  

  if((ucHour1==50)  & (ucHour2==52))
  {
    ucHour1=48;
    ucHour2=48;
  }

  if(ucHour2==58)
    ucHour2=48;
  
  if(ucMin1 == 54)
    ucMin1=48;

  if(ucMin2==58)
    ucMin2=48;
  
  if(ucHour2==58)
    ucHour2=48;
  
  if(ucSec1 == 54)
    ucSec1=48;

  if(ucSec2==58)
    ucSec2=48;

}


** 기타 파일들은 지난 시간에 올린 것과 동일 




 

 

반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 5. 13. 13:44

16비트 타이머/카운터

 

================================ Outline ====================================

16비트 타이머/카운터

16비트 타이머/카운터를 활용한 디지털 시계 만들기

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

 

<16비트 타이머/카운터>

 

p/189 타이머/카운터 1, 3, 4, 5

 

8bit 레지스터와 달리 타이머/카운터 레지스터가 16bit(high/low)로 구성 되어 있다.

때문에 highlow레지스터를 붙이는 작업만 추가해주면 16bit 타이머/카운터를 사용할 수 있다.

 

16bit 타이머/카운터는 카운터를 할 수 있는 최대수가 65,535이기 때문에 분주비를 활용하면 한번에 1초를 잴 수 있는 타이머를 만들 수 있다.

 

Atmega 256016000000 클록임으로, 256분주와 16bit의 최대 값인 65,536을 이용하면,



1초에 1.048576번 작동하는 타이머를 만들 수 있다.

 

이 때 오버플로우 인터럽터의 TCNT1은 상위 8bit와 하위 8bit로 나누어져 있는데 이것을 합쳐주기 위한 작업이 필요하다.

이 때 하위 비트의 값을 우측으로 8개 밀어 넣은 값을 상위 비트에 대입하거나, 혹은 하위 비트의 레지스터 값을 정의할 때 char형이 아닌 int형으로 해주면 하위 비트 값에 16bit 값이 모두 대입가능하다.

 

//이동 연산의 경우 (대상) >> or << 옮기고 싶은 bit


/*** 16bit 타이머/카운터를 활용한 1초 LED 깜빡임 ***/



<16비트 타이머/카운터를 활용한 디지털 시계 만들기>


/*** 소스 ***/

<main.c>

#include "SMART.h"
#include "LCD.h"

unsigned char ucMin2=48;
unsigned char ucMin1=48;
unsigned char ucSec2=48;
unsigned char ucSec1=48;

int main(void)
{
  /* 변수 설정 */

  
  /* PORT 설정 */
  DDRB = 0xFF;


  /*  레지스터 설정 */

  // 16 BIT Timer/Counter //

  TCCR1A   = 0X00;//0B 0000 0000 -> NORMAL MODE, NO PWM MODE
  TCCR1B   = 0X84;//0B 1000 0100 -> FALLING EDGE, NORMAL MODE, 256 분주
  TCCR1C  = 0X00;//0B 0000 0000 -> BLOCK COMPARE MODE
  TCNT1H  = 0X00;//0B 0000 0000 -> START FROM 0
  TCNT1L  = 0X00;//0B 0000 0000 -> START FROM 0
  TIMSK1   = 0X01;// 0B 0000 0001 -> OVERFLOW REGISTER ENABLE
  TIFR1  = 0X00;// 0B 0000 0000 ->BIT CLEAR, FLACK BIT CLEAR
  SREG   |=0X80;// 0B 1000 0000 -> GLOBAL INTERRUPT ENABLE

  TCNT1H = TCNT1L >> 8;

    
  
  while(1)
  {  

    
    
  }

  return 0;
}

void __vector_20(void)
{
  LCD_Init();
  LCD_PRINT("  DIGITAL WATCH");
  LCD_INST(0xC0);
  LCD_Data(' ');
  LCD_Data(' ');
  LCD_Data(' ');
  
  LCD_Data('[');
  LCD_Data('0');
  LCD_Data('0');
  LCD_Data(':');
  LCD_Data(ucMin1);
  LCD_Data(ucMin2);
  
  LCD_Data(':');

  LCD_Data(ucSec1);
  LCD_Data(ucSec2);
  LCD_Data(']');  
  ++ucSec2;
  
  if(ucSec2==58)
    ucSec1++;
  if(ucSec1==54 & ucSec2 ==58)
  ++ucMin2;
  
  if(ucSec2==58 & ucSec1 == 54)
    ucSec1=48;

  if(ucSec2==58)
    ucSec2=48;

  
  

  if(ucMin2==58)
    ucMin1++;

  if(ucMin2==58 & ucMin1 == 54)
    ucMin1=48;

  if(ucMin2==58)
    ucMin2=48;
  

}

<LCD.h>

#ifndef __LCD_H__
#define __LCD_H__

#include "SMART.H"

#define  LCD_BUS  PORTC
#define  LCD_CTL    PORTG

#define  LCD_BUS_DDR  DDRC
#define  LCD_CTL_DDR  DDRG

#define  LCD_PIN_RS  0 
#define  LCD_PIN_RW  1
#define  LCD_PIN_EN  2

#define  LCD_INST_CLR  0x01 //화면 지우기
#define  LCD_INST_HOME  0x02 //커서 홈
#define  LCD_INST_ENT  0x06 //Increase mode(I/D=1), 쉬프트 ON(S=0)
#define  LCD_INST_DSP  0x0//화면 보이게(1), 커서표시(1),  커서(깜빡 거림)
#define  LCD_INST_CUR  0x14 // 
#define  LCD_INST_FUNC  0x38 




void LCD_AVR_PIN_INIT(void);
void LCD_INST(unsigned char ucInst);
void LCD_Data(unsigned char ucData);
void LCD_Init(void);
void LCD_PRINT(const unsigned char * ucString);
void USART0_INIT(void);
void USART1_INIT(void);
void INIT(void);
void USART0_TX( unsigned char ucData );
void USART1_TX( unsigned char ucData );
void TEST_LCD(void);
void LCD_SetAddr(unsigned char);
void LCD_MYNAME(void);
void LCD_CGRom_Read(unsigned char);
void LCD_CGRom_Write(unsigned char);


#endif //__LCD_H__

<LCD.c>

#include "LCD.h"
#include "SMART.h"

//Wide variable
static unsigned int uiCharCnt;



// LCD driver 프로그램 작성

void LCD_AVR_PIN_INIT(void)
{
  LCD_BUS_DDR = 0xFF;
  LCD_CTL_DDR = (1<<LCD_PIN_RS) |  (1<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x07
  
  
  return;
}

void LCD_INST(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

}


void LCD_Data(unsigned char ucData)

{
  volatile unsigned int uiCnt;

  LCD_BUS=ucData;

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN);

  Delay(500); //4//10ns 지연

}

void LCD_Init(void)
  
{
  
  
  volatile unsigned int uiCnt;

  LCD_AVR_PIN_INIT();

  Delay(500); // ATmega가 LCD보다 구동이 먼저 되는 경우를 대비하여 넣어주는 딜레이 코드  

  LCD_INST(LCD_INST_FUNC);
  LCD_INST(LCD_INST_DSP);
  LCD_INST(LCD_INST_ENT);
  LCD_INST(LCD_INST_CUR);
  LCD_INST(LCD_INST_CLR);
  LCD_INST(LCD_INST_HOME);

  uiCharCnt = 0;
  

  return;
}

void LCD_PRINT(const unsigned char * ucString)
{
  for(;*ucString != 0; ++ucString)
  {
    LCD_Data(*ucString);
    
  }
  
  return
}

void LCD_SetAddr(unsigned char ucAddr)
{
  if(ucAddr>15)
  {
    if(ucAddr<40)
    {
      ucAddr = 40;
    }  
    else if(ucAddr>55)
    {
      ucAddr = 0;

    }
  }
  
  

  LCD_INST(0x80|ucAddr);
  
}

void LCD_CGRom_Write(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

}
void LCD_CGRom_Read(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (1<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연
}


void LCD_MYNAME(void)
{
  volatile unsigned int vuiCnt;
  unsigned char font[] =
  {
      0x0A, 0x040x000x000x000x000x1F, 0x00,  // 0.second char ㅡ  
      0x0E, 0x000x1f, 0x000x040x0a, 0x0a, 0x04,  // 1. forth char ㅎ 
      0x100x100x100x100x100x100x100x10,  // 2. fifth char ㅣ
      0x1F, 0x0A, 0x0A, 0x0A, 0x000x100x1F, 0x00,  // 3. sixth char ㅠㄴ 
      0x120x120x1E, 0x120x120x120x000x00,  // 4. eighth char ㅐ
      0x040x0A, 0x110x0A, 0x040x000x1F, 0x00,  // 5. nineth char ㅇ ㅡ
  
  };
  for(vuiCnt=0; vuiCnt<42; ++vuiCnt)
    LCD_Data(font[vuiCnt]);
    
}

void LCD_Cnt(unsigned char ucData)

{
  volatile unsigned int uiCnt;
  

  LCD_BUS=ucData;

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN);

  Delay(500); //4//10ns 지연

  ucData++;

}
  
#include "LCD.h"
#include "SMART.h"

//Wide variable
static unsigned int uiCharCnt;



// LCD driver 프로그램 작성

void LCD_AVR_PIN_INIT(void)
{
  LCD_BUS_DDR = 0xFF;
  LCD_CTL_DDR = (1<<LCD_PIN_RS) |  (1<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x07
  
  
  return;
}

void LCD_INST(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

}


void LCD_Data(unsigned char ucData)

{
  volatile unsigned int uiCnt;

  LCD_BUS=ucData;

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN);

  Delay(500); //4//10ns 지연

}

void LCD_Init(void)
  
{
  
  
  volatile unsigned int uiCnt;

  LCD_AVR_PIN_INIT();

  Delay(500); // ATmega가 LCD보다 구동이 먼저 되는 경우를 대비하여 넣어주는 딜레이 코드  

  LCD_INST(LCD_INST_FUNC);
  LCD_INST(LCD_INST_DSP);
  LCD_INST(LCD_INST_ENT);
  LCD_INST(LCD_INST_CUR);
  LCD_INST(LCD_INST_CLR);
  LCD_INST(LCD_INST_HOME);

  uiCharCnt = 0;
  

  return;
}

void LCD_PRINT(const unsigned char * ucString)
{
  for(;*ucString != 0; ++ucString)
  {
    LCD_Data(*ucString);
    
  }
  
  return
}

void LCD_SetAddr(unsigned char ucAddr)
{
  if(ucAddr>15)
  {
    if(ucAddr<40)
    {
      ucAddr = 40;
    }  
    else if(ucAddr>55)
    {
      ucAddr = 0;

    }
  }
  
  

  LCD_INST(0x80|ucAddr);
  
}

void LCD_CGRom_Write(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

}
void LCD_CGRom_Read(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (1<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연
}


void LCD_MYNAME(void)
{
  volatile unsigned int vuiCnt;
  unsigned char font[] =
  {
      0x0A, 0x040x000x000x000x000x1F, 0x00,  // 0.second char ㅡ  
      0x0E, 0x000x1f, 0x000x040x0a, 0x0a, 0x04,  // 1. forth char ㅎ 
      0x100x100x100x100x100x100x100x10,  // 2. fifth char ㅣ
      0x1F, 0x0A, 0x0A, 0x0A, 0x000x100x1F, 0x00,  // 3. sixth char ㅠㄴ 
      0x120x120x1E, 0x120x120x120x000x00,  // 4. eighth char ㅐ
      0x040x0A, 0x110x0A, 0x040x000x1F, 0x00,  // 5. nineth char ㅇ ㅡ
  
  };
  for(vuiCnt=0; vuiCnt<42; ++vuiCnt)
    LCD_Data(font[vuiCnt]);
    
}

void LCD_Cnt(unsigned char ucData)

{
  volatile unsigned int uiCnt;
  

  LCD_BUS=ucData;

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN);

  Delay(500); //4//10ns 지연

  ucData++;

}
  

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

/* USART */
#define UCSR0A  (*((volatile unsigned char*)0xC0))
#define UCSR0B  (*((volatile unsigned char*)0xC1))
#define UCSR0C  (*((volatile unsigned char*)0xC2))
#define  UCSR1A  (*((volatile unsigned char*)0xC8))
#define  UCSR1B  (*((volatile unsigned char*)0xC9))
#define  UCSR1C  (*((volatile unsigned char*)0xCA))

#define UBRR0H  (*((volatile unsigned char*)0xC5))
#define UBRR0L  (*((volatile unsigned char*)0xC4))
#define  UBRR1H  (*((volatile unsigned char*)0xCD))
#define  UBRR1L  (*((volatile unsigned char*)0xCC))

#define UDR0    (*((volatile unsigned char*)0xC6))
#define  UDR1  (*((volatile unsigned char*)0xCE))


// UCSR0A 레지스터
#define  RXC    7
#define  TXC    6
#define  UDRE  5
#define  FE    4
#define  DOR    3
#define  UPE    2
#define  U2X   1
#define  MPCM   0

// UCSR0B 레지스터
#define  RXCIE  7
#define  TXCIE  6
#define  UDRIE  5
#define  RXEN  4
#define  TXEN  3
#define  UCSZ2  2
#define  RXB8   1
#define  TXB8   0

// UCSR0C 레지스터
#define  UMSEL  6
#define  UPM1  5
#define  UPM0  4
#define  USBS  3
#define  UCSZ1  2
#define  UCSZ0   1
#define  UCPOL   0

/* A/D컨버터 레지스터 */

#define ADCSRA  (*((volatile unsigned char*)0x7A))
#define ADCSRB  (*((volatile unsigned char*)0x7B))
#define ADMUX  (*((volatile unsigned char*)0x7C))
#define ADCH    (*((volatile unsigned char*)0x79))
#define ADCL    (*((volatile unsigned char*)0x78))
#define DIDR0  (*((volatile unsigned char*)0x7E))
#define DIDR1  (*((volatile unsigned char*)0x7F))
#define DIDR2  (*((volatile unsigned char*)0x7D))

/* Analog Comparator Register */

#define ACSR    (*((volatile unsigned char*)0x50))

/* 16 bit Timer/Counter Register */

#define TCCR1A  (*((volatile unsigned char*)0x80))
#define TCCR3A  (*((volatile unsigned char*)0x90))
#define TCCR4A  (*((volatile unsigned char*)0xA0))
#define TCCR5A  (*((volatile unsigned char*)0x120))

#define TCCR1B  (*((volatile unsigned char*)0x81))
#define TCCR3B  (*((volatile unsigned char*)0x91))
#define TCCR4B  (*((volatile unsigned char*)0xA1))
#define TCCR5B  (*((volatile unsigned char*)0x121))

#define TCCR1C  (*((volatile unsigned char*)0x82))
#define TCCR3C  (*((volatile unsigned char*)0x92))
#define TCCR4C  (*((volatile unsigned char*)0xA2))
#define TCCR5C  (*((volatile unsigned char*)0x122))

#define GTCCR  (*((volatile unsigned char*)0x43))

#define TCNT1H  (*((volatile unsigned char*)0x85))
#define TCNT1L  (*((volatile unsigned char*)0x84))


#define TCNT3H  (*((volatile unsigned char*)0x95))
#define TCNT3L  (*((volatile unsigned char*)0x94))

#define TCNT4H  (*((volatile unsigned char*)0xA5))
#define TCNT4L  (*((volatile unsigned char*)0xA4))

#define TCNT5H  (*((volatile unsigned char*)0x125))
#define TCNT5L  (*((volatile unsigned char*)0x124))

#define OCR1AH  (*((volatile unsigned char*)0x89))
#define OCR1AL  (*((volatile unsigned char*)0x88))

#define OCR1BH  (*((volatile unsigned char*)0x8B))
#define OCR1BL  (*((volatile unsigned char*)0x8A))

#define OCR1CH  (*((volatile unsigned char*)0x8D))
#define OCR1CL  (*((volatile unsigned char*)0x8C))

#define ICR1H  (*((volatile unsigned char*)0x87))
#define ICR1L  (*((volatile unsigned char*)0x86))

#define ICR3H  (*((volatile unsigned char*)0x97))
#define ICR3L  (*((volatile unsigned char*)0x96))

#define ICR4H  (*((volatile unsigned char*)0xA7))
#define ICR4L  (*((volatile unsigned char*)0xA6))

#define ICR5H  (*((volatile unsigned char*)0x127))
#define ICR5L  (*((volatile unsigned char*)0x126))

#define TIMSK1  (*((volatile unsigned char*)0x6F))
#define TIMSK3  (*((volatile unsigned char*)0x71))
#define TIMSK4  (*((volatile unsigned char*)0x72))
#define TIMSK5  (*((volatile unsigned char*)0x73))

#define TIFR1  (*((volatile unsigned char*)0x36))
#define TIFR3  (*((volatile unsigned char*)0x38))
#define TIFR4  (*((volatile unsigned char*)0x39))
#define TIFR5  (*((volatile unsigned char*)0x3A))






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

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

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

/* 함수의 원형 */

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



#endif //__SMART_H__


*** 시 단위는 코드는 다음 시간에...


반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 5. 12. 12:34

스위치 입력 시간에 따른 차등 실행

================================ Outline ====================================

스위치 입력 시간에 따른 차등 실행

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

 

<스위치 입력 시간에 따른 차등 실행>

 

 

I. 서술

 

스위치를 입력 받아 3초 이하 시간을 입력하고 있을 경우와 3초 이상의 시간을 입력하고 있을 때의 실행 값이 다르도록 코딩을 해본다.

 

II. 작업 나누기

 

1. 인터럽트가 제대로 작동하는지 확인한다.

 

2. 시간 차등을 위해 시간을 설정하기 위한 코딩을 한다.

- 3초 이하는 PORTA 4ON

- 3초 이상은 PORTA 5ON

 

3. 조건문을 사용하여 스위치를 눌렀다가 떼었을 때 출력 값이 나오도록 한다.

 

 

III. 코딩 및 실행

 

1. 인터럽트 작동 확인 -> 작동한다.

 

2. 시간 차등을 위한 코딩

- 3초 이하: 4번핀 ON

- 3초 이상: 5번핀 ON

 

-> 4번 핀의 값에 불이 들어오는 것은 확인했지만 3초 이상 시 5번 핀에 불이 들어오지 않는다.

 

!!! PORT A초기화 설정에서 DDRA = 0xF0; 값을 입력한 결과 0~3번 핀이 모두 입력으로 되어 입력 값을 넣어주지 않은 핀은 floating 상태가 되어 카운터를 위한 조건문에 값이 입력되지 않았다.

 

/*** 회로도 ***/



 

/*** 소스 ***/

<main.c>

#include "SMART.h"
#include "LCD.h"

volatile unsigned int uiCnt;
volatile unsigned char ucPin;
volatile unsigned int uipCnt=0;
volatile unsigned char ucSign=0;

int main(void)
{
  /* 변수 설정 */

  
  /* PORT 설정 */
  DDRA = 0x3E;  // PORTA, 0~3핀은 입력 4~7은 출력 

  
  


  /*  레지스터 설정 */
  // Timer/Counter //
  SREG = 0x7F;    // Global Interrupt Disable
  TCCR0A = 0x00;  // Normal mode, PWM inactive
  TCCR0B = 0x05;  // 분주비 설정: 1024분주
  TCNT0 = 0x00;  // Counter 0부터 시작. 
  TIMSK0 = 0x01;  // Overflow interrupt enable
  TIFR0 = 0x00;    // Clear interrupt flag
  SREG |= 0x80;  // Global interrupt enable

  
  while(1)
  {
    while(ucPin >= 0x01)
    {
    
      
      while(1)
      {
        ucPin = PINA;
        while(ucPin == 0x00)
        {  
          if(ucSign>3)
          {
            PORTA = 0x20;

          }
          

          else
          {
            PORTA = 0x10;

          }
          


        }
        
      }
      
      
    
      
          
          
    }
    
    
    
    
    
    
  }
  return 0;
}

void __vector_23(void)
{
  ucPin = PINA;
  if(ucPin>=0x01)
    ++uipCnt;

  if(uipCnt >= 10)
    ++ucSign;

}

 

/*** 실행 ***/


반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 5. 8. 13:24

AVR 인공호흡법, 아날로그 비교기

 

================================ Outline ====================================

인공호흡을 위한 하드웨어 준비

아날로그 비교기

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

 

<인공호흡을 위한 하드웨어 준비>

 

- 부품 준비

전자부품 쇼핑몰에 가서 OSC 1Mhz를 구매한다.(이 때, 사용 가능한 크리스탈은 1-4MHz를 권장한다.)

 

- 선들의 결선 방법

OCS7번은 AVRGND핀에, 14번은 AVRVCC핀에, 8번은 XTAL1핀에 연결한다.

 

AVR Studio를 실행하고,

 

 

인공호흡 완료

- 모듈의 전원을 끈다.

-모듈에서 오실레이터를 제거한다.

-떼어 두었던 크리스탈을 모듈의 원위치에 붙인다.

 

AVR 교재 p/296쪽 읽고 정리할 필요가 있다.

 

<아날로그 비교기>

 

AIN0 - 양극성 입력

AIN1 - 음극성 입력

 

// AVR 공부 시, 레지스터의 기능을 정리해 놓아야 한다.

 

아날로그 비교기 제어 및 상태 레지스터(ACSR:Analog Comparator Control and Status Register)

 

비트 7 - 아날로그 비교기의 동작을 금지시키는 비트(1 = 비교기 동작 정지)

 

비트 6 - 아날로그 비교기의 양극성 입력에 인가되는 전압 선택(1 = 양극성 입력(AIN0에는 1.1v, 0 = AIN0 단자로 입력되는 전압이 선택)

 

비트 5 - 아날로그 비교기의 출력값으로서 클록과 동기되어 발생

비트 4 - 아날로그 비교기의 인터럽트 발생 플랙(1 = 비트 강제 클리어 -> 0으로 변화)

 

비트 3 - 아날로그 비교기 인터럽트 발생을 개별적으로 허용하는 비트

 

비트 2 - 아날로그 비교기 출력이 타이머/카운터1의 입력캡쳐 트리거 신호로 사용되도록 설정

 

비트 1 ~ 0 - 인터럽트 발생 모드 설정

 

A/D 컨버터 제어 및 상태 레지스터 B(ADCSRB: Analog Comparator Multiplexer Enable)

비트 6 - 아날라고 비교기의 음극성 입력에 A/D 컨버터의 입력 신호가 사용될 수 있도록 허용(1 & ACDSRC 레지스터의 ADEN = 0으로 설정하면 A/D 컨버터의 동작이 정지되고 ADC0 ~ ADC15의 입력 신호가 아날로그 비교기의 음극성 입력으로 사용된다. 0 = 음극성 입력에는 무조건 AIN1로 입력된 전압이 사용된다.)

 

디지털 입력 금지 레지스터 1(DIDR1: Digital Input Disable Register 1)

 

비트 1 ~ 0 - 각각 AIN1 AIN0 단자에서 디지털 입력을 금지시킨다. 디지털 입력을 금지하면 해당 PINx 레지스터를 읽었을 때 디지털 값이 0으로 읽혀진다.

 

 

/*** 소스 ***/

<main.c>

#include "SMART.h"

int main(void)
{
  /* 변수 설정 */

  
  /* PORT 설정 */
  DDRA =     0xFF; //PORTA 출력 설정


  /* Analog 비교기  레지스터 설정 */

  ACSR =     0x43// +입력 = 1.1v
  ADCSRA =   0x00// ADEN =0
  ADCSRB =   0x40// ACME =1
  ADMUX =   0x01// -입력 = ADC1
    
  while(1)
  {
    if((ACSR & 0x20== 0x20)
    {
      PORTA = 0xF0;
    
    }
    else
    {
      PORTA = 0x0F;
    
    }
  }
  

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


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

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

/* USART */
#define UCSR0A  (*((volatile unsigned char*)0xC0))
#define UCSR0B  (*((volatile unsigned char*)0xC1))
#define UCSR0C  (*((volatile unsigned char*)0xC2))
#define  UCSR1A  (*((volatile unsigned char*)0xC8))
#define  UCSR1B  (*((volatile unsigned char*)0xC9))
#define  UCSR1C  (*((volatile unsigned char*)0xCA))

#define UBRR0H  (*((volatile unsigned char*)0xC5))
#define UBRR0L  (*((volatile unsigned char*)0xC4))
#define  UBRR1H  (*((volatile unsigned char*)0xCD))
#define  UBRR1L  (*((volatile unsigned char*)0xCC))

#define UDR0    (*((volatile unsigned char*)0xC6))
#define  UDR1  (*((volatile unsigned char*)0xCE))


// UCSR0A 레지스터
#define  RXC    7
#define  TXC    6
#define  UDRE  5
#define  FE    4
#define  DOR    3
#define  UPE    2
#define  U2X   1
#define  MPCM   0

// UCSR0B 레지스터
#define  RXCIE  7
#define  TXCIE  6
#define  UDRIE  5
#define  RXEN  4
#define  TXEN  3
#define  UCSZ2  2
#define  RXB8   1
#define  TXB8   0

// UCSR0C 레지스터
#define  UMSEL  6
#define  UPM1  5
#define  UPM0  4
#define  USBS  3
#define  UCSZ1  2
#define  UCSZ0   1
#define  UCPOL   0

/* A/D컨버터 레지스터 */

#define ADCSRA  (*((volatile unsigned char*)0x7A))
#define ADCSRB  (*((volatile unsigned char*)0x7B))
#define ADMUX  (*((volatile unsigned char*)0x7C))
#define ADCH    (*((volatile unsigned char*)0x79))
#define ADCL    (*((volatile unsigned char*)0x78))
#define DIDR0  (*((volatile unsigned char*)0x7E))
#define DIDR1  (*((volatile unsigned char*)0x7F))
#define DIDR2  (*((volatile unsigned char*)0x7D))

/* Analog Comparator Register */

#define ACSR    (*((volatile unsigned char*)0x50))




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

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

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

/* 함수의 원형 */
unsigned char RX0_scan(void);
unsigned char RX0_char(void);
void TX0_char(unsigned char);
void TX0_string(char *);



#endif //__SMART_H__


반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 5. 7. 13:49

A/D 컨버터와 조도 센서를 활용한 코딩





/*** 소스 ***/


<main.c>


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


int main(void)
{
  /* 변수 설정 */

  unsigned int i;
  unsigned char sum;    
  unsigned char ucVolt;
  volatile unsigned int uiCnt;
  char cCnt;
  unsigned char cH;
  unsigned char cT;
  unsigned char cU;
  unsigned char * ucP;
  
  /* PORT 설정 */
  DDRF = 0xFE;    // F Port 0번 핀 입력
  DDRC = 0xFF;  // C Port 모두 출력
  DDRG = 0xFF;  // G Port 모두 출력
  

  /* ADC 레지스터 설정: 초기화 */

  //ADCSRA = 0x00;  // disable adc
  ADCSRA = 0x85;     // Enable adc, 분주비 32-> 500kHz
  ADCSRB = 0x00;    // free running mode
  ADMUX   = 0x40;     // select adc input 0

  LCD_Init();

  
  
  while(1)
  {
    sum = 0;
    for(i=0; i<16; ++i)
    {
      ADCSRA = 0xD5;
      while((ADCSRA & 0x10) != 0x10);
      sum += ((((int) ADCH<<8))+(int)ADCL);  
      // 두개의 레지스터는 한 byte씩 차지하고 있기 때문에 
      // 상위 비트와 하위 비트를 구분하기 위한 코드
      
    }
    sum >>= 4;  // sum = sum / 16, 아날로그 신호의 평균값을 내준다.
    ucP = &sum;

    LCD_PRINT(ucP);

    ucVolt = (unsigned char)((5*sum)/1024);
    
    cH = (ucVolt/100)+48;
    cT = (ucVolt%100)/10+48;
    cU = ucVolt%10+48;

    LCD_PRINT("Please wait");
    
    cCnt=0;
    while(cCnt<3)
    {
      LCD_Data('.');
      Delay();
      cCnt++;
    }

    LCD_PRINT(ucP);

    
      
    LCD_Init();

    LCD_PRINT("Value = ");
    LCD_Data(cH);
    LCD_Data(cT);
    LCD_Data(cU);

    LCD_Init();
  
      
  }
  

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


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

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

/* USART */
#define UCSR0A  (*((volatile unsigned char*)0xC0))
#define UCSR0B  (*((volatile unsigned char*)0xC1))
#define UCSR0C  (*((volatile unsigned char*)0xC2))
#define  UCSR1A  (*((volatile unsigned char*)0xC8))
#define  UCSR1B  (*((volatile unsigned char*)0xC9))
#define  UCSR1C  (*((volatile unsigned char*)0xCA))

#define UBRR0H  (*((volatile unsigned char*)0xC5))
#define UBRR0L  (*((volatile unsigned char*)0xC4))
#define  UBRR1H  (*((volatile unsigned char*)0xCD))
#define  UBRR1L  (*((volatile unsigned char*)0xCC))

#define UDR0    (*((volatile unsigned char*)0xC6))
#define  UDR1  (*((volatile unsigned char*)0xCE))


// UCSR0A 레지스터
#define  RXC    7
#define  TXC    6
#define  UDRE  5
#define  FE    4
#define  DOR    3
#define  UPE    2
#define  U2X   1
#define  MPCM   0

// UCSR0B 레지스터
#define  RXCIE  7
#define  TXCIE  6
#define  UDRIE  5
#define  RXEN  4
#define  TXEN  3
#define  UCSZ2  2
#define  RXB8   1
#define  TXB8   0

// UCSR0C 레지스터
#define  UMSEL  6
#define  UPM1  5
#define  UPM0  4
#define  USBS  3
#define  UCSZ1  2
#define  UCSZ0   1
#define  UCPOL   0

/* A/D컨버터 레지스터 */

#define ADCSRA  (*((volatile unsigned char*)0x7A))
#define ADCSRB  (*((volatile unsigned char*)0x7B))
#define ADMUX  (*((volatile unsigned char*)0x7C))
#define ADCH    (*((volatile unsigned char*)0x79))
#define ADCL    (*((volatile unsigned char*)0x78))
#define DIDR0  (*((volatile unsigned char*)0x7E))
#define DIDR1  (*((volatile unsigned char*)0x7F))
#define DIDR2  (*((volatile unsigned char*)0x7D))





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

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

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

/* 함수의 원형 */
unsigned char RX0_scan(void);
unsigned char RX0_char(void);
void TX0_char(unsigned char);
void TX0_string(char *);



#endif //__SMART_H__

<LCD.h>

#ifndef __LCD_H__
#define __LCD_H__

#include "SMART.H"

#define  LCD_BUS  PORTC
#define  LCD_CTL    PORTG

#define  LCD_BUS_DDR  DDRC
#define  LCD_CTL_DDR  DDRG

#define  LCD_PIN_RS  0 
#define  LCD_PIN_RW  1
#define  LCD_PIN_EN  2

#define  LCD_INST_CLR  0x01 //화면 지우기
#define  LCD_INST_HOME  0x02 //커서 홈
#define  LCD_INST_ENT  0x06 //Increase mode(I/D=1), 쉬프트 ON(S=0)
#define  LCD_INST_DSP  0x0//화면 보이게(1), 커서표시(1),  커서(깜빡 거림)
#define  LCD_INST_CUR  0x14 // 
#define  LCD_INST_FUNC  0x38 




void LCD_AVR_PIN_INIT(void);
void LCD_INST(unsigned char ucInst);
void LCD_Data(unsigned char ucData);
void LCD_Init(void);
void LCD_PRINT(const unsigned char * ucString);
void USART0_INIT(void);
void USART1_INIT(void);
void INIT(void);
void USART0_TX( unsigned char ucData );
void USART1_TX( unsigned char ucData );
void TEST_LCD(void);
void LCD_SetAddr(unsigned char);
void LCD_MYNAME(void);
void LCD_CGRom_Read(unsigned char);
void LCD_CGRom_Write(unsigned char);


#endif //__LCD_H__

<LCD.c>

#include "LCD.h"
#include "SMART.h"

//Wide variable
static unsigned int uiCharCnt;



// LCD driver 프로그램 작성

void LCD_AVR_PIN_INIT(void)
{
  LCD_BUS_DDR = 0xFF;
  LCD_CTL_DDR = (1<<LCD_PIN_RS) |  (1<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x07
  
  
  return;
}

void LCD_INST(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

}


void LCD_Data(unsigned char ucData)

{
  volatile unsigned int uiCnt;

  LCD_BUS=ucData;

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN);

  Delay(500); //4//10ns 지연

}

void LCD_Init(void)
  
{
  
  
  volatile unsigned int uiCnt;

  LCD_AVR_PIN_INIT();

  Delay(500); // ATmega가 LCD보다 구동이 먼저 되는 경우를 대비하여 넣어주는 딜레이 코드  

  LCD_INST(LCD_INST_FUNC);
  LCD_INST(LCD_INST_DSP);
  LCD_INST(LCD_INST_ENT);
  LCD_INST(LCD_INST_CUR);
  LCD_INST(LCD_INST_CLR);
  LCD_INST(LCD_INST_HOME);

  uiCharCnt = 0;
  

  return;
}

void LCD_PRINT(const unsigned char * ucString)
{
  for(;*ucString != 0; ++ucString)
  {
    LCD_Data(*ucString);
    
  }
  
  return
}

void LCD_SetAddr(unsigned char ucAddr)
{
  if(ucAddr>15)
  {
    if(ucAddr<40)
    {
      ucAddr = 40;
    }  
    else if(ucAddr>55)
    {
      ucAddr = 0;

    }
  }
  
  

  LCD_INST(0x80|ucAddr);
  
}

void LCD_CGRom_Write(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

}
void LCD_CGRom_Read(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (1<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연
}


void LCD_MYNAME(void)
{
  volatile unsigned int vuiCnt;
  unsigned char font[] =
  {
      0x0A, 0x040x000x000x000x000x1F, 0x00,  // 0.second char ㅡ  
      0x0E, 0x000x1f, 0x000x040x0a, 0x0a, 0x04,  // 1. forth char ㅎ 
      0x100x100x100x100x100x100x100x10,  // 2. fifth char ㅣ
      0x1F, 0x0A, 0x0A, 0x0A, 0x000x100x1F, 0x00,  // 3. sixth char ㅠㄴ 
      0x120x120x1E, 0x120x120x120x000x00,  // 4. eighth char ㅐ
      0x040x0A, 0x110x0A, 0x040x000x1F, 0x00,  // 5. nineth char ㅇ ㅡ
  
  };
  for(vuiCnt=0; vuiCnt<42; ++vuiCnt)
    LCD_Data(font[vuiCnt]);
    
}


반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 5. 6. 13:29

A/D 컨버터를 활용한 LCD에 문자 출력하기

 

================================ Outline ====================================

가변저항 읽는 법

ADC 잡음제거 방법

ADC 실습 - LCD에 문자 출력하기

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

 

 

지난 시간에 ATmega2560에서 입력 PORTA로 하였는데 F PORT로 수정해 주어야 제대로 출력이 될 것이다.

 

<ADC 실습 - LCD에 문자 출력하기>

 

ASCII Code를 이용하여 LCDABCD..를 차례대로 띄워보자.

 

<가변저항 읽는 법>

 

ex) 474

 

47 * 10

 

그러므로 470kΩ

 

가변 저항은 파여진 홈을 이용하여 저항 값을 조절할 수 있다. (turn)가 적은 가변 저항일수록 저항 값의 미세조정이 힘들고, 턴수가 많은 가변 저항일수록 미세조정이 가능하다.

 

클럭(clock)16MHz인 분주비가 32일 때 500kHz이다.

분주비가 빠를수록 빠른 속도로 입력 값을 읽어 들인다.


아날로그 입력은 크게 16가지의 단극성 입력과 44가지 종류의 차동입력으로 구분되고, 차동 입력은 다시 4가지의 경우로 나누어진다.

 

양자화 오차란,

 

표현 가능한 영역으로 데이터를 표현하였지만 실제 데이터와 차이가 나는 값을 일컫는다.

 

 

Thermocoupler K type

<AVR 교재 p/294 - 잡음제거 방법>

 

- 우선 가능한한 신호선을 짧게 하여 노이즈 발생 가능성을 낮춘다.

 

- 데이터선 주변에 GND로 감싸준다.

 

- 읽어 들인 값의 평균처리

 

<ADC 실습 - LCD에 문자 출력하기>

 

/*** 회로 ***/

 

/*** 코드 ***/

 

<main.c>

#include "SMART.h"
#include <Turboc.h>
#include <stdio.h>


int main(void)
{
  /* 변수 설정 */

  unsigned char i;
  unsigned int sum;    
  unsigned char ucASC=0;

  /* PORT 설정 */
  DDRF = 0xFE;    // F Port 0번 핀 입력
  DDRC = 0xFF;  // C Port 모두 출력
  DDRG = 0xFF;  // G Port 모두 출력
  

  /* ADC 레지스터 설정: 초기화 */

  //ADCSRA = 0x00;  // disable adc
  ADCSRA = 0x85;     // Enable adc, 분주비 32-> 500kHz
  ADCSRB = 0x00;    // free running mode
  ADMUX   = 0x40;     // select adc input 0

  LCD_Init();

  srand(rand(NULL));
  
  
  while(1)
  {
    sum = 0;
    for(i=0; i<16; ++i)
    {
      ADCSRA = 0xD5;
      while((ADCSRA & 0x10) != 0x10);
      sum += ((((int) ADCH<<8))+(int)ADCL);  
      // 두개의 레지스터는 한 byte씩 차지하고 있기 때문에 
      // 상위 비트와 하위 비트를 구분하기 위한 코드
      
    }
    sum >>= 4;  // sum = sum / 16, 아날로그 신호의 평균값을 내준다.

      while(PINF==0)
      {
        while(PINF == 1)
        {
          ucASC += PINF;
          sum = ucASC + 47;
          LCD_Data(sum);
          break;
        }
        
        if(sum== 58)
        {
          ucASC=0;
          break;
        }
    }
  }
  

  return 0;
}


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

A/C 컨버터

 

================================= Outline ===================================

A/C 컨버터

- 분해능의 정의

- A/D 컨버터의 사용 목적

- 디지털 신호의 장점

 

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

//USART의 대장급은 RS485이다.

 

//1024... 장이사=_=

 

AVR 교재 p/278,

 

“10비트 분해능...”이란,

 

0 - 5v10bit, 1024등분할 수 있다는 뜻이다.

 

 

<A/D 컨버터의 사용 목적>

 

연속적인 데이터는 지속적으로 데이터화하여 정확하게 표현하는 것은 불가능하다. 때문에 연속성을 포기하고 순간의 정지된 데이터를 잘게 끊어서 표현함으로써 연속된 자료와 유사하게 표현하기 위함이다.

 

<Digital 신호의 장점>

Analog신호에 비해 잡음에 강하다.

 


<서미스터(Thermistor)>

저항 값은 온도에 따라 변할 수 있다. 저항 소자가 금속으로 만들어져 있기 때문이다.

온도에 따라 저항 값이 바뀌는 소자를 thermistor라 하고 이를 활용하여 온도계를 만들 수 있다.

<A/D 컨버터 레지스터>

 

A/D 컨버터 제어 및 상태 레지스터 A(ADCSRA)

비트 7 - 1로 설정하면 A/D컨버터의 모든 동작이 허용되고 0으로 설정하면 모든 동작이 금지된다.

 

비트 6 - 1로 설정하면 A/D 컨버터의 변환이 시작된다. 변환이 완료되면 자동적으로 0으로 클리어 된다.

 

비트 5 - 1로 설정하면 외부 트리거 소스에 의해 소프트웨어적으로 A/D변환이 시작, 0으로 설정하면 ADSC비트에 의해서 A/D변환이 시작된다.

 

비트 4 - A/D변환이 완료되어 A/D 컨버터 데이터 레지스터 값이 갱신되고 나면 이것이 1로 셋트되면서 변환완료 인터럽트를 요청한다.

 

비트 3 - 변환완료 인터럽트를 개별적으로 허용한다. 인터럽트 허용을 위해 ADIE = 1, SREGI비트가 1로 설정되어 있어야 한다.

 

비트 2 - 0 - 분주비 설정

A/D 컨버터 제어 및 상태 레지스터 B(ADCSRB)

비트 6 - 아날로그 비교기의 음극성 입력에 A/D 컨버터의 입력신호가 사용될 수 있도록 허용한다.

 

비트 3 - MUX5ADMUX 레지스터의 MUX 4-0 비트와 함께 A/D컨버터의 아날로그 입력 채널을 선택한다.

 

비트 2 - 0


A/D 컨버터 멀티플렉서 선택 레지스터(ADMUX)



/* 소스 */

<main.c>

#include "SMART.h"
#include <Turboc.h>
#include <stdio.h>


int main(void)
{
  /* 변수 설정 */

  unsigned char i;
  unsigned int sum;    

  /* PORT 설정 */
  DDRA = 0xFE;    // A Port 0번 핀 입력
  DDRC = 0xFF;    // C Port 모두 출력
  DDRG = 0xFF;    // G Port 모두 출력
  

  /* ADC 레지스터 설정 */

  //ADCSRA = 0x00;  // disable adc
  ADCSRA = 0x85;     // Enable adc, 분주비 32
  ADCSRB = 0x00;    // free running mode
  ADMUX   = 0x40;     // select adc input 0

  LCD_Init();

  srand(rand(NULL));
  
  
  while(1)
  {
    sum = 0;
    for(i=0; i<16; ++i)
    {
      ADCSRA = 0xD5;
      while((ADCSRA & 0x10) != 0x10);
      sum += ((((int) ADCH<<8))+(int)ADCL);
    }
    sum >>= 4;  // sum = sum / 16, 아날로그 신호의 평균값을 내준다.

    for(i=0; i<100; ++i)
    {
      sum += srand;
      PORTC = sum;
    }
  }
  

  return 0;
}

<SMART.h>


/* A/D컨버터 레지스터 */


#define ADCSRA  (*((volatile unsigned char*)0x7A))

#define ADCSRB  (*((volatile unsigned char*)0x7B))

#define ADMUX  (*((volatile unsigned char*)0x7C))

#define ADCH    (*((volatile unsigned char*)0x79))

#define ADCL    (*((volatile unsigned char*)0x78))

#define DIDR0  (*((volatile unsigned char*)0x7E))

#define DIDR1  (*((volatile unsigned char*)0x7F))

#define DIDR2  (*((volatile unsigned char*)0x7D)) 





반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 5. 1. 13:16

USART /수신, Visual C# 시리얼 통신

 

================================== Outline ==================================

USART /수신(설정 및 절차)

* 시험 공고

Visual C#시리얼 통신

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

 

USART 송신 절차(설정)

 

1. 제어 레지스터에 대해 필요한 통신 모드를 설정한다.(Baud Rate, Stop bit, Parity)

2. UCSRB RegisterTXEN bitset하여 TxD핀이 USART 송신 단자로 사용될 수 있도록 한다.

 

레지스터 설정은,

 

UBRR0L/UBRR0H: Baud Rate 설정

UCSRn0으로 Baud Rate를 제외한 설정

 

USART 송신 절차(전송)

 

1. 전송할 Data를 송신 버퍼 UDR에 써 준다.

2. UCSRA RegisterUDRE or TXC bit를 체크하여 송신 버퍼에 데이터를 쓸 수 있는지 검사.

//UDRE 플래그 비트는 송신 버퍼가 비어 있는 것만을 나타내지만, TXC 플래그 비트는 송 신 버퍼 및 송신 Shift Register가 비어 있는 상태까지 확인하기 때문에 속도가 느릴 수 있다.

 

3. 인터럽트 이용 시 UCSRB레지스터에 대응하는 인터럽트 Enable BitSREGI BitSet 해주어야 한다.

 

USART 수신(설정)

 

1. 제어 레지스터에 필요한 통신모드를 설정한다.

2. Baud Rate레지스터에 사용자 전송속도에 맞는 설정 값을 설정한다.

3. UCSRB에서 RXEN비트를 Set하여 RxD 핀이 수신 단자로 동작하도록 해야 한다.

 

//송신은 polling, 수신은 interrupt방식

 

USART 수신(절차)

 

1. 수신 버퍼(UDR)의 값을 읽기 전에 수신 데이터가 전송되어 수신 버퍼에 저장되어 있는지 UCSRA 레지스터의 RXC 플래그 비트를 검사한다.(RXC = 1 : 아직 읽지 않은 수신 데이터가 수신 버퍼에 있다)

2. RXC 비트는 수신 버퍼를 읽으면 자동 Clear 된다.

 

//Windows CE에서 HMI를 사용하여 구동시킨다. ex) 네비게이션

 

//PLC(Programmable Logic Controller): 산업 플랜트의 자동 제어 및 감시에 사용하는 제어장치.

 

/* 시험공고 */

 

평가목적:

- 온도 및 조도 정보의 ADC 변환 기술 능력 평가

- Character LCD 제어 능력 평가

- 시리얼 통신에 대한 처리 능력 평가

 

평가방법

- 보고서(실기)

- 객관식 10문항(필기, 4지선다, 60)

 

평가내용

- ADC 변환 기술, Character LCD 제어, 시리얼 통신 기술

 

평가기준

- 실기: ADC 변환(30), Character LCD 제어(30), 시리얼 통신(30)

- 필기: ADC 용어(2), ADC Register(3), Timing Diagram(3), USART Register(2)

 

평가활용:

- 실기 50점 이하: 보고서 재작성 및 재평가

- 필기 5점 이하: 관련 내용 보고서 작성 제출 및 재시험

 

 

// 필기 객관식 10문제

 

 

- ADC 레지스터가 아닌 것은?


ADC 레지스터는.

- ADMUX, ADCSRA, ADCH/ADCH

 

 

- A/D converter의 아날로그 입력 단자에서 디지털 입력 버퍼를 금지시켜 병렬 I/O포트로 동작하지 못하도록 하는 기능을 수행하여 디지털 입력 버퍼에서 소비 전력을 절약하는데 이바지하는 레지스터를 모두 고르시오.


 

- 다음 중 A/D 컨버터의 동작을 설정하거나 동작 상태를 표시하는 기능을 수행하는 레지스터는 무엇인가

 

- 다음 중 A/D변환 오차에 대한 설명으로 틀린 것

 

- Crystal10mhz일 때 9600 bpsBuad Rate를 만들고자 할 때 UBRR0l UBRRnH에 적용해야 할 값은?

 

- LCD 타이밍 차트 보는 법

 

- ADC 잡음 제거 방법으로 옳지 않은 것은?

 

- USART와 관련이 없는 레지스터는?

 

지난 시간에 Visual C#을 활용하여 LED전구에 불을 켜고 끈 것에 이어 문자를 보내 화면에 출력하는 실습을 해보자!

 

우선 text상자를 만들고,

시리얼포트 -> 이벤트에서 다음과 같이 설정해 준다.


반응형
Posted by newind2000