회원가입 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
번호 분류 제목 글쓴이 조회 수 날짜
1687 자유주제 여러분 Altium 써 보셨습니까? 테나르 16 2010.05.27
1686 자유주제 HOT하드웨어 공부어디서 부터 해야돼요3 피디박스 8732 2010.05.25
1685 자유주제 HOT내일까지 보고서...ㅍ.ㅍ4 kssyjy 4629 2010.05.25
1684 자유주제 HOTㅠ.ㅠ kssyjy 3735 2010.05.25
1683 자유주제 HOT회로가 넘어려워11 제갈공ㅇㅇ 8809 2010.05.24
1682 자유주제 HOT혹시.. PLC와 관련된 사이트 아시는분 추천좀요~ KillingS 8006 2010.05.23
1681 자유주제 HOTavr강좌 무료로 들을 수 있는곳 없나요~?ㅎ6 재럴 8683 2010.05.22
1680 자유주제 HOT전공과제가 2일뒤인데~~1 재럴 3670 2010.05.22
1679 자유주제 HOT화면에 그림파일이 안보입니다_어떻게해야 보이나요1 파인 윤 9232 2010.05.21
1678 자유주제 HOT납을주세요~!5 청소부 4006 2010.05.20
1677 자유주제 HOT나이키?17 고고 1672 2010.05.20
1676 자유주제 HOT높이뛰기17 고고 1572 2010.05.20
1675 자유주제 HOT도끼와 나무꾼11 고고 3081 2010.05.20
1674 자유주제 HOT저만 이렇게 보이나요..?7 늘품 1597 2010.05.19
1673 자유주제 HOT메인 페이지가 약간이 변화가 있는것 같네요.1 수테크노 3532 2010.05.18
1672 자유주제 HOT출근 도장도 납 주나요 ??? ^^5 만물낙도 4168 2010.05.18
1671 자유주제 HOT출근도장 대단하시네요1 아크마 3731 2010.05.17
1670 자유주제 HOT머리빨 그게 뭐임 먹는거임 우걱우걱12 duziny 1684 2010.05.15
1669 자유주제 HOT적절류 최강!7 duziny 1518 2010.05.15
1668 자유주제 HOT자넨 해고일세!10 duziny 1901 2010.05.15
Prev 1 ... 46 47 48 49 50 51 52 53 54 55 ... 135 Next
  • 벗을 사귐에는 과하여 넘치지 말지니 넘치면 아첨하는 자가 생기리라.
    - 채근담
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.