뉴티씨



  • HOME
  • 고객지원
  • 질문답변


 
ADC 입력을 통해 DC 모터 속도제어 문의
 글쓴이 : 김상용
작성일 : 21-02-16 17:26
조회 : 174  
안녕하세요.
가변저항을 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





}

}