реклама на сайте
подробности

 
 
> tiny2313. приостановить таймер, как приостановить таймер
tazik
сообщение Nov 27 2009, 13:30
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 195
Регистрация: 13-05-07
Из: Норильск
Пользователь №: 27 691



Друг попросил сделать генератор синусоидального сигнала частотой примерно от 3 до 15 Гц. Соственно, это сделал. Загвоздка в том, как изменять генерируемую частоту с дискретностью, скажем 0.1 Гц. Синус генерирую с помощью таймера Т1 в режиме PWM. Значение PWM беру из таблицы и обновляю в обработчике прерывания при каждом достижении пилой вершины. Для уменьшения частоты генерируемого сигнала пытаюсь останавливать таймер Т1 в каждом прерывании на некоторое время. При этом, почему-то искажается форма сигнала.
Вопросы:
1. как правильно регулировать частоту генерируемого сигнала?
2. почему форма сигнала так искажается?

Прикрепленное изображение


код (tiny2313, тактовая частота 8МГц):

CODE
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "sine_table.h"

static uint16_t step_counter;
uint8_t kvadrant;
uint8_t time_delay;

void IOInit(void){
DDRB=(1<<PB3);
}

void Timer1Init(void){
ICR1=0x01FF;
TCCR1A=(1<<COM1A1);
TCCR1B=(1<<WGM13)|(1<<CS10);
TIMSK=(1<<TOV1);
}

ISR(TIMER1_OVF_vect){

TCCR1B&=~(1<<CS10); //останавливаю таймер
_delay_us(20); //пытаюсь сделать задержку, если нулевая, то искажений нет
TCCR1B|=(1<<CS10); //запускаю таймер вновь

switch(kvadrant){
case 1:{
OCR1A=pgm_read_word(pSine+step_counter);
step_counter++;
if (step_counter==511) kvadrant=2;
break;
};
case 2:{
OCR1A=pgm_read_word(pSine+step_counter);
step_counter--;
if (step_counter==0) kvadrant=3;
break;
};
case 3:{
OCR1A=0x1FF-pgm_read_word(pSine+step_counter);
step_counter++;
if (step_counter==511) kvadrant=4;
break;
};
case 4:{
OCR1A=0x1FF-pgm_read_word(pSine+step_counter);
step_counter--;
if (step_counter==0) kvadrant=1;
break;
};
};
};

int main(void){

OCR1A=0x10;
IOInit();
Timer1Init();
sei();
step_counter=511;
kvadrant=4;

while(1){

_delay_ms(500);
};
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SasaVitebsk
сообщение Nov 27 2009, 19:28
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Непонятно зачем что-то останавливать?

Частота определяется делителем таймера с учётом квантования. Ну например вы хотите запустить мегу на 8МГц, получить 16 ступенек на синус. Для этого вы должны создать таблицу из 16 значений определяющих значение сигнала с шагом Pi/8. Значения в таблице - процентные. Далее для получения нужной частоты Fi надо Fclk/(Fi*16). То есть получить делитель периода ступеньки. Значение ШИМа - есть значение периода * соответствующий процент из таблицы.

Есть соответствующий режим таймера.
Go to the top of the page
 
+Quote Post
tazik
сообщение Nov 29 2009, 10:50
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 195
Регистрация: 13-05-07
Из: Норильск
Пользователь №: 27 691



ок, то есть предлагаете использовать делитель тактовой частоты? Дело в том, что частоту генерируемого сигнала хочется менять плавно. А делителем получится только дискретно: CLK, CLK/2, CLK/4.... Отсюда и мои выкрутасы с задержкой.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 17:15
Рейтинг@Mail.ru


Страница сгенерированна за 0.01268 секунд с 7
ELECTRONIX ©2004-2016