이 문서에서 연속으로 이전 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
이제이 될 수 있습니다 두 가지 방법으로 달성:
- 그래서 나는 여기에 어떤 코드도 쓰지 않을 것입니다(의사 코드 만).이 방법을 사용하는 것은 매우 간단합니다. 나는 내 이전 게시물을 읽은 후,당신은 하나를 직접 쓸 수있을만큼 똑똑 가정! 우리는 개념 만 논의 할 것입니다.
첫째로,적당한 타이머를 선택하십시오. 이 응용 프로그램을 위해,우리는 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″로 설정할 수 있습니다. 여기 봐 테이블입니다.
파형 생성 모드 비트 설명
- 이러한 비트는 출력 비교 핀의 동작을 제어하기 위해 설정된다. 다음 표에서는 빠른 모드를 위한 핀의 동작을 결정합니다.1149>
이제 빠른 파형 파형을 살펴 보겠습니다. 자세한 설명은 이전 자습서에서 찾을 수 있습니다.
빠른 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 }}
그래서 여기에 또 다른 기다려온 긴 튜토리얼이 끝납니다! 다음.. 직렬 통신! 주변에 보자!! 🙂
당신이 어떤 제안,의심,건설적인 비판 등이있는 경우 그리고 그래,당신은 아래에 메모를 드롭하는 것이 가장 환영합니다! 내 블로그를 구독하거나 업데이트 상태를 유지하기 위해 피드를 잡아!