2017-10-05 23 views
0

두 개의 서로 다른 ADC에서 두 개의 측정 값과 두 개의 서로 다른 PWM 신호가 필요합니다. 측정 된 값은 freqduty 변수에 저장됩니다. 이름에서 알 수 있듯이, 하나의 PWM 신호의 주파수는 freq의 값에 따라 달라지며, 다른 하나는 duty에 따라 듀티 사이클을 변경해야합니다. 문제는 첫 번째 신호가 올바르게 작동하지만 두 번째 신호는 작동하지 않는다는 것입니다.왜 PWM 신호가 나오지 않습니까?

저는 ATmega328p를 사용하고 있습니다. 나는 변수 duty 대신에 상수 값을 사용하려했지만 똑같은 일이 발생했다. PWM 신호 대신에, 출력 핀 (OC0B)은 계속해서 하이, 즉 5V DC로 설정된다. 이 기능은 정말 간단하다 : 나는 트리플 체크 TCCR0 레지스터의 값을하지만 모든 것이 올바른 것 같다했습니다

//Timer0 configuration 
TCCR0A = 0b00100011; 
TCCR0B = 0b00001001; //Fast PWM, no prescaler, non-inverted, out OC0B 
OCR0B = duty; 

. 이 문제의 원인은 무엇입니까?

+0

[웹 페이지]에 대한 광범위한 토론이 있습니다 (http://www.avrfreaks.net/forum/solved-atmega328p-output-pwm-oc0a-and-oc0b). –

+0

아마도 모드 7 대신에 모드 3을 사용하기를 원할 것입니다. 그렇지 않으면'OCR0A'를 설정하는 것을 잊었습니다. –

+0

@EdgarBonet 내 무지 죄송하지만, 무슨 뜻이야? "모드 3"또는 7로 무엇을 의미하는지 이해하지 못합니다. 또한 B 출력을 사용하려면 왜 'OCR0A'를 설정해야합니까? – Tendero

답변

0

전체 답변으로 확장하십시오.

page 140 of the datasheet에는 "파형 생성 모드"인 이 모두 나열되는 표가 있습니다. 질문에 표시되는 코드는 타이머를= OCR0A 인 모드   7 : 빠른 PWM으로 설정합니다. 이 모드에서 타이머는 0부터 OCR0A에 저장된 값까지 카운트 한 다음 이 롤백되어 다시 시작됩니다. 이 모드를 사용하여 OC0B에서 PWM 신호를 으로 생성 할 수 있습니다. 그런 다음 신호 (OCR0A 레지스터를 설정하여)와 펄스 폭 (OCR0B를 통해)을 모두 제어 할 수 있습니다. OCR0A 설정에 실패하면 기본값은 0이며 작동하지 않습니다.

주기가 256  이고 만족스럽고 을 변경하지 않으려면   255를 OCR0A에 쓸 수 있습니다. 또는 은 타이머를   모드로 설정할 수 있습니다. 3 : 빠른 PWM은 TOP   = 0xff입니다. 이 모드에서 OCR0A에 저장된 값 에 관계없이 기간은 256  주기입니다.

은 아래에의 펄스 폭은 64 CPU 사이클 인 PWM 신호를 생성하고 기간은 256 회이다   모드   3. 의 사용을 보여주는 간단한 테스트 프로그램이다.

#include <avr/io.h> 

int main(void) 
{ 
    uint8_t duty = 64; 

    // Set pin PD5 = OC0B as output. 
    DDRD |= _BV(PD5); 

    // Configure Timer 0. 
    OCR0B = duty - 1; // set duty cycle 
    TCCR0A = _BV(COM0B1) // non-inverting PWM on OC0B 
      | _BV(WGM00) // mode 3: fast PWM, top = 0xff 
      | _BV(WGM01); // ditto 
    TCCR0B = _BV(CS00); // clock at F_CPU 

    for (;;) ; 
}