뉴티씨



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


 
ADC 입력을 통해 DC 모터 속도제어 문의
 글쓴이 : 관리자
작성일 : 21-02-17 14:44
조회 : 26  

안녕하세요 고객님,
저희 뉴티씨 제품을 이용해주셔서 감사합니다.

코드는 잘 짜신 것 같습니다.

다만 오타때문에 나머지 동작이 안되는 것 같습니다.
ADC를 읽어오는 것과 사용하는 변수명이 달라서, 사용이 안되고있습니다.

캡쳐 올려드렸으니 해당 변수 맞게 수정하시고 또 문제가 있다면 연락 부탁드리겠습니다.

감사합니다.

>
>
> 안녕하세요.
> 가변저항을 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
>
>
>
>
>
> }
>
> }
>