AVR(AT90CAN128)공부2010. 10. 14. 15:25
아날로그 전압을 카운팅하려고 합니다. | 새싹 전용 Q&A
2009.12.07 00:37

안녕하세요

 

Atmega128을 공부하고 있는 대학생입니다.

 

적외선 수광부, 발광부 센서를 이용하여 rpm을 측정하려고 합니다.

 

오실로 스코프로 찍어봤을때

 

대략 0~4.2V를 왔다갔다 하는 파형으로

 

측정되는데,

 

문제는 들어오는 신호가 0~4.2V의 sine 파형이

 

완전히 0으로 안내려오는 부분도 있고, 4.2V로 안 올라가는 부분이 생겨서

 

이를 조정하기 위해

 

내려가는 부분을

 

외부 인터럽트를 걸어서 일정시간동안 하강에지를 카운트하여  

 

속도를 측정하여 rpm을 측정하려고 합니다.

 

이때 바퀴가 돌면 사인 파형이 100개의 주기가 나옵니다.

 

사실, 공부는 해봤지만, 너무 지식이 얕아서 너무 어렵네요

 

저보다 먼저 공부해보시고, 이런고민들을 먼저하셔서 해결하신 분들이 계신다면

 

노하우를 알려주셨으면 합니다.

 

그리고 전압이 나오는 신호를 그냥 입력핀에다가 그냥 꼽아도 괜찮은지 알고 싶습니다.

 

원래 제꺼의 보드는 5v가 나오는 핀도 있어서

 

들어오는 max값이 4.3V이기 때문에 괜찮을것 같긴하지만, 자칫 잘못될수도 있기 때문에 여쭤봅니다.

 

참고로 외부인터럽트가 가능한 입력은 PD0(int0)에 넣을 것입니다.

 

//-----------------------------------------------------------------------------------//
// # PROJECT NAME : test3
// # FILE NAME : test3.c
// # AUTHOR : Administrator
// # DATE : 2009-12-06
// # DESCRIPTION :
//-----------------------------------------------------------------------------------//

#include <avr/io.h>
#include <avr/iom128.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#define LCD_EN (*(volatile unsigned char *)0x8000)
#define LCD_WRITE (*(volatile unsigned char *)0x8002)
#define LINE1 0x00
#define LINE2 0x40

int Data=0;
void delay_us(unsigned char);
void delay_ms(unsigned int);

void FunctionSet();
void DisplayOnOffControl();
void DisplayClear();
void EntryModeSet();
void DisplayChar(unsigned char);
void DisplayString(unsigned char*);
void SetLCDAddress(unsigned char);
int i, c1, c2;


SIGNAL(SIG_INTERRUPT4)
{
 Data=Data+1;
}


void Inlet(void)
{
 MCUCR=0X00;
 DDRA=0XFF;
 DDRD=0X00;
 DDRE=0X00;
 PORTA=0X00;
 PORTD=0X00;
 PORTE=0X00;
}

void Inlet_in0(void)
{
 EICRB=0X01;
 EIMSK=0X10;
 EIFR|=0X10;
}

int main(void)
{
 Inlet();
 Init_in0();
 sei();
 MCUCR = 0x80;
 XMCRA = 0x40;
 XMCRB = 0x80;
 FunctionSet();
 DisplayOnOffControl();
 DisplayClear();
 EntryModeSet();
  
 while(1)
 {
  PORTA=Data;
  DisplayChar(Data);
 }
}


void DisplayChar(unsigned char c)
{
 LCD_WRITE = c;
 delay_us(50);
}

void DisplayString(unsigned char* s)
{
 unsigned char i, j;
 i = 0;
 j = strlen(s)-1;
 
 for(i=0 ; i<=j ; i++)
 {
  DisplayChar(s[i]);
 }
}

void SetLCDAddress(unsigned char mode)
{
 LCD_EN = 0x80 | mode;
 delay_us(50);
}

void FunctionSet()
{
 delay_ms(50);
 LCD_EN = 0x38;
}

void DisplayOnOffControl()
{
 delay_us(40);
 LCD_EN = 0x0c;
}

void DisplayClear()
{
 delay_us(40);
 LCD_EN = 0x01;
}

void EntryModeSet()
{
 delay_ms(2);
 LCD_EN = 0x06;
 delay_us(40);
}

void delay_us(unsigned char time_us)
{
 register unsigned char i;
 for(i=0 ; i<time_us ; i++)
 {
  asm volatile("PUSH R0");
  asm volatile("POP R0");
  asm volatile("PUSH R0");
  asm volatile("POP R0");
  asm volatile("PUSH R0");
  asm volatile("POP R0");
 }
}

void delay_ms(unsigned int time_ms)
{
 register unsigned int i;
 for(i=0 ; i<time_ms; i++)
 {
  delay_us(250);
  delay_us(250);
  delay_us(250);
  delay_us(250);
 }
}

 

읽어주셔서 감사합니다.

 

Posted by 초동