회원가입 ID/PW 찾기
AA

Atmega128 를 이용해 외부의 전압(건전지이용)값의 변화를(가변저항이용) LCD 에 표시하는 구성입니다..

 

Atmega를 배운적은 없지만.. 스스로 독학하려고 하고 있는데.. 실상 책을 아무리 봐도 어려운건 할 수 없군요..

 

회로도를 따로 그릴 수가 없어서요..

 

구성은 이렇습니다.

 

1. Atmega128 사용

2. D포트를 활용해 LCD 출력 <- 알기쉽게 배우는 AVR Atmega128 이라는 책을 보고 있는데요, 그것을 보고 2라인 출력하는것 까지는 해보았습니다.

3. F포트의 PF0 부분에

   (5v 어답터, 저항두개 연결로 전압 낮춰서..)
   vcc의 +부분 --------------> 10K 저항 ---- 10K 저항----------------> vcc-부분

                                                       |

                                                       |

                                                       |

                                             PF0으로 들어가는 도선
이런 식입니다..

원래는 책에서 7세그먼트에 값을 표시하도록 하는 프로그램이었는데요.. LCD를 해보아서 그냥 LCD에서 문자를 입력하는 곳에 AD 컨버터된

값을 넣으면 되겠지 하고 프로그램도 수정해 보았습니다.. 일종의 짜마추기죠..

(실은.. LM35 를 이용해서 온도계 형식을 구성하고 싶은데, 전압값을 읽을 수 있다면 온도계 하는것은 수월하지 않을까 해서 매달리고 있습니다..)

일단 코드를 칩에 올리면,

Voltage 3.50

이라구 표시되는되요, 실제로 테스터기로 그 곳 부하의 전압을 제어보면 2.5정도 나옵니다..

(10K 옴을 두개 연결한다음 전압을 제서 2.5V가 나오는게 맞는거 같은데요;)


어떤 이유로 1의 차이가 발생하는걸까요..??


코드입니다.

//     RS  - PD0
//     R/W - PD1
//     EN  - PD2
//     DB4  - PD4
//     DB5  - PD5
//     DB6  - PD6
//     DB7  - PD7

#include <mega128.h>       
#include <delay.h> 
#include <stdio.h>

#define FUNCSET       0x28 // Function Set
#define ENTMODE       0x06 // Entry Mode Set
#define ALLCLR        0x01 // All Clear
#define DISPON        0x0c  // Display On
#define LINE2         0xC0 // 2nd Line Move
#define HOME          0x02      // Cursor Home

void LCD_init(void);
void LCD_String(char *);
void Busy(void);
void Command(unsigned char);
void Data(unsigned char);

void  AD_disp(int);

void main(void)
{              
        int   ad_val;
                  
 DDRD = 0xFF; // 포트 B 출력 설정
        DDRF = 0xF0;    // PF4-PF7 출력, PF0-PF3 입력
       
        LCD_init();
                                                       
        ADMUX = 0x00;   // ADC0 단극성 입력 선택
        ADCSRA = 0xE7;  // ADEN=1, ADFR=1, ADSC=1, 16MHz  256분주 -> 125kHz

        delay_ms(5);
        
         while(1){  
               ad_val = (int)ADCL + ((int)ADCH << 8);      // A/D값 읽기
               AD_disp(ad_val);                            // A/D값 표시

               delay_ms(10);
         }
}   

// A/D 변환값 표시
void AD_disp(int val)
{               
        float  fval;
        int  ival,buf;
        char N100,N10, N1;
        char Temp0[20],Temp1[20];
       
        fval = (float)val * 5.0 / 1023.0;    
        ival = (int)(fval  * 100.0);
        buf = ival % 100;
       
        N100 = (ival/100);      // 정수부 추출
        N10 = buf /10;
        N1= buf%10;

       
        sprintf(Temp1,"%2d.%d%d",N100,N10,N1);
        sprintf(Temp0,"Voltage");
        Command(HOME);
        LCD_String(Temp0); 
        Command(LINE2);
        LCD_String(Temp1);
              
        delay_ms(100);
}


// LCD 초기화 
void LCD_init(void)
{       
         DDRD = 0xFF;   // 포트 D 출력 설정
         PORTD &= 0xFB;   //E = 0;
               
         delay_ms(15);
         Command(0x20);
         delay_ms(5);
         Command(0x20);
         delay_us(100);
         Command(0x20);
         Command(FUNCSET);
         Command(DISPON);
         Command(ALLCLR);
         Command(ENTMODE);
}

// 문자열 출력 함수
void LCD_String(char str[])
{              
         while(*str) Data(*str++);
}                                 

// 인스트럭션 쓰기 함수
void Command(unsigned char byte)
{
         Busy();

         // 인스트럭션 상위 바이트
         PORTD = (byte & 0xF0);  // 데이터 
         PORTD &= 0xFE;   //RS = 0;           
         PORTD &= 0xFD;   //RW = 0;  
         delay_us(1);     
         PORTD |= 0x04;   //E = 1;
         delay_us(1);
         PORTD &= 0xFB;   //E = 0;

         // 인스트럭션 하위 바이트
        PORTD = ((byte<<4) & 0xF0); // 데이터
         PORTD &= 0xFE;   //RS = 0;
         PORTD &= 0xFD;   //RW = 0;
         delay_us(1);      
         PORTD |= 0x04;   //E = 1;
         delay_us(1);
         PORTD &= 0xFB;   //E = 0;
}
                   
//데이터 쓰기 함수
void Data(unsigned char byte)
{
         Busy();
        
         // 데이터 상위 바이트
         PORTD = (byte & 0xF0);  // 데이터
         PORTD |= 0x01;   //RS = 1;
         PORTD &= 0xFD;   //RW = 0;
         delay_us(1);      
         PORTD |= 0x04;   //E = 1;
         delay_us(1);
         PORTD &= 0xFB;   //E = 0;

         // 데이터 하위 바이트
         PORTD = ((byte<<4) & 0xF0);   // 데이터
         PORTD |= 0x01;   //RS = 1;
         PORTD &= 0xFD;   //RW = 0;     
         delay_us(1);      
         PORTD |= 0x04;   //E = 1;
         delay_us(1);
         PORTD &= 0xFB;   //E = 0;
}

// Busy Flag Check -> 일반적인 BF를 체크하는 것이 아니라
// 일정한 시간 지연을 이용한다.
void Busy(void)
{
        delay_ms(2);
}


정말 초보적인 뭔가를 모르고 있다는 생각이 듭니다..

아무것도 모르고 무작정 달려들어서 하려니 막히는게 많네요..

 

답변 부탁드립니다...

댓글 4
  • No Profile
    회로가 없어 정확히 판별할 순 없습니다만.

    adc소스는 제대로 받는거 같고요. 직감으로 아마 세그먼트에 표시되는 루틴이 잘못된거 같군요
    아스키코드로 2와 3은 1비트 차이이므로 이부분에서 착오가 있었던거 같네요
    전반적으로 루틴은 잘된거 같네요
    참고로 온도센서로부터 나중에 adc값만 받으면 온도계는 쉽게 구현가능할거 같군요
  • No Profile
    글쓴이 늘품 10.05.19 23:28 댓글 좋아요 0 싫어요 0

    답변 감사드립니다 ( _ _  (상당히 내용이 긴데.. 꼼꼼히 봐주셔서 다시 한번 감사드립니다( _ _))

    오차가 있긴하지만 ADC 가 문제 없다고 하시니 좀 안심이 됩니다..

    시간이 좀 생기면 책에있는소스를(책은 KIT 로 하기 땜에..) 세그먼트 달아서 해봐야겠네요:
    그래야 좀 더 이해가 될 것 같습니다.. ( 시간만 많으면 직접 해보는게 최고더군요..)

    하루빨리 온도센서 달아봐야 겠군요.^^:

  • No Profile
    fval = (float)val * 5.0 / 1023.0;    
            ival = (int)(fval  * 100.0);
            buf = ival % 100;
           
            N100 = (ival/100);      // 정수부 추출
            N10 = buf /10;
            N1= buf%10;


    여기부분은 좀 미심쩍입니다.
    왜 이렇게 하셨는지 좀 그렇군요.
    전압환산하고 스케일을 100배 했다가 다시 내리는 방법으로  정수를 찾아내셨던걸로 보이는군요
    조금은 복잡한 방법인거 같네요...

  • No Profile

    예전에 제가 비슷한 제품을 만들어 드린적있는데 제가 짠 소스 코드를 올려 드리겠습니다.

    저같은 경우는 ADC 입력 받은것을 일단 버블 정렬 알고리즘으로 평균을 구해서 전압 벡터 테이블에서 비교 발췌한 후 이 값을 LCD에 표출하도록 했었습니다. 상용 제품으로 나가고 있는 소스니 많은 도움이 되실겁니다.

    마이크로 프로세서 가지고 연산을 수행하려면 것두 부동 소수점 연산을 수행하려면 속도가 미치지 못할때가 많습니다.

    이럴때는 그냥 레퍼런스 테이블을 만들어서 비교하는게 더 빠릅니다.

하드웨어 설계 및 개발에 대하여 개발자들이 자유롭게 토론하는 공간입니다.
- Q&A, 자유주재 토론, 관련 정보 공유
- 분야 : 마이크로프로세서 응용, 전기/전자(아날로그/디지털) 회로 설계, C/C++ 프로그래밍, 펌웨어,
         PCB Artwork, 트러블슈팅 등 하드웨어 설계에 관한 전반인 내용
※ 게시글에 맞는 분류를 선택하여 글을 작성해 주시면 쾌적한 사이트 운영에 많은 도움이 됩니다.
※ 하드웨어 인사이트는 회원들간의 거래정보를 게재할 뿐이지, 그 어떤 책임과 의무도 가지지 않습니다.

search
번호 분류 제목 글쓴이 조회 수 날짜
2764 전기전자 아무거나 HOTmaxwell 프로그램 구할수 없을까요?3 김씨 1405 2010.05.22
2763 전기전자 아무거나 HOTorcad및회로 완전초짜입니다. 이렇게생긴것 이름이 뭔가요7 흰메이크 1018 2010.05.21
2762 자유주제 HOT화면에 그림파일이 안보입니다_어떻게해야 보이나요1 파인 윤 9232 2010.05.21
2761 중고장터 HOTHELICOMM 사의 IP-LINK 2134- 2264 모듈 구매합니다. 아크마 4119 2010.05.20
2760 마이크로프로세서 HOT엔코더 신호받는 코딩 질문좀 할게요2 엘머 1446 2010.05.20
2759 자유주제 HOT납을주세요~!5 청소부 4006 2010.05.20
2758 자유주제 HOT나이키?17 고고 1672 2010.05.20
2757 자유주제 HOT높이뛰기17 고고 1573 2010.05.20
2756 자유주제 HOT도끼와 나무꾼11 고고 3081 2010.05.20
2755 전기전자 아무거나 HOTdsp 가르치는 학원 없을까요? shoai 865 2010.05.19
2754 자유주제 HOT저만 이렇게 보이나요..?7 늘품 1598 2010.05.19
마이크로프로세서 HOTAtmega128 A/D 컨버터 이용 전압 LCD 표시 코드 조언 부탁드립니다( _ _4 늘품 4083 2010.05.19
2752 마이크로프로세서 HOTpic12f675로 서보모터 제어에 대해 질문...2 푸후 3540 2010.05.19
2751 마이크로프로세서 HOT벨런싱 로봇에 들어 가는 DC모터 pwm제어시 적합한 모드좀 알려주세요2 해돌이 1318 2010.05.18
2750 자유주제 HOT메인 페이지가 약간이 변화가 있는것 같네요.1 수테크노 3532 2010.05.18
2749 마이크로프로세서 HOTAVR Visual 4 를 사용하려 합니다.3 만물낙도 860 2010.05.18
2748 자유주제 HOT출근 도장도 납 주나요 ??? ^^5 만물낙도 4168 2010.05.18
2747 전기전자 아무거나 HOT증폭기 회로설계할때 저항 크기는 어떻게 정하나요??1 예비군 1510 2010.05.18
2746 마이크로프로세서 HOTatmega88 pwm 생성1 바다새 1142 2010.05.17
2745 자유주제 HOT출근도장 대단하시네요1 아크마 3731 2010.05.17
  • 남의 생활과 비교하지 말고 네 자신의 생활을 즐겨라.
    - 콩도르세
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.