shemmer
Jul 24 2009, 03:25
Добрый день. Собственно нужна идея как можно получить генерацию пачки импульсов такого вида с использованием ШИМ в Attiny 26
Сам сигнал должен иметь вид IIIIIIII________IIIIIIII - те в пачке 8 импульсов, частота заполнения 50 Кгц, длительность паузы ~ 50 мс,
Проблема в том как корректно отключить ШИМ на заданное время паузы.
А у Вас процессор сильно загружен?
stells
Jul 24 2009, 04:50
Цитата(shemmer @ Jul 24 2009, 07:25)

Проблема в том как корректно отключить ШИМ на заданное время паузы.
а что тут можно придумать, кроме как считать эти импульсы? если у Вас неинвертированный ШИМ, то прерывание по совпадению, подсчет, сравнение, отключение ШИМ. можно этот же таймер запустить дальше на 50мс
shemmer
Jul 24 2009, 05:41
Загрузка следующая - генерация ШИМ, передача раз в 50 мс байта по SPI (USI) а также обработка прерывания от INT0 + таймер 0 для подсчета интервалов времени
У меня вариант генерирую пачку, когда TCNT1 досчитал до 8, выключаю ШИМ. Контролирую время в 50 мс с посощью TCNT1.
Как только прошло 50 мс, запускаю снова.
shemmer
Jul 25 2009, 09:23
Что-то я запутался, как проконтролировать факт генерации 8 импульсов? Как мне подсчитать что прошло именно 8 импульсов?
stells
Jul 25 2009, 09:25
формировать прерывание по каждому импульсу и считать
По моему нужно сделать тупо:
Код
#include <inttypes.h>
#include <interrupt.h>
#include <sig-avr.h>
#include <io.h>
volatile uint8_t rpr;
#define RTIM0 1 //признак прерывания от таймера 0
//---------------------------------------------------------
SIGNAL(SIG_OVERFLOW0)
{
TCNT0 = 0xfb;
rpr |= RTIM0;
}
//---------------------------------------------------------
void timer0_ini(void)//инициализация таймера 0
{
TIMSK |= 0x01;//прерывание по переполнению
TCCR0 = 0x05;//частота CPU/1024
TCNT0 = 0xfb;//1 мсек при кварце 4096 МГц
}
//---------------------------------------------------------
int main(void)
{
timer0_ini();
DDRB=0x01;
sbi(PORTB,0);
static uint8_t sch_;//
sei();
for(;;)
{
if(rpr & RTIM0)
{
sch_ ++;
if(sch_<16)
{
if(sch_&0x01) sbi(PORTB,0);
else cbi(PORTB,0);
}
else cbi(PORTB,0);
if(sch_>116) sch_=0;
}
else
{
}
}
}
Здесь правда сделано под WinAvr и таймер 0 ... sorry!
shemmer
Jul 25 2009, 10:39
Я в ИАРе сделал вот так
Код
#pragma vector=TIMER1_CMPB_vect
__interrupt void Timer(void)
{
n++;
if (n>=4)
{
n=0;
TCCR1A=0x00;
}
else TCCR1A=0x35;
}
Правда с точностью до одного импульса не получается.
Осталось прикрутить задержку в 50 мс
Цитата(shemmer @ Jul 25 2009, 16:39)

Осталось прикрутить задержку в 50 мс
А зачем ее прикручивать, если не выполняется требование 8 импульсов ?
shemmer
Jul 25 2009, 12:21
у меня получилось 10 импульсов, что в принципе, подойдет
stells
Jul 25 2009, 12:23
Цитата(shemmer @ Jul 25 2009, 16:21)

у меня получилось 10 импульсов, что в принципе, подойдет
настроиться можно и точно на 8, видимо есть ошибка
shemmer
Jul 25 2009, 14:16
Я тоже считаю что у меня где-то некорректно, только вот где?
Вот так удалось получить пачку из 8 импульсов
Код
#pragma vector=TIMER1_CMPB_vect
__interrupt void Timer(void)
{
n++;
Count50ms++;
if (n==2) // По идее это количество импульсов в пачке
{
n=0;
TCCR1A=0x00;
}
if (Count50ms>=500) // Длительность паузы между пачками
{
TCCR1A=0x21;
Count50ms=0;
}
}
PLLCSR=0x07;
Вообще стоит ли программировать фуз PLLCK?
shemmer
Jul 26 2009, 07:08
Вопрос решился сбрасывал не в том месте счетчик импульсов. В продолжение темы хотел бы задать еще один вопрос.
Есть ли возможность программно заставить начать считать модуль ССР в attiny261? А останавливать счет по фронту входного импульса?
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.