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