회원가입 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
번호 분류 제목 글쓴이 조회 수 날짜
592 마이크로프로세서 HOT소스 수정좀 도와주세요....2 만도 2897 2010.05.24
591 펌웨어 & 코딩언어 HOT코드비젼 소스 설명좀 부탁드립니다 ㅠㅠ1 vsvm 2187 2010.05.24
590 마이크로프로세서 HOTAVR타이머관련 질문입니다.1 초초보보 1240 2010.05.24
589 마이크로프로세서 HOT[질문]PIC-C 프로그래밍점 도와주세요 야호힛 2554 2010.05.23
588 마이크로프로세서 HOTATmega128과 바코드를 연동 시키고 싶습니다.2 붑붑붑붑 2032 2010.05.22
587 마이크로프로세서 HOTAVR 과 소리인식센서2 재럴 2073 2010.05.22
586 Software & IDEs HOTData = Data * 0x100 무슨 의미 인가요4 파인 윤 1184 2010.05.22
585 마이크로프로세서 HOT엔코더 신호받는 코딩 질문좀 할게요2 엘머 1438 2010.05.20
마이크로프로세서 HOTAtmega128 A/D 컨버터 이용 전압 LCD 표시 코드 조언 부탁드립니다( _ _4 늘품 4081 2010.05.19
583 마이크로프로세서 HOTpic12f675로 서보모터 제어에 대해 질문...2 푸후 3535 2010.05.19
582 마이크로프로세서 HOT벨런싱 로봇에 들어 가는 DC모터 pwm제어시 적합한 모드좀 알려주세요2 해돌이 1317 2010.05.18
581 마이크로프로세서 HOTAVR Visual 4 를 사용하려 합니다.3 만물낙도 857 2010.05.18
580 마이크로프로세서 HOTatmega88 pwm 생성1 바다새 1139 2010.05.17
579 마이크로프로세서 HOT소스 분석 좀 부탁드릴게요 t - T 엔젤루피님 1003 2010.05.17
578 마이크로프로세서 HOT라인트레이서 모터부 회로 변경에 관해서..5 라인 2480 2010.05.16
577 마이크로프로세서 HOT디지털 온도계 질문이에요3 prunus5757 1210 2010.05.16
576 마이크로프로세서 HOT8051은 이제 사라지는 추세 아닌가요?5 genid 1148 2010.05.14
575 마이크로프로세서 HOTAVR STUDIO 가장 안정적인 버전은?3 genid 1299 2010.05.14
574 마이크로프로세서 HOTATmega에서 LCD를 제어하는데 필요한 명령어?2 genid 1156 2010.05.14
573 마이크로프로세서 HOT8051프로그래밍 할려면 어찌 합니까?2 토닉스 1090 2010.05.14
Prev 1 ... 24 25 26 27 28 29 30 31 32 33 ... 58 Next
  • 인생의 위대한 목표는 지식이 아니라 행동이다.
    - 헉슬리
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.