ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AVR] 가변저항을 이용해서 ATmega 128의 ADC 다뤄보기
    AVR study 2013. 2. 10. 00:58
    반응형

    가지고 있는 센서가 마땅치 않아서 일단 가변저항으로 ADC의 기본 동작을 확인했습니다.

     

    그런데 AVR 내부 2.56전압을 사용한 경우와 AVCC 전압을 사용한 경우 둘 다 최대 2.56V 까지만 올라가는데..

    원인을 도저히 잡아내질 못하겠네요. 코드상의 문제인지, 아니면 ADC 내부구조에 대해서 뭔가 잘못 이해하고 있는지

    혹시 해결책을 아시는 분은 답변을 달아주시면 감사드리겠습니다 (__)

     

    제가 사용하는 atmega128 모듈 회로도 같이 올려드릴게요.

     

     

    위 회로는 M.A.I 사의 ATmega128 모듈 회로도입니다. 자세한 정보는 이곳을 따라 들어가시면 볼 수 있습니다.

     

     

    ADC_TEST.C

     


     

    //---------------------------------------------------------------------------------------->LCD 옵션 설정문
    #define CMD_CREAR_DISPLAY     0x01 //1. Clear Display
    #define CMD_RETURN_HOME      0x02 //2. Return Home
    //3. Entry Mode Set
    #define CMD_ENTRY_MODE_SET_OPTION1   0x04 // cursor [left], Display shift[none]
    #define CMD_ENTRY_MODE_SET_OPTION2   0x05 // cursor [left], Display shift[]
    #define CMD_ENTRY_MODE_SET_OPTION3   0x06 // cursor [right], Display shift[none]
    #define CMD_ENTRY_MODE_SET_OPTION4   0x07 // cursor [right], Display shift[]
    //4. Display On/Off
    #define CMD_DISPLAY_OPTION1     0x08 // Display [Off], Cursor [Off], Cursor Blink [Off]
    #define CMD_DISPLAY_OPTION2     0x09 // Display [Off], Cursor [Off], Cursor Blink [On]
    #define CMD_DISPLAY_OPTION3     0x0A // Display [Off], Cursor [On], Cursor Blink [Off]
    #define CMD_DISPLAY_OPTION4     0x0B // Display [Off], Cursor [On], Cursor Blink [On]
    #define CMD_DISPLAY_OPTION5     0x0C // Display [On], Cursor [Off], Cursor Blink [Off]
    #define CMD_DISPLAY_OPTION6     0x0D // Display [On], Cursor [Off], Cursor Blink [On]
    #define CMD_DISPLAY_OPTION7     0x0E // Display [On], Cursor [On], Cursor Blink [Off]
    #define CMD_DISPLAY_OPTION8     0x0F // Display [On], Cursor [On], Cursor Blink [On]
    //5. Cursor or Display Shift
    #define CMD_CURSOR_DISPLAY_SHIFT_OPTION1 0x10 // [Cursor] Select, Cursor Shift [Left]
    #define CMD_CURSOR_DISPLAY_SHIFT_OPTION2 0x14 // [Cursor] Select, Cursor Shift [Right]
    #define CMD_CURSOR_DISPLAY_SHIFT_OPTION3 0x18 // [Display] Select, Display Shift [Left]
    #define CMD_CURSOR_DISPLAY_SHIFT_OPTION4 0x1C // [Display] Select, Display Shift [Right]
    //6. Function Set
    #define CMD_FUNCTION_SET_OPTION1   0x20 // [4]bit mode, [1] line, [5x8] Font
    #define CMD_FUNCTION_SET_OPTION2   0x24 // [4]bit mode, [1] line, [5x11] Font
    #define CMD_FUNCTION_SET_OPTION3   0x28 // [4]bit mode, [2] line, [5x8] Font
    #define CMD_FUNCTION_SET_OPTION4   0x2C // [4]bit mode, [2] line, [5x11] Font
    #define CMD_FUNCTION_SET_OPTION5   0x30 // [8]bit mode, [1] line, [5x8] Font
    #define CMD_FUNCTION_SET_OPTION6   0x3C // [8]bit mode, [1] line, [5x11] Font
    #define CMD_FUNCTION_SET_OPTION7   0x34 // [8]bit mode, [2] line, [5x8] Font
    #define CMD_FUNCTION_SET_OPTION8   0x38 // [8]bit mode, [2] line, [5x11] Font
    //-----------------------------------------------------------------------------------> 헤더파일 선언
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    //---------------------------------------------------------------------------------------->설정 bit 선언
    #define RS 0
    #define RW 1
    #define E 2
    #define DATA PORTA

    unsigned int time_count = 0; // 타이머 카운트


    void LCD_INS (unsigned char com) // LCD Instruction 함수
    {
        PORTC&=~(1<<RS); // RS bit을 0으로 SET
        PORTC&=~(1<<RW); // RW bit을 0으로 SET
        PORTC|=(1<<E); // E bit을 0으로 SET
        _delay_ms(50);
        DATA=com;
        _delay_ms(50);
        PORTC&=~(1<<E); // E bit을 1으로 SET
     
    }
     
    void LCD_WRITE_DATA (unsigned char com) // LCD DATA 쓰기 함수
    {
     PORTC|=(1<<RS); // RS bit을 1으로 SET
        PORTC&=~(1<<RW); // RW bit을 0으로 SET
        PORTC|=(1<<E); // E bit을 1으로 SET
        _delay_ms(10);
        DATA=com;
        _delay_ms(10);
        PORTC&=~(1<<E); // E bit을 0으로 SET
    }  

    void LCD_PST(unsigned char col, unsigned char row) // 문자열 디스플레이 행, 열 지정 함수
    {
        LCD_INS(0x80|(row+col*0x40));
    }
     
    void str(unsigned char* com) // 문자열 함수
    {
     while(*com!=0)
     {
      LCD_WRITE_DATA(*com);
      com++;
     }
    }
     
    void init_buffer(void) // LCD 버퍼 초기화 함수
    {
     PORTC|=(1<<RS);
     PORTC|=(1<<RW);
     PORTC|=(1<<E);
     _delay_ms(10);
     while(DATA!=0)
     {
      LCD_WRITE_DATA(0);
      _delay_ms(10);
     }
    }

    void LCD_Decimal( unsigned char num, short AD_dat) { // Voltage 값을 LCD에 출력하는 함수
     
     unsigned char Decimal[5];

     Decimal[4] = '0' + AD_dat / 10000;  // 10000의자리 아스키값으로 저장
     AD_dat = AD_dat%10000;     // Data 변수의 나머지 값 저장
     Decimal[3] = '0' + AD_dat / 1000;  // 1000의자리 아스키값으로 저장
     AD_dat = AD_dat%1000;     // Data 변수의 나머지 값 저장    
     Decimal[2] = '0' + AD_dat / 100;  // 100의자리 아스키값으로 저장
     AD_dat = AD_dat%100;     // Data 변수의 나머지 값 저장
     Decimal[1] = '0' + AD_dat / 10;   // 10의자리 아스키값으로 저장
     AD_dat = AD_dat%10;      // Data 변수의 나머지 값 저장
     Decimal[0] = '0' + AD_dat / 1;   // 1의자리 아스키값으로 저장

     if (num==0) { // A/D 데이터 표시
      LCD_PST(0,8);
      LCD_WRITE_DATA(Decimal[3]);
      LCD_PST(0,9);
      LCD_WRITE_DATA(Decimal[2]);  // 100의자리 출력
      LCD_PST(0,10);
      LCD_WRITE_DATA(Decimal[1]);  // 10의자리 출력
      LCD_PST(0,11);
      LCD_WRITE_DATA(Decimal[0]);  // 1의자리 출력
     }

     else if(num ==1) {
      LCD_PST(1,8);
      LCD_WRITE_DATA(Decimal[4]);  // 10000의자리 출력
      LCD_PST(1,9);
      LCD_WRITE_DATA('.');   // . 출력
      LCD_PST(1,10);
      LCD_WRITE_DATA(Decimal[3]);  // 1000의자리 출력
      LCD_PST(1,11);
      LCD_WRITE_DATA(Decimal[2]);  // 100의자리 출력
      LCD_PST(1,12);
      LCD_WRITE_DATA(Decimal[1]);  // 10의자리 출력
      LCD_PST(1,13);
      LCD_WRITE_DATA(Decimal[0]);  // 1의자리 출력
      LCD_PST(1,14);
      LCD_WRITE_DATA('V');   // V 출력
     }
    }
    // ------------------------------------------------------------------------> main 함수
    int main(void) {

     short voltage = 0; // ADC 변환 값 저장 변수
     
      //TCNT0 = 0x06; // ---------------------> 1ms 만들기 위한 시스템 타이머 레지스터 설정
      //TCCR0 = 0x04; // ----------------> freescale 64배수
      //TIMSK = 0x01; // --------------> 오버플로우 인터럽트 사용
      //SREG = 0x80; // --------------> 인터럽트 허용 레지스터
     
     //-----------------------------------------------------------> ADC 관련 레지스터 초기화

     ADMUX = 0b11000011; // 내부 2.56전압, ADC 결과값 오른쪽 정렬, 싱글엔드 입력 ADC3
     ADCSRA = 0b11100111; // ADC Enable, free running, 프리스케일 최대

     //--------------------------------------------------------> 포트 초기화
     DDRA=0xff; // PORTA 출력 설정
        DDRC=0xff; // PORTC 출력 설정
     DDRF=0x00; // ACD 포트 입력 설정
     
        PORTA=0x00; // PORTA 값 초기화
        PORTC=0x00; // PORTC 값 초기화
     //---------------------------------------------------------> LCD 초기화
        LCD_INS(CMD_CREAR_DISPLAY); // Clear Display
        _delay_ms(2);
     
     LCD_INS(CMD_RETURN_HOME); // Return Home
        _delay_ms(2);
     
        LCD_INS(CMD_FUNCTION_SET_OPTION8); // [8]bit mode, [2] line, [5x8] Font
        _delay_ms(2);
     
        LCD_INS(CMD_DISPLAY_OPTION5); // Display [On], Cursor [Off], Cursor Blink [Off]
        _delay_ms(2);
     
        LCD_INS(CMD_CURSOR_DISPLAY_SHIFT_OPTION2); // [Cursor] Select, Cursor Shift [Right]
        _delay_ms(2);
     
        LCD_INS(CMD_ENTRY_MODE_SET_OPTION3); // cursor [right], Display shift[none] (커서 오른쪽증가, shift Off)
        _delay_ms(2);

     unsigned char str1[] = "Voltage:";
     unsigned char str2[] = "R.Value:";
     //-------------------------------------> 문자열 출력 인터페이스 구성
     LCD_PST(0,0);
     str(str1);

     LCD_PST(1,0);
     str(str2);
     
     while(1) { //----------------------------------------> while문
     
      voltage = (short)((0.0025*ADCW)*10000); // A/D 데이터 변환
     
      LCD_Decimal(0,ADCW);
      LCD_Decimal(1,voltage);
      _delay_ms(100);


     }
    }

    반응형
Designed by Tistory.