회원가입 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
번호 분류 제목 글쓴이 조회 수 날짜
75 중고장터 HOTAVR JTAGICE MK2 에뮬레이터 팝니다. bluewing 5041 2010.10.06
74 중고장터 HOTARM 개발보드 마이크로비젼 MV2440-LCD 팝니다. bluewing 4211 2010.10.06
73 중고장터 HOT뉴코란도 구합니다.11 설록맨 3174 2010.10.05
72 중고장터 HOTUSB HUB IC판매 Newface 3478 2010.09.24
71 중고장터 HOT삼성 3.5인치 TFT-LCD (Touch 포함) 싸게 드려요. 삼성 3.5인치 TFT-LCD (Touch 포함) 싸게 드려요. 삼성 3.5인치 TFT-LCD (Touch 포함) 싸게 드려요.1 띵요루슛 4338 2010.09.17
70 중고장터 HOT오실로스코프 싸게 사고 싶어요~7 야웅이 3255 2010.09.13
69 중고장터 HOTSTR-6253 판매합니다.2 행국강기 3914 2010.09.07
68 중고장터 HOTnewtc꺼 AVR MEGA 128pro 개발키트(풀셋) 구합니다. 어쩌다 3226 2010.08.21
67 중고장터 HOTD&J DC모터 3개 판매 로봇용적합 IGM30 12V 엔코더 타입1 아크마 6575 2009.01.11
66 중고장터 HOTCMOS 카메라 OV9650 판매1 아크마 3756 2010.07.28
65 중고장터 HOT삼성 3.5인치 TFT-LCD (Touch 포함) 싸게 드려요.2 용가리3 3280 2010.07.17
64 중고장터 HOTmicrochip 사 ac motror controller demo board 이단장 3377 2010.06.17
63 중고장터 HOT각종 부품 팝니다. 캐리안 3648 2010.06.10
62 중고장터 HOT기울기센서 (TILT SA1) 팝니다 폴라리스 4193 2010.06.05
61 중고장터 HOT중고 서적구해요..^^13 로이lee 4164 2010.05.26
60 중고장터 HOT컴퓨터 사요2 제갈공ㅇㅇ 3859 2010.05.24
59 중고장터 HOT소리인식센서 구합니다!1 재럴 3661 2010.05.22
58 중고장터 HOTHELICOMM 사의 IP-LINK 2134- 2264 모듈 구매합니다. 아크마 4117 2010.05.20
57 중고장터 HOT터치 lcd안쓰시는거 구입합니다1 duziny 3881 2010.05.13
56 중고장터 HOT어셈블리어 교재 구합니다~1 배개 3706 2010.04.28
  • 좋은 전쟁 또는 나쁜 평화는 없다.
    - 프랭클린
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.