회원가입 ID/PW 찾기
AA

#include <iom128v.h>
#include <macros.h>

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

unsigned char value;
typedef unsigned char byte;

#pragma interrupt_handler adc_isr:22
void adc_isr(void)
{
  value=ADCH;
 Command(LINE2);
  htoa(value);
 delay_ms(5000);
          
}
void delay_us(unsigned char time_us) /* time delay for us 16MHz */
{
  register unsigned char i;

  for(i = 0; i < time_us; i++) // 4 cycle +
  {
    asm (" PUSH R0 "); // 2 cycle +
    asm (" POP R0 "); // 2 cycle +
    asm (" PUSH R0 "); // 2 cycle +
    asm (" POP R0 "); // 2 cycle +
    asm (" PUSH R0 "); // 2 cycle +
    asm (" POP R0 "); // 2 cycle +
  }
}

void delay_ms(unsigned int time_ms) /* time delay for ms */
{ register unsigned int i;

  for(i = 0; i < time_ms; i++)
  {
    delay_us(250);
   delay_us(250);
 delay_us(250);
 delay_us(250);
  }
}
// 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++);
 delay_ms(100);
 }
}
// 인스트럭션 쓰기 함수
void Command(byte inst)
{
 delay_ms(2);

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

 // 인스트럭션 하위 바이트
 PORTD = ((inst<<4) & 0xF0); // 데이터
 PORTD &= 0xFE;   //RS = 0;
 PORTD &= 0xFD;   //RW = 0;
 delay_ms(4);     
 PORTD |= 0x04;   //E = 1;
 delay_ms(4);
 PORTD &= 0xFB;   //E = 0;
}

//데이터 쓰기 함수
void Data(byte dw)
{
 delay_ms(2);
       
 // 데이터 상위 바이트
 PORTD = (dw & 0xF0);  // 데이터
 PORTD |= 0x01;   //RS = 1;
 PORTD &= 0xFD;   //RW = 0;
 delay_ms(4);     
 PORTD |= 0x04;   //E = 1;
 delay_ms(4);
 PORTD &= 0xFB;   //E = 0;

 // 데이터 하위 바이트
 PORTD = ((dw<<4) & 0xF0);   // 데이터
 PORTD |= 0x01;   //RS = 1;
 PORTD &= 0xFD;   //RW = 0;    
 delay_ms(4);     
 PORTD |= 0x04;   //E = 1;
 delay_ms(4);
 PORTD &= 0xFB;   //E = 0;
}
void htoa(byte hh)
{
 Data((hh%1000)/100+'0');
 Data((hh%100)/10+'0');
 Data(hh%10+'0');
}
void main(void)
{
 DDRF=0X00; //수광포트
 LCD_init();
 Command(HOME);
 LCD_String("ADC TEST");  // 첫 번째 라인에 출력
 SEI();
 ADCSRA = 0xaf;
 ADMUX = 0x20;
 delay_ms(100);
 ADCSRA |= 0x40;
}
센서회로도는 아크마님 라인트레이서 회로도를 보고 만들었구요
컴파일러는 icc인데
adc한다음에 adc값을 lcd로 출력하는 프로그램입니다

그런데 adc완료인터럽트는 걸리는것 같은데
막상 값을 출력해보면 adc값이 000으로 나오더라구요

이게 어디가 잘못된건지를 못찾아서 질문올립니다..

댓글 9
  • No Profile

    제가 좋아하는 컴파일러 중에 하나가 icc입니다^^

    전체 소스는 보지 못했구요 님이 말씀하신부분만 봤습니다.


     value=ADCH;
     Command(LINE2);
      htoa(value);
     delay_ms(5000);
              

    이런 구문이 있는데요

    adc로 값을 받을때는

    10비트 모드로 작동시킬때에는 1바이트만으로는 표현할수 없어요

    ADCH, ADCL 레지스터에 각각 값이 상위, 하위 바이트로 나뉘어져 저장됩니다.

    사용법 예를 들자면

    int value;

    value = ADCH << 8;
    value |= ADCL;

    이런식으로 저장을 해야합니다.


    그리고 단편적으로 보건데 ADC인터럽트에서 딜레이 함수를 쓰는건 좋지 않습니다..

    해보시고 이외에 문제점 있으시면 말씀해주세요...

    ADC레지스터 설정부분은 제가 안봤기때문에..

  • No Profile
    참고로 코드비젼에서는 워드값 즉 2바이트로 값이 저장되는 레지스터가 ADCW이란게 있어서

    int value;

    value = ADCW;

    이런식으로 플밍하시면 되겠습니다.

    제가 나가봐야 되서 길게 못적어요...수고하세욤
  • No Profile
    글쓴이 sinpk 07.09.08 19:47 댓글 좋아요 0 싫어요 0
    value=ADCH; 로 값받는거는 레지스터에서 왼쪽 정렬을 시키고 CH를 읽은건데
    이렇게해서 8비트 ADC를 하려고한건데 잘못한건가요

    그리고 INT로 선언해서 오른쪽정렬로 바꾼다음에 value = ADCH << 8; value |= ADCL;
    으로 수정하여 실행해도 안되네요 ㅜㅜ

    아 뭐가 잘못된건지 모르겠다는..
  • No Profile

    단계별로 테스트 해보세요.

    1. 오실로 스코프로 센서의 출력값을 측정해보세요. 실제 물리적으로 출력값이 나와야 측정이 될테니까요
    2. avcc, agnd, aref 단에 배선이 정확이 연결되었는지 확인해보세요.
    3. adc인터럽트가 호출된후에 다시 adc 인터럽트를 enable시켜주는 명령어를 해줘야 합니다. 아래 소스에서는 이러한 구문이 없네요.

    void adc_isr(void)
    {
      value=ADCH;
     Command(LINE2);
      htoa(value);
     delay_ms(5000);
              
    }


    위 3가지 사항을 잘 확인해보시고

    아래 소스는 제가 실제로 구현해서 쓰는 소스입니다.


    void adc_isr(void)
    {
     int value=0;
     //conversion complete, read value (int) using...
     value=ADCL;            //Read 8 low bits first (important)
     value|= (int)ADCH << 8; //read 2 high bits and shift into top byte

    ADMUX =  0; // adc cheannel select  
    ADCSRA|=0x40; // adc on 

    }


    제가 icc로 adc할때 주로 쓰는 프로그램 코드입니다. avr128에서 테스트되었으며 잘 작동합니다.^^

    ADMUX는 선택받고 싶은 ADC채널입니다(8개중에 선택하는거죠 데이터 쉬트 참조)

  • No Profile
    아참 그리고 첨에 ADC할때 받고싶은 채널을 ADMUX로 설정하시는거 잊지 마시길..
  • No Profile
    글쓴이 sinpk 07.09.08 19:47 댓글 좋아요 0 싫어요 0

    답글 달아주신대로 수정해보았지만 ADC값이 계속 000으로 나오네요
    밑에는 수정된 소스입니다
    #include <iom128v.h>
    #include <macros.h>

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

    unsigned int value;
    typedef unsigned char byte;

    #pragma interrupt_handler adc_isr:22
    void adc_isr(void)
    {
     value = ADCH << 8;
     value |= ADCL;
     Command(LINE2);
      htoa(value);
     ADMUX=0X00;
     ADCSRA|=0x40;
              
    }
    void delay_us(unsigned char time_us) /* time delay for us 16MHz */
    {
      register unsigned char i;

      for(i = 0; i < time_us; i++) // 4 cycle +
      {
        asm (" PUSH R0 "); // 2 cycle +
        asm (" POP R0 "); // 2 cycle +
        asm (" PUSH R0 "); // 2 cycle +
        asm (" POP R0 "); // 2 cycle +
        asm (" PUSH R0 "); // 2 cycle +
        asm (" POP R0 "); // 2 cycle +
      }
    }

    void delay_ms(unsigned int time_ms) /* time delay for ms */
    { register unsigned int i;

      for(i = 0; i < time_ms; i++)
      {
        delay_us(250);
       delay_us(250);
     delay_us(250);
     delay_us(250);
      }
    }
    // 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++);
     delay_ms(100);
     }
    }
    // 인스트럭션 쓰기 함수
    void Command(byte inst)
    {
     delay_ms(2);

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

     // 인스트럭션 하위 바이트
     PORTD = ((inst<<4) & 0xF0); // 데이터
     PORTD &= 0xFE;   //RS = 0;
     PORTD &= 0xFD;   //RW = 0;
     delay_ms(4);     
     PORTD |= 0x04;   //E = 1;
     delay_ms(4);
     PORTD &= 0xFB;   //E = 0;
    }

    //데이터 쓰기 함수
    void Data(byte dw)
    {
     delay_ms(2);
           
     // 데이터 상위 바이트
     PORTD = (dw & 0xF0);  // 데이터
     PORTD |= 0x01;   //RS = 1;
     PORTD &= 0xFD;   //RW = 0;
     delay_ms(4);     
     PORTD |= 0x04;   //E = 1;
     delay_ms(4);
     PORTD &= 0xFB;   //E = 0;

     // 데이터 하위 바이트
     PORTD = ((dw<<4) & 0xF0);   // 데이터
     PORTD |= 0x01;   //RS = 1;
     PORTD &= 0xFD;   //RW = 0;    
     delay_ms(4);     
     PORTD |= 0x04;   //E = 1;
     delay_ms(4);
     PORTD &= 0xFB;   //E = 0;
    }
    void htoa(byte hh)
    {
     Data((hh%1000)/100+'0');
     Data((hh%100)/10+'0');
     Data(hh%10+'0');
    }
    void main(void)
    {
     DDRF=0X00; //수광포트
     LCD_init();
     Command(HOME);
     LCD_String("ADC TEST");  // 첫 번째 라인에 출력
     SEI();
     ADCSRA = 0xaf;
     ADMUX = 0x00;
     delay_ms(100);
     ADCSRA |= 0x40;
     while(1){};
    }

  • No Profile
    글쓴이 sinpk 07.09.08 19:47 댓글 좋아요 0 싫어요 0
    이래도 안된거면 센서부 회로도를 제가 잘못 납땜한거라고 봐야하나요?
  • No Profile

    그럴수도 있겠지요..그래서 제가 오실로 스코프로 일단 센서출력을 찍어보라고 위 답변에서 말씀드렸습니다.


    기능을 한번에 테스트 하려 하지 마시고 나눠서 테스트를 해보세요

    lcd는 잘 작동하나요?/


    이 소스 의문되는 상당히 많이 있군요..;;


    void htoa(byte hh)
    {
     Data((hh%1000)/100+'0');
     Data((hh%100)/10+'0');
     Data(hh%10+'0');
    }


    이 함수는 왜 byte로 받나요? 2바이트 데이터가 날라오는데요//

    256 이상 값이 들어오지도 않는데 1000에 나머지값이라니요..ㅡㅡ;



    // 제가 늘 말씀들이자면

    하드웨어, 소프트웨어 두가지가 결합된 형태이기때문에

    모든것이 생각되로 작동한다고 생각하고 의심되는 부분만을 고치시면 안됩니다.//


    기능을 작게 작게 나두고 하드웨어와 소프트웨어로 나눈 후에 각각 확실한 검증을 한 후에

    전체 기능을 테스트 해야합니다.


    그리고 unsigned int value; 는 초기화를 해주셔야지요 쓰레기값이 들어갑니다..;;


    안되는 부분만 질문하지마시고 각각 나눠서 하나하나씩 해보고 안되는 부분을 찾아서 질문을 해주시면 좋겠네요..


    회로도도 첨부좀 해주시면 좋겠구요//

  • No Profile
    질문을 올리실때에는 아래 사항을 한번쯤 생각해보시기 바랍니다.


    ----------------------------------------------------------------------------------------------------------
    마이크로 프로세서를 응용한 회로에서의 디버깅


    마이크로 프로세서를 응용한 회로에서는  하드웨어, 소프트웨어 두가지가 결합된 형태이기때문에

    모든 것이 개발자 생각되로 작동한다고 생각하고 의심되는 부분만을 고치시면 안됩니다

    하드웨어와 소프트웨어로 나눈 후에 각 기능을 작게 나누고 기능별로 확실한 검증을 한 후에

    전체 기능을 테스트 해야합니다.

    전반적으로 문제가 있는것을 다른것은 다 잘동작하고 한 부분만 문제가 있다고 생각하시면 큰일납니다.

    특히 전체 소스를 자신이 직접 코딩하여 테스트한 것이 아니라 타인의 소스를 응용해서 제작할때에는 더욱 그러합니다.

    질문을 하시기전에 위와 같은 점을 한번쯤 점검해보시기 바랍니다.


    - by 아크마 -




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

search
번호 분류 제목 글쓴이 조회 수 날짜
6 개발용역 HOT업체홍보란은? 아크마 5514 2007.09.09
5 개발용역 HOT[개발 의뢰] 간단한 Reversible Motor 제어기 하늘바라기 6956 2007.08.27
4 개발용역 HOTS/W 엔지니어를 모집합니다. 블루솔텍(주) 4833 2007.08.13
3 개발용역 HOT모터 구동관련 컨트롤러 개발의뢰1 현인로직 4632 2007.06.04
2 개발용역 HOT간단한 VB 프로그램 짜실 분 모집 아크마 4571 2007.05.30
1 개발용역 HOTLED 컨트롤러 회로 설계 의뢰건3 황성업 5476 2007.05.28
Prev 1 ... 3 4 5 6 7 8 9 10 11 12 Next
  • 사랑하며 가난한 것이 애정 없는 부유함보다 훨씬 낫다.
    - L.모리스
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.