회원가입 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
번호 분류 제목 글쓴이 조회 수 날짜
66 펌웨어 & 코딩언어 HOT텍트로닉스(tektronix) 오실로스코프 질문드려요~~1 파괴지왕 1168 2010.06.24
65 펌웨어 & 코딩언어 HOTspice 프로그램을 만들고 싶습니다1 TreeOfDream 978 2010.06.21
64 펌웨어 & 코딩언어 HOTC언어 초보에요 ㅠㅠ 이쪽부분 간소화할려고하는데..조언좀..11 다크소마 1448 2010.06.19
63 펌웨어 & 코딩언어 HOTMFC 를 공부중입니다 API를 시작해야 하는데..3 TreeOfDream 1122 2010.06.11
62 펌웨어 & 코딩언어 HOT펌웨어 엔지니어입니다. 윈도우응용프로그램 MFC하고싶은데...6 상하이찬 1569 2010.06.02
61 펌웨어 & 코딩언어 HOT리눅스 기반 어셈블리어 작성했는데 자꾸 'command not found'라 뜨네요......2 하늘위의 성 1409 2010.05.30
60 펌웨어 & 코딩언어 HOT코드비젼 소스 설명좀 부탁드립니다 ㅠㅠ1 vsvm 2190 2010.05.24
59 펌웨어 & 코딩언어 HOT맥스포사의 mtm-cm3000 으로 리모콘 모듈이 조종 가능한가요? 철방이 880 2010.05.11
58 펌웨어 & 코딩언어 HOT코드비젼으로 컴파일해봤습니다...도움좀 주세요.4 푸후 1219 2010.05.04
57 펌웨어 & 코딩언어 HOT다시 작성합니다. MSDN 도움말 문제입니다. TreeOfDream 883 2010.04.29
56 펌웨어 & 코딩언어 HOT어셈블 도와주세요 ㅠㅠ1 마왕님 1032 2010.04.26
55 펌웨어 & 코딩언어 HOT왕초보 c언어 질문이요11 hshyo 1053 2010.04.19
54 펌웨어 & 코딩언어 HOT마이컴 제어하는 C언어 학습이 어디까지 이루어져야 할까요?8 봄날 1434 2010.04.17
53 펌웨어 & 코딩언어 HOT액세스 지정자에 대해서 궁금한 점이 있습니다. TreeOfDream 902 2010.04.17
52 펌웨어 & 코딩언어 HOT조이스틱 관련 Firmware,Driver 관련 조언 부탁드립니다.2 루키키 1094 2010.04.14
51 펌웨어 & 코딩언어 HOTc언어 배우려는 초보입니다.9 빛의속도 1026 2010.04.09
50 펌웨어 & 코딩언어 HOTzigbee 통신 프로그램 질문입니다!!5 소울 2451 2010.04.01
49 펌웨어 & 코딩언어 HOT비쥬얼 스튜디오 6.0에 관해서..3 꿇단지 1061 2010.03.24
48 펌웨어 & 코딩언어 HOTc언어 왕초보입니다. 좋은책 추천좀 해주세요10 circuit 1296 2010.03.15
47 펌웨어 & 코딩언어 HOT8051과 일반 C와 많이 차이나나요?5 개똥껄레 1098 2010.02.20
  • 뇌물로 얻은 충성은 뇌물로 정복된다.
    - 세네카
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.