Генератор меандра на Atmega16

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 1
Зарегистрирован: Чт янв 19, 2017 17:26:29

Сообщение Алексей НН »

Здравствуйте уважаемые форумчане!

Не так давно начал заниматься программированием микроконтроллеров.
Периодически пишу различные небольшие программки в CodeVisionAVR.
Обычно если у меня возникают какие-то вопросы,то справляюсь (курю) сам в даташите или Гугле....
Но тут я вообще затупил((((.... :(

Товарищи прошу вашей помощи!
Для очередной моей задачи нужно сделать генератор меандра на МК с регулировкой частоты и длительности импульса.

-----------------------------------------------------------------------------------------------
Подскажите как организовать генерацию меандра с управлением...
Параметры частоты особо не критичны: от 10 Hz до 50(100)kHz шаг-желательно 100-500Hz
Длительность 10мкс(мин)
Переферию прицеплю сам...
------------------------------------------------------------------------------------------------
P.S.Пробовал генерировать импульсы в прерывании по переполнению таймера Т0
А в этой функции постоянно увеличивать переменную...и при достижении определенного значения изменять состояние лапки КОТа (МК)
Примерно вот так:
interrupt [TIM0_OVF] void timer0_ovf_isr(void){
count++;
if(count==b){
FRIQ=1;
delay_us(10);
FRIQ=0;
count=0;
}
}
Значение переменной b мы меняем кнопками (Увеличиваем или уменьшаем) а FRIQ это порт в дефайне...
Код относительно рабочий....частота меняется,но непонятно(
например при значении:
b=9000 частота на выходе равна 14200hz
b=10000 частота составляет 27000hz
а к примеру при меньших значениях переменной b частота на выходе изменяется более плавно....
b=1000 частота на выходе равна 3000hz
b=2000 частота составляет 3300hz
Частота работы МК стабилизируется кварцевым резонатором на 16Mhz.
Фьюзы вроде тоже правильно зашил....
Реклама
Родился
Сообщения: 18
Зарегистрирован: Чт ноя 24, 2016 20:16:46

Сообщение krash_artem »

Читай режимы ШИМ таймеров. В частности CTC
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

В вашем случае регулируется не частота а длительность периода. Период обратно пропорционален частоте T = 1/f.
Вы используете в прерывании таймера "тупые" задержки, да еще нерегулируемые. Так делать нельзя.
Если хотите получить меандр (последовательность прямоугольных импульсов, у которых длительность импульса равна длительности паузы) на прерывании таймера (проще сделать на ШИМе, но лучше сами даташит почитайте, там несложно), стоит просто инвертировать вывод:

Код: Выделить всё

#define PORT_PWM PORTB //задавать выводы именно так не слишком удобно, я бы задавал как #define PWM_OUT B,2 и далее самописными макросами, но вам это пока рано
#define BIT_PWM 2
volatile uint16_t T_pwm = 10; //модификатор volatile важен! Он говорит компилятору, что переменная может измениться или использоваться где и когда угодно. Обычно это сигналы, прерывания или отображаемая в память периферия.
//для примера, предположим, что прерывание вызывается с частотой 1 МГц (максимальная частота, обеспечивающая выход 10 Гц при двухбайтном делителе). Впрочем, быстродействия ядра может и не хватить на такое, но это ради примера.
ISR(TIMER1_COMPA_vect){ //прерывание объявлено в стиле avr-gcc, синтаксис cvavr мне незнаком, да и несовместим с Си
  static uint16_t count = 0; //модификатор static говорит, что после выхода из прерывания (в общем случае - функции) переменная не будет потеряна, а сохранится до следующего вызова. При этом снаружи она не видна (т.е. ее сложнее случайно испортить).
  count++;
  if(count > T_pwm){
    count = 0;
    PORT_PWM ^= (1<<BIT_PWM); //операция "побитовый XOR", в данном случае инвертирует один бит. Для подробностей см. описание битовых и логических операций.
  }
}
//процедура изменения частоты меандра
void SetFreq(uint32_t freq){
  uint32_t f_t1 = 500000; //половина частоты срабатывания прерывания, потому что оно выдает не целый период частоты, а только импульс или паузу
  f_t1 = f_t1 / freq;
  T_pwm = f_t1;
}
Ответить

Вернуться в «AVR»