Программирование AVR Синтез двухчастотного сигнала с помощью ШИМ Tue, November 12 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


Синтез двухчастотного сигнала с помощью ШИМ Печать
Добавил(а) microsin   

Этот пример кода генерирует на ножке OC1A (PD5) микроконтроллера ATmega32A сигнал ТРЦ с помощью режима быстрого ШИМ (Fast PWM Mode).

[pwm.h]

Константами TRC420_8_MAIN и TRC420_8_MOD задаются основная частота и частота модуляции ТРЦ. Таблица SinusTable сгенерирована с помощью утилиты sinus-table-generator, см. архив [7].

#pragma once
 
#include 
#include 
 
// Для ATmega32A используется кварц на 20 МГц. Для надежного
// запуска генерации на плате AVR-USB-MEGA16 [5] следует выпаять
// конденсаторы C3 и C4.
#define F_CPU 20000000
 
// Частота ШИМ в режиме Fast PWM, Гц:
#define PWM_FREQ  5000
#define PWM_TOP (F_CPU/PWM_FREQ)
 
#define TRC_OVERMODULATION (1.29)
#define TRC420_8_MAIN   420
#define TRC420_8_MOD    8
 
extern const signed char SinusTable [256];
 
void FastPWMstart(void);

[pwm.c]

В модуле pwm.c находится обработчик прерывания таймера 1 и подпрограмма запуска ШИМ FastPWMstart:

#include "pwm.h"
 
float phaseincHi = 256.0*(float)TRC420_8_MAIN/PWM_FREQ;
float phaseincLo = 256.0*(float)TRC420_8_MOD/PWM_FREQ;
float phaseHi = 0;
float phaseLo = 0;
float ScaleCoef;
 
// Настраивает для ATmega32A таймер TIMER1 в режиме
// Fast PWM Mode с генерацией ШИМ на ножке OC1A (PD5).
void FastPWMstart (void)
{
   //ScaleCoef = 6.8231441;
   ScaleCoef = ((float)PWM_TOP/2)/((float)128 * (1 + TRC_OVERMODULATION));
   
   //Считать счетчик будет до ICR1:
   ICR1 = PWM_TOP;
   //Сравниваемая величина для меандра:
   OCR1A = PWM_TOP/2;
   // Очистка уровня OC1A/OC1B (установка выхода в лог. 0)
   // при Compare Match, тактовая частота равна F_CPU
   // (настроено опциями компилятора на 20 МГц):
   TCCR1A = (1 << COM1A1)|(1 << WGM11);
   TCCR1B = (1 << WGM13)|(1 << WGM12)|(1 << CS10);
   //Настройка ножки OC1A как выход:
   DDRD |= (1 << PWM_OUT);
   //Разрешить прерывание для TIMER1_OVF_vect:
   TIMSK = (1 << TOIE1);
}
 
// Обработчик прерывания таймера 1. Прерывание переполнения происходит,
// когда счетчик достигает предела счета TOP (в нашем случае ICR1).
ISR(TIMER1_OVF_vect)
{
   static u16 OCRnext = 0;
   s16 uc, um, uam;
 
   OCR1A = OCRnext;
 
   uc = SinusTable [(u8)phaseHi];
   um = SinusTable [(u8)phaseLo];
   uam = ScaleCoef * uc * (1 + TRC_OVERMODULATION * ((float)um/127));
 
   phaseHi = phaseHi + phaseincHi;
   if (phaseHi >= 256)
   {
      phaseHi = phaseHi - 256;
   }
   phaseLo = phaseLo + phaseincLo;
   if (phaseLo >= 256)
   {
      phaseLo = phaseLo - 256;
   }
 
   //Возможный диапазон от 0 до PWM_TOP:
   OCRnext = PWM_TOP/2 + uam;
}
 
void pwmstop (void)
{
   TCCR1B = 0;
}

[main.c]

Тело основной программы, где запускается генерация:

#include "pwm.h"
 
void main (void)
{
   FastPWMstart();
   sei();
   
   while(1)
   {
   }
}

[Фильтр для сигнала ШИМ]

Поскольку ШИМ работала на 5 кГц, то для получения качественного сигнала ТРЦ был спроектирован фильтр Чебышева 6-го порядка с полосой пропускания 2 кГц и частой среза 5 кГц при подавлении -60 дБ. Фильтр был синтезирован с помощью онлайн-утилиты Filter Design от компании Texas Instruments [6].

TRC420 8 OP482G filter chebyshev 2kHz SCH

В качестве операционного усилителя лучше всего подошел счетверенный OP482G.

TRC420 8 OP482G filter board1

Сигнал ТРЦ на экране осциллографа:

TRC420 8 ATmega32A PWM

[Ссылки]

1Использование 16-bit Timer/Counter1 для измерения и подсчета импульсов.
2AVR130: настройка и использование таймеров AVR.
3Таймеры-счетчики ATmega2560.
4ATmega32: 16-битный таймер/счетчик 1.
5Макетная плата AVR-USB-MEGA16.
6. Filter Design Tool site:ti.com.
7201209031346trc-gen-avr.zip.
8. ATmega16 - PWM с помощью T/C0, T/C1, T/C2.

 

Добавить комментарий


Защитный код
Обновить

Top of Page