안녕하세요
현재 사용 AVR : ATmega128
프로그램 : AVR Studio ADC3 에 가변저항을 연결하였습니다. 그리고 PORTB 에 DAC0800 을 연결해서 가변저항 0V~5V까지 변화를 주었을때 DAC 출력에서 0V~10V로 출력되록 프로그램과 회로를 만들었습니다. 즉 가변저항이 5V일때 DAC 출력은 10V가 되도록 할려고 합니다. AREF 단자는 GND와 104로 연결하였고 AVCC단자는 5V을 연결하였습니다. 그런데 가변저항이 1.25V 가 되었을때 DAC 출력이 10V가 됩니다. 여기서 가변저항값을 더올리면 DAC 출력값이 0V로 떨어지고 계속 가변저항 값을 올리면 다시 10V로 올라갑니다. 가변저항이 5V가 될때까지 이런 현상이 3번 반복 하는데 이유를 모르겠습니다. 최종적으로가변저항이 5V가 되었을때는 DAC 출력값을 10V로 출력 됩니다. 프로그램 #include <avr/io.h> void MCU_initialize(void)
{
MCUCR = 0x80;
XMCRA = 0x44;
XMCRB = 0x80; DDRB = 0xFF;
PORTB = 0x00; DDRF = 0x00;
PORTF = 0x00;
} 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);
}
} int main(void)
{
unsigned char i;
unsigned int sum;
float volt;
MCU_initialize();
Delay_ms(50); ADCSRA = 0x85;
ADMUX = 0x43;
Delay_us(150); while(1)
{
sum = 0; for(i=0; i<16; i++)
{
ADCSRA = 0xD5;
while((ADCSRA & 0x10) != 0x10);
sum += ADCL + ADCH*256;
Delay_ms(1);
} sum = sum >> 4;
volt = sum*5./1024.;
PORTB = volt; Delay_us(10); }
}
프로그램 : AVR Studio ADC3 에 가변저항을 연결하였습니다. 그리고 PORTB 에 DAC0800 을 연결해서 가변저항 0V~5V까지 변화를 주었을때 DAC 출력에서 0V~10V로 출력되록 프로그램과 회로를 만들었습니다. 즉 가변저항이 5V일때 DAC 출력은 10V가 되도록 할려고 합니다. AREF 단자는 GND와 104로 연결하였고 AVCC단자는 5V을 연결하였습니다. 그런데 가변저항이 1.25V 가 되었을때 DAC 출력이 10V가 됩니다. 여기서 가변저항값을 더올리면 DAC 출력값이 0V로 떨어지고 계속 가변저항 값을 올리면 다시 10V로 올라갑니다. 가변저항이 5V가 될때까지 이런 현상이 3번 반복 하는데 이유를 모르겠습니다. 최종적으로가변저항이 5V가 되었을때는 DAC 출력값을 10V로 출력 됩니다. 프로그램 #include <avr/io.h> void MCU_initialize(void)
{
MCUCR = 0x80;
XMCRA = 0x44;
XMCRB = 0x80; DDRB = 0xFF;
PORTB = 0x00; DDRF = 0x00;
PORTF = 0x00;
} 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);
}
} int main(void)
{
unsigned char i;
unsigned int sum;
float volt;
MCU_initialize();
Delay_ms(50); ADCSRA = 0x85;
ADMUX = 0x43;
Delay_us(150); while(1)
{
sum = 0; for(i=0; i<16; i++)
{
ADCSRA = 0xD5;
while((ADCSRA & 0x10) != 0x10);
sum += ADCL + ADCH*256;
Delay_ms(1);
} sum = sum >> 4;
volt = sum*5./1024.;
PORTB = volt; Delay_us(10); }
}
volt = sum*5./1024.;
PORTB = volt; 부분을 다음과 같이 바꾸어 보시기 바랍니다. sum = sum >>4; volt = sum>>2; // we can combine above two lines as // volt = sum>>6;
PORTB = volt; 또한 변수 volt의 형을 float로 하지 말고 unsigned 또는 unsigned char로 바꾸시기 바랍니다. 참고로, 이 경우에는 당연히 필요없는 것이기는 한데, 일반적으로 MCU 프로그램을 하면서 float 형은 사용하지 않는 것이 좋습니다. integer 형과 float 형 사이의 형 변환은 상당히 많은 프로그램 사이클을 요구하므로, 프로그램의 동작이 느려지게 하고 또한 code size도 불필요하게 길어지는 문제가 있습니다.
10BIT를 받아서 8비트로 출력하시는데.. ADC를 하위 2비트 버리시고 상위 8비트만 사용해서 그대로 출력해 주시면 어떨까요? DAC0800 datasheet 보니깐 8bt 입력이고 0xff 일때 바로 10V 출력이 되는군요..