본문 바로가기

AVR

온도계 소스

#include<avr/io.h>
#include <stdio.h>

/***** 포트가 바뀔 경우 여기에서 수정 ******/

//LCD의 4,5,6번의 포트
#define LCD_PORT_CONTROL PORTA
#define LCD_DDR_CONTROL DDRA

//LCD의 7~14번의 포트
#define LCD_PORT_DATA PORTB
#define LCD_DDR_DATA DDRB


void Delay_us(int time_us)
{
 int volatile i;

 for(i=0; i<time_us; i++){ // 4 cycle +
  asm volatile("PUSH R0"); // 2 cycle +
  asm volatile("POP R0"); // 2 cycle + = 8 cycle = 1us for 8Mhz
  asm volatile("PUSH R0"); // 2 cycle +
  asm volatile("POP R0"); // 2 cycle + = 12 cycle for 11.0592MHZ
  asm volatile("PUSH R0"); // 2 cycle +
  asm volatile("POP R0"); // 2 cycle = 16 cycle = 1us for 16MHz
 }
}

void Delay_ms(int time_ms)
{
 int volatile i;

 for(i=0; i<time_ms; i++)
  Delay_us(1000);
}

 

/***** LCD 명령어 레지스터에 쓰는 함수 *****/

void Command(unsigned char command)
{
  LCD_PORT_CONTROL = 0x00;   // E = 0, R/W=0, Rs = 0
  LCD_PORT_DATA = command;   // 명령어 출력
  LCD_PORT_CONTROL = 0x04;   // E = 1 , R/W=0, Rs = 0(LCD 동작)
  Delay_us(1);
  LCD_PORT_CONTROL = 0x00;    // E = 0, R/W=0, Rs = 0
  Delay_us(50);
}

/***** LCD 데이터 레지스터에 쓰는 함수 *****/

void Data(unsigned char data)
{
  LCD_PORT_CONTROL = 0x01;   // E = 0, R/W=0, Rs = 1
  LCD_PORT_DATA = data;      // 데이터 내용 출력
  LCD_PORT_CONTROL = 0x05;   // E = 1, R/W=0, Rs = 1(LCD 동작)
  Delay_us(1);
  LCD_PORT_CONTROL = 0x01;   // E = 0, R/W=0, Rs = 1
  Delay_us(50);
}

/***** LCD에 글자 출력 함수 *****/

void String( unsigned char *string)
{
  while(*string != '\0')
  {
    Data(*string);
    string++;
  }
}

/***** AVR 초기화 및 LCD에 대한 초기화 *****/

void Init(void)
{
 LCD_DDR_DATA=0xff;
  LCD_DDR_CONTROL=0x07;
 Delay_ms(50);

  Command(0x38);  // function set(데이터 선을 8 bit 다 사용, 2줄표시 , 5x7 dot 사용)
  Command(0x0C); // display control(표시(display) 켬, 커서(cursor) 끔)
  Command(0x06);  // entry mode set(CGRAM이나 DDRAM을 써넣거나 읽을 때
                        // 어드레스를 1증가 시키고 커서를 우로 이동, 시프트는 안함
  Command(0x01);  // clear display
  Delay_ms(2);
}


int adc(unsigned char channel)
{
 unsigned int adc_sum, i;

 ADMUX = 0X00 + channel;
 ADCSRA = 0X87;
 Delay_us(200);

 adc_sum = 0;
 for(i = 0; i < 16; i++)
 {
  ADCSRA = 0XD7;
  while((ADCSRA & 0X10) != 0X10);   
  adc_sum += ADCL + ADCH*256;
  Delay_ms(1);
 }

 return adc_sum;
}

void heat_adc(void)
{
    unsigned int adc_sum, change_heat;
    unsigned int _10_heat, _1_heat, _0_1_heat;
    float adc_avg, heat;
    char temp[16];

        adc_sum = adc(0);
        adc_avg = adc_sum / 16;

        adc_sum = adc(1);
        adc_avg = adc_avg + (adc_sum / 16);

        adc_sum = adc(2);
        adc_avg = adc_avg + (adc_sum / 16);

        adc_sum = adc(3);
        adc_avg = adc_avg + (adc_sum / 16);

        adc_avg = adc_avg / 4;
        heat = (adc_avg * 10) / 225;
        change_heat = heat * 10;

        _10_heat = change_heat / 100;
        change_heat = change_heat % 100;
        _1_heat = change_heat / 10;
        _0_1_heat = change_heat % 10;

        Command(0x80);
        String("   Temperature   ");

        sprintf( temp, "     %d%d.%d C  ", _10_heat, _1_heat, _0_1_heat );
        Command(0xC0);
        String(temp);


        Delay_ms(1000);

}


int main(void)
{
 DDRF = 0XF0;
        Init();

 while(1)
 {
  heat_adc();

 }
 return 0;
 
}


 

'AVR' 카테고리의 다른 글

간단한 송수신 프로그램  (0) 2009.11.11
간단한 송신 프로그램  (0) 2009.11.11
스텝모터 구동  (0) 2009.09.14
타이머 / 카운터 0 일반모드(실습)  (0) 2009.07.25
타이머 / 카운터 0 일반모드(이론)  (0) 2009.07.25