AVR 타이머 PWM 모드로–부분 II

AVR 시리즈이 문서에서 연속으로 이전 PWM post. 이 응용 프로그램은 당신에게 아름다운 천장 디자인 아이디어의 갤러리를 보여줍니다 그래서 시작하자!

안녕하세요 여러분! 오랜 시간이 더 볼 수 없습니다! 🙂

내 이전 게시물에서는 기본 개념을 논의했습니다. 먼저 요약 해 보겠습니다:

  • 펄스 폭 변조를 의미합니다.
  • 소정 파형을 기준 전압 레벨과 비교하거나 간단한 아날로그 회로를 만들어 생성할 수 있습니다.
  • 파형의 듀티 사이클은 다음과 같은 관계에 의해 주어진다.
듀티 사이클
  • 타이머,작동 모드를 선택하고 원하는 출력 모드를 생성하기위한 출력 모드를 비교하는 방법.
이제 많은 번거 로움없이 마이크로 컨트롤러를 사용하여 구현하는 방법을 살펴 보겠습니다. 우리가 진행하기 전에,난 당신이 타이머 및 삼일성에 내 이전 게시물을 통해 이동하는 것이 좋습니다.

우리가 문제 문을 보자. 우리는 45%듀티 사이클을 갖는 50 헤르쯔의 신호를 생성 할 필요가있다.

분석

Frequency = 50 Hz

즉,기간,티

T = T(on) + T(off) = 1/50 = 0.02 s = 20 ms

또한,

Duty Cycle = 45%

따라서,위의 방정식에 따라 해결,우리가 얻을

T(on) = 9 msT(off) = 11 ms

이제이 될 수 있습니다 두 가지 방법으로 달성:

  1. 그래서 나는 여기에 어떤 코드도 쓰지 않을 것입니다(의사 코드 만).이 방법을 사용하는 것은 매우 간단합니다. 나는 내 이전 게시물을 읽은 후,당신은 하나를 직접 쓸 수있을만큼 똑똑 가정! 우리는 개념 만 논의 할 것입니다.

    첫째로,적당한 타이머를 선택하십시오. 이 응용 프로그램을 위해,우리는 32 에서 사용할 수있는 세 가지 타이머 중 하나를 선택할 수 있습니다. 적합한 프리 스케일러를 선택하십시오. 그런 다음 타이머를 설정하고 평소와 같이 진행하십시오. 여기에 있는 캐치는 매번 레지스터의 비교 값을 업데이트해야 한다는 것입니다. 그러한 방법 중 하나는 아래에 주어진 의사 코드에서 논의됩니다.

    이것은 온/오프 시간이 다르다는 사실을 제외하고,전통적인 지도된 자동 점멸장치와 유사합니다.

    의사 코드

    #include <avr/io.h>#include <avr/interrupt.h> uint8_t count = 0; // global counter // initialize timer, interrupt and variablevoid timerX_init(){ // set up timerX with suitable prescaler and CTC mode // initialize counter // initialize compare value // enable compare interrupt // enable global interrupts} // process the ISR that is firedISR (TIMERx_COMPA_vect){ // do whatever you want to do here // say, increment the global counter count++; // check for the global counter // if count == odd, delay required = 11 ms // if count == even, delay required = 9 ms // thus, the value of the OCRx should be constantly updated if (count % 2 == 0) OCRx = 9999; // calculate and substitute appropriate value else OCRx = 10999; // calculate and substitute appropriate value} int main(void){ // initialize the output pin, say PC0 DDRC |= (1 << 0); // initialize timerX timerX_init(); // loop forever while(1) { // do nothing }}

    이제 이것이 하나의 방법입니다. 그리고 그것은 매우 비효율적입니다. 더 나은 코드(구문 현명한)를 작성하여 효율성을 높일 수 있지만 개념은 동일하게 유지됩니다. 당신은 다른 방법/개념이있는 경우,당신은 여기에 공유 할 가장 환영합니다! 이 코드를 작성했으며 그를 위해 일했습니다.

    이 코드는 아직 테스트되지 않았습니다! 그래서,당신의 그것을 밖으로 시도 하는 경우,여기에 귀하의 결과 게시 할,나는 그들을 보고 행복 할 것 이다! 이 문제를 해결하기 위해 몇 가지 방법이 있습니다. 이 모드는 하드웨어로 제어됩니다. 이것은 내가”모든 것”을 의미하는 모든 것이 모든 것을 의미합니다. 당신이해야 할 모든 초기화 및 타이머를 시작하고,듀티 사이클을 설정하는 것입니다! 쿨,응?! 의 방법을 알아 보자!이 문제를 해결하려면 다음을 수행하십시오. 다른 타이머 또는 마이크로 컨트롤러를 선택할 수도 있습니다. 이제 레지스터에 대해 살펴보겠습니다.이 레지스터는 내 타임머 0 튜토리얼에서 찾을 수 있습니다. 여기서 우리는 적절한 비트를 설정하는 방법을 배우게 될 것입니다.

    우리는 지금 우리에게 관심있는 비트 만 논의 할 것입니다.0-파형 생성 모드-이 비트는 생성하려는 파형 생성기의 유형에 따라”00″또는”01″로 설정할 수 있습니다. 여기 봐 테이블입니다.

    파형 생성 모드 비트 설명

    파형 생성 모드 비트 설명

  2. 이러한 비트는 출력 비교 핀의 동작을 제어하기 위해 설정된다. 다음 표에서는 빠른 모드를 위한 핀의 동작을 결정합니다.1149>

    이제 빠른 파형 파형을 살펴 보겠습니다. 자세한 설명은 이전 자습서에서 찾을 수 있습니다.

    빠른 PWM

    빠른 PWM

    이제는 내가 당신을 생각 나게 AVR PWM 은 완전히 하드웨어,제어하는 것을 의미하는지 타이머 비교 작업에 의해 수행되 AVR CPU. 우리가 해야 할 일은 일치가 발생했을 때 무엇을 할 것인지를 알려주는 것입니다. 01:0 핀이 여기에 등장합니다. “10”또는”11″으로 설정하면 출력 핀이 설정되거나 해제됩니다.

    마찬가지로 위상이 올바른지,조회 테이블 및 파형은 다음과 같이 이동합니다.

    비교 출력 모드,위상 올바른 출력 모드

    비교 출력 모드,위상 올바른 출력 모드

    10″또는”11″로 설정하면 이 핀의 동작이 결정됩니다. 다운 카운팅 중 업 카운팅 중 하나,다른–파형에 도시 된 바와 같이,두 개의 인스턴스가 있습니다. 이 동작은 조회 테이블에 명확하게 설명되어 있습니다.

    출력 핀입니다. 따라서,그 효과는 제대로 설정되지 않으면 재생되지 않습니다. 자세한 내용은 이 자습서를 참조하십시오.이러한 비트는 이미 타임머신 튜토리얼에서 설명합니다.우리는 내 타임머 0 자습서에서도 이 레지스터를 발견했습니다. 이 레지스터를 사용하여 비교 값을 저장합니다. 그러나,그 안에 저장된 값은 듀티 사이클(분명히!). 문제 문에서 듀티 사이클이 45%인 경우,이는

    OCR0 = 45% of 255 = 114.75 = 115

    을 의미합니다. 이제 우리는 그것을 위해 코드를 작성할 준비가되었습니다! 🙂

    편집:참고

    다음 코드는 원하는 듀티 사이클의 신호를 만드는 방법에 대해 설명합니다. 당신이 그 주파수를 변경하고자하는 경우,당신은(8 비트 타이머에 의해 지원되지 않습니다)를 사용하여 수행 할 수있는 최고 값을 변경해야합니다. 나는 우리가 서보 조종 장치에 관하여 토론할 때 이것에 관하여 빨리 토론할 것입니다.

    코드

    여기 코드가 있습니다. 입력/출력 포트 작업에 대한 자세한 내용은 다음을 참조하십시오. 비트 조작에 대해 알고,이보기. 자세한 내용은 다음을 참조하십시오. 이 코드가 어떻게 구성되어 있는지 알아보려면 이전 타임머신 0 게시물을 참조하십시오.

    #include <avr/io.h>#include <util/delay.h>void pwm_init(){ // initialize TCCR0 as per requirement, say as follows TCCR0 |= (1<<WGM00)|(1<<COM01)|(1<<WGM01)|(1<<CS00); // make sure to make OC0 pin (pin PB3 for atmega32) as output pin DDRB |= (1<<PB3);} void main(){ uint8_t duty; duty = 115; // duty cycle = 45% of 255 = 114.75 = 115 // initialize timer in PWM mode pwm_init(); // run forever while(1) { OCR0 = duty; }}

    문제 문

    이제 다른 문제 문을 보자. 이 것은 이전 것과는 다른 실제적인 재료의 더 이기 위하여 려고 하고 있다!

    의 우리가 특정 주파수에서 주도 깜박 할 필요가 기존의 주도 점멸을 보자. 하지만,이봐,잠깐,우리는이 게시물에 긴 다시 논의하지 않았다(끝으로 아래로 스크롤)? 흠,그래서 그것을 수정하여 통합 할 수 있습니다. 그것은 최대 밝기에 빛을 만들 수 있습니다,그리고 천천히 0 에 도달 할 때까지 밝기를 감소,그것은 최대 될 때까지 다시 천천히 밝기를 증가.

    분석 및 코드

    어떻게 해야 할까요? 예,당신은 바로 그것을 짐작! 듀티 사이클을 255 에서 0 으로 천천히 줄인 다음 0 에서 255 로 늘립니다. 의무 주기에 따라서,지도하는에 적용된 전압은 변화합니다,따라서 광도. 다음 공식은 전압과 듀티 사이클 사이의 관계를 제공합니다.이 문제를 해결하는 데 도움이되는 몇 가지 방법이 있습니다. 나는 그것을 설명하지 않을 것이다,당신은 그것을 스스로 해독 할 수있다. 입력/출력 포트 작업에 대한 자세한 내용은 다음을 참조하십시오. 비트 조작에 대해 알고,이보기. 자세한 내용은 다음을 참조하십시오. 이 코드가 어떻게 구성되어 있는지 알아보려면 이전 타임머신 0 게시물을 참조하십시오.

    // program to change brightness of an LED// demonstration of PWM #include <avr/io.h>#include <util/delay.h> // initialize PWMvoid pwm_init(){ // initialize timer0 in PWM mode TCCR0 |= (1<<WGM00)|(1<<COM01)|(1<<WGM01)|(1<<CS00); // make sure to make OC0 pin (pin PB3 for atmega32) as output pin DDRB |= (1<<PB3);} void main(){ uint8_t brightness; // initialize timer0 in PWM mode pwm_init(); // run forever while(1) { // increasing brightness for (brightness = 0; brightness < 255; ++brightness) { // set the brightness as duty cycle OCR0 = brightness; // delay so as to make the user "see" the change in brightness _delay_ms(10); } // decreasing brightness for (brightness = 255; brightness > 0; --brightness) { // set the brightness as duty cycle OCR0 = brightness; // delay so as to make the user "see" the change in brightness _delay_ms(10); } // repeat this forever }}

    그래서 여기에 또 다른 기다려온 긴 튜토리얼이 끝납니다! 다음.. 직렬 통신! 주변에 보자!! 🙂

    당신이 어떤 제안,의심,건설적인 비판 등이있는 경우 그리고 그래,당신은 아래에 메모를 드롭하는 것이 가장 환영합니다! 내 블로그를 구독하거나 업데이트 상태를 유지하기 위해 피드를 잡아!

Write a Comment

이메일 주소는 공개되지 않습니다.