글쓴이 :
김상용
작성일 : 21-02-16 17:26
조회 : 46
|
안녕하세요.
가변저항을 ADC0~3에 연결하고 타이머를 설정하여(방법?) PROT로 PWM을 출력하려고 합니다.
열심히 데이터 시트 보고 셋팅하는데 정말 잘안되는데 도움 부탁드립니다.
1. 구현 기능
- 가변저항 4개를 ADC0,1,2,3 에 연결한다.
- 각 ADC를 이용 PWM을 발생 시킨다.
2. 아래 소스 동작
- 타이머 설정 : TCCR1A = 0xA2; // FAST PWM-96
TCCR1B = 0x1A; // 8분주=0.5usec
- 출력 포트 : ADMUX = 0xC0; //ADC0
ADCSRA |= 0xfe;
LL = ADCL & 0xff;
HH = ADCH & 0x03;
val_adc0 = (int)LL + ((int)HH << 8); // A/D변환값 읽기
OCR1A = val_adc0;//PB6
- 정상적으로 PWM 가변 출력됨
3. 질문
- 여러개 GPIO로 ADC 입력받아 PWM으로 출력하고자 하는데 안됨(사실 잘모름)
- 타이머 설정 : TCCR3A = 0xA2; // FAST PWM-96
TCCR3B = 0x1A; // 8분주=0.5usec
- 출력 포트 : ADMUX = 0xC1; //ADC0
ADCSRA |= 0xfe;
LL = ADCL & 0xff;
HH = ADCH & 0x03;
val_adc0 = (int)LL + ((int)HH << 8); // A/D변환값 읽기
OCR3A = val_adc0;//PE3
- PE3에 ADC 입력에 따른 PWM 출력이 나와야 하는데 안나옴
- ADMUX 0xC0, 0xC1, 0xC2, 0xC3 설정후 각각의 ADC 값에 따라 PWM을 출력시키려고 하는데
어떻게 해야 할지 데이터시트를 참조 해도 잘 모르겠어요.
아래 소스는 제가 직접 만든것인데 오직 ADC0 밖에 안되는데 가변저항을 ADC0~3(PF0~3) 연결하여
PWM을 PB, PE 포트로 출력하고 싶은데 정말 열심히 해도 개념이 없어 모르겠네요..
질문
타이머 하나당 비교 레지터를 각각 사용해야 하나요?
TCCR1A 설정 후 ICR1 설정
TCCR3A 설정 후 ICR3 설정
해야 하는지 도와주세요. 일주일째 해매고 있어요...
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
int val_adc0 = 0,val_adc1= 0,val_adc2 = 0,val_adc3= 0;
int i;
unsigned int HH=0, LL=0;
int i;
int ad_val=0;
int i;
void PWM_output(void){
OCR1B = 0;
}
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xff;
PORTB = 0x00;
DDRB = 0xff;
PORTC = 0x00; //m103 output only
DDRC = 0xff;
PORTD = 0x00;
DDRD = 0xff;
PORTE = 0x00;
DDRE = 0xff;
PORTF = 0x00;
DDRF = 0x00;
PORTG = 0x0f;
DDRG = 0x03;
}
int main(){
port_init();
/* Timer/Counter ControlRegister ? TCCR0
7 6 5 4 3 2 1 0
FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
0 1 1 1 1 1 1 1
TCCR0 = 0x6F; // 1024 Prescale, Fast PWM 모드 셋팅, COM핀은 10으로 셋팅
OCR0 = 200;
WGM00 WGM01 Timer/CounterMode of Operation Update of OCR0 at
0 0 Normal
0 1 PWM, Phase Correct
1 0 CTC
1 1 Fast PWM
COM01 COM00 Description
0 0 Normal port operation, OC0 disconnected.
0 1 Reserved
1 0 Clear OC0 on compare match, set OC0 at BOTTOM,(non-inverting mode)
1 1 Set OC0 on comp
CS02 CS01 CS00 Description
0 0 0 No clock source (Timer/Counter stopped)
001 clkT0S/(No prescaling)
010 clkT0S/8 (From prescaler)
011 clkT0S/32 (From prescaler)
100 clkT0S/64 (From prescaler)
101 clkT0S/128 (From prescaler)
1 1 0 clkT0S/256 (From prescaler)
1 1 1 clkT0S/1024 (From prescaler)
Timer/Counter1 Control Register A - TCCR1A 1010 0010
7 6 5 4 3 2 1 0
COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10
1 0 1 0 0 0 1 0
Timer/Counter1 Control Register B - TCCR1B 0001 1010
7 6 5 4 3 2 1 0
ICNC1 ICES1 ? WGM13 WGM12 CS12 CS11 CS10
Timer/Counter3 Control Register A - TCCR3A
7 6 5 4 3 2 1 0
COM3A1 COM3A0 COM3B1 COM3B0 COM3C1 COM3C0 WGM31 WGM30
Timer/Counter3 Control Register B - TCCR3B
7 6 5 4 3 2 1 0
ICNC3 ICES3 ? WGM33 WGM32 CS32 CS31 CS30
Timer/Counter Control Register ? TCCR2
7 6 5 4 3 2 1 0
FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20
*/
TCCR1A = 0xA2; // FAST PWM-96
TCCR1B = 0x1A; // 8분주=0.5usec
TCCR3A = 0xA2; // FAST PWM-96
TCCR3B = 0x1A; // 8분주=0.5usec
ADCSRA=0xE7; // 프리런닝 ADC0
ICR1 = 1000; // 1/1.6 * 8 * 40000 =20ms
OCR1B = 0; // 1ms
/*
ADMUX ACD OUTPUT SELECTION
=================================================
MUX4:0 ADC INPUT PORT PIN
1100 0000 ADC0 PF0 #61
1100 0001 ADC1 PF1 #60
1100 0010 ADC2 PF2 #59
=================================================
ADC CONTROL STATUS REG ADCSRA
=================================================================================================================
7 6 5 4 3 2 1 0
ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPSO
ADC Enable--ADC START--ADC FREE RUN-- Interrupt Flag--Interrupt Enable--ADC Prescaler select-----
1 enable 1 start 1 running 1 1 enable 000: 2, 001:2, 010:4, 011:8
100:16, 101:32, 110:64, 111:128
=================================================================================================================
ADC DATA Reg. ADLAR=0 = 0:
===========================================================================
9 8
ADC9 ADC8
7 6 5 4 3 2 1 0 ADCH
ADC7 ADC7 ADC7 ADC7 ADC7 ADC7 ADC7 ADC7 ADCL
===========================================================================
ADMUX = 0xC0; // ADC INPUT PF0 설정
ADCSRA |= 0xfe;
LL = ADCL & 0xFF;
HH = ADCH & 0x03;
va0 = (int)LL + ((int)HH << 8); // A/D변환값 읽기
OCR0 = va0; // 포텐셜메터로 부터 아날로그 입력이 타이머 TCCR0 와 비교하여 PB4 포트로 PWM이 출력된다.
OCRO TCCRO COMPAR REG
===========================================================
8BIT COMPARE REG. ADC OUT PORT PIN
OCR0 OC0 PB4 #14
OCR1 OC2 PB7 #17
===========================================================
ADMUX = 0xC1; //ADC INPUT PF0 설정
ADCSRA |= 0xfe;
LL = ADCL & 0xFF;
HH = ADCH & 0x03;
va1 = (int)LL + ((int)HH << 8); // A/D변환값 읽기
OCR2 = va1; // 포텐셜메터로 부터 아날로그 입력이 타이머 TCCR2 와 비교하여 PB7 포트로 PWM이 출력된다.
*/
// OC0 PB4
// OC1A PB5
// OC1B PB6
// OC2/OC1C PB7
// OC3A PE3
// OC3B PE4
// OC3C PE5
// OCR1A = PB6, OCR1B = PB7,
while(1){
/*ADCSRA = 0xfe; // 16분주, 폴링, // ADC 인에이블 , ADSC = 1
while ((ADCSRA & 0x10) == 0); // ADIF=1(변환완료)일 때까지 기다림
ad_val = (int)ADCL+((int)ADCH << 8);
OCR1A = ad_val;
//OCR1B = ad_val;
*/
ADMUX = 0xC0; //ADC0
ADCSRA |= 0xfe;
LL = ADCL & 0xff;
HH = ADCH & 0x03;
val_adc0 = (int)LL + ((int)HH << 8); // A/D변환값 읽기
OCR0 = val_adc0;//PB4
//OCR2 = val_adc0;//PB4
ADMUX = 0xC1; //ADC0
ADCSRA |= 0xfe;
LL = ADCL & 0xff;
HH = ADCH & 0x03;
val_adc0 = (int)LL + ((int)HH << 8); // A/D변환값 읽기
OCR2 = val_adc1;//PB7
ADMUX = 0xC2; //ADC0
ADCSRA |= 0xfe;
LL = ADCL & 0xff;
HH = ADCH & 0x03;
val_adc0 = (int)LL + ((int)HH << 8); // A/D변환값 읽기
OCR1A = val_adc2;//PB6
ADMUX = 0xC3; //ADC0
ADCSRA |= 0xfe;
LL = ADCL & 0xff;
HH = ADCH & 0x03;
val_adc0 = (int)LL + ((int)HH << 8); // A/D변환값 읽기
OCR3A = val_adc3;//PE3
}
}
|
|