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

 
 
> Формирование сигнала определенного вида длительностью 1,5 мкс
Sprite
сообщение Jun 6 2008, 19:07
Сообщение #1


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

Группа: Участник
Сообщений: 173
Регистрация: 11-05-08
Пользователь №: 37 414



Доброго всем времени суток! Программирую atmga8535 с кварцем на 16 Мгц.
Возникла такая задача:

Имеется входной сигнал вида 1.
Нужно получить сигнал вида 2:

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


Длительность нулевых уровней сигнала 2 - строго фиксированная и составляет 1,5 мкс. Нулевой уровень сигнала 2 должен заканчивается в момент смены фронта сигнала 1.
Проблема в том, что частота сигнала 1 заранее не известна и может меняться в пределах 10-20 кГц.
Думаю, что придется использовать таймер 1 и захватывать сигнал по ICP.
Уважаемые эксперты, какой режим таймера выбрать?
Буду очень признателен за изложение алгоритма (хотя бы на словах)!
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
domowoj
сообщение Jun 7 2008, 01:35
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 548
Регистрация: 20-12-07
Из: г.Новосибирск
Пользователь №: 33 486



Что-то подобное делал на частоте 100Гц.
В вашем случае входной сигнал - на ITNx, меряете интервал от фронта до фронта в "тиках",
вычитаете из измеренного 1,5 мкс в тиках(при тактовой 16МГц- это число 24), полученное число в
OCRx и по прерыванию от OCRx формируете на вых. импульс.
Перый импульс пропадает.


--------------------
И на камнях растут деревья!
Go to the top of the page
 
+Quote Post
Sprite
сообщение Jun 7 2008, 04:29
Сообщение #3


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

Группа: Участник
Сообщений: 173
Регистрация: 11-05-08
Пользователь №: 37 414



Цитата(domowoj @ Jun 7 2008, 08:35) *
Что-то подобное делал на частоте 100Гц.
В вашем случае входной сигнал - на ITNx, меряете интервал от фронта до фронта в "тиках",
вычитаете из измеренного 1,5 мкс в тиках(при тактовой 16МГц- это число 24), полученное число в
OCRx и по прерыванию от OCRx формируете на вых. импульс.
Перый импульс пропадает.


Действительно реальный совет! a14.gif
И к гадалкам не надо обращаться! smile.gif

Одна немаловажная поправка:
Прикрепленное изображение


В моменты времени 5-6 границы нулевого сигнала должны быть такими же(относительно полупериода входного сигнала) как и 3-4; Другими словами: границы 3-4, 5-6 измеряются один раз в период сигнала 1.
Вот что я делаю:

Код
#include "avr/io.h"
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define LEFT_1  0
#define RIGHT_1 1
#define LEFT_2  2

//Массив границ нулевых импульсов сигнала 2
volatile uint16_t bound[3];
//bound[0] соответствует моменту времени 3 (на рисунке)
//bound[1] соответствует моменту времени 4 (на рисунке)
//bound[2] соответствует моменту времени 5 (на рисунке)

//Текущее, предыдущее значение тиков процессора и разница между ними
volatile uint16_t ICR_Current, ICR_Prev, ICR_Diff;

//Счетчик (для обращения к элементам массива bound)
volatile uint8_t count;
//========================================================
//========================================================

void InitPorts(void)
{
    DDRB = 0xFF;
    PORTB = 0;
    
    DDRD = _BV(5);
    PORTD = 0;
}

//========================================================
void InitTimers(void)
{
    //Таймер 1 -------------------------------------------
    TCCR1A = _BV(COM1A1)|_BV(FOC1A); //Сброс OC1A при совпадении с OCR1A, разрешаем вывод на ногу OC1A    
    TCCR1B = _BV(CS10); //Частота==16 МГц (без делителя), режим Normal
    TCCR1B|= _BV(ICES1); //Прерывание по захвату положительного фронта сигнала 1
    TIMSK =  _BV(TICIE1)|_BV(OCIE1A); //Разрешение прерывания по захвату и сравнению с OCR1A

    sei(); //Общий флаг разрешения прерываний
}

//========================================================
void InitValues(void)
{
    count = 0;
    ICR_Prev = 0;
}

//========================================================
int main (void)
{
    InitPorts();
    InitValues();
    InitTimers();

    for (;;)            
        sleep_mode();
}

//========================================================
//========================================================
ISR(TIMER1_CAPT_vect) //Прерывание по захвату сигнала 1
{
    ICR_Current = ICR1;

    if (count==4) //соответствует моменту времени 6 (на рисунке)
    {
        PORTD|= _BV(5); //Устанавливаем на выводе OC1A логическую 1
    }

    //Т.к. счетчик(TCNT1) циклично увеличивается до 65535 и сбрасывается в 0
    //нужно обработать ситуацию, когда в момент захвата значение счетчика лежит
    //в пределах [0;24]. При этом текущее значение == TCNT1, а предыдущее лежит
    //в пределах [65511; 65535](т.е. текущее значение МЕНЬШЕ предыдущего)

    ICR_Diff = (ICR_Current>ICR_Prev)? (ICR_Current-ICR_Prev) : (ICR_Prev-ICR_Current);
    ICR_Prev = ICR_Current;
    

    bound[RIGHT_1] =  ICR_Current + ICR_Diff/2;    //bound[RIGHT_1]соответствует моменту времени 4 (на рисунке)
    bound[LEFT_1]  =  bound[RIGHT_1]-24;            //bound[LEFT_1] соответствует моменту времени 3 (на рисунке)
    bound[LEFT_2]  =  ICR_Current + ICR_Diff-24;    //bound[LEFT_2] соответствует моменту времени 5 (на рисунке)
  
  
    //Установка вывода OC1A в "0" в последующем прерывании по сравнению
    TCCR1A&=~_BV(COM1A0);
    TCCR1A|=_BV(COM1A1);
    
    OCR1A = bound[LEFT_1]; //Установка первого прерывания по сравнению
    count = 1;
}


ISR(TIMER1_COMPA_vect) //Прерывание по сравнению сигнала
{
    OCR1A = bound[count];
    count++;
    
    //Режим TOGGLE (инвертирование состояния вывода OC1A в последующем прерывании по сравнению)
    TCCR1A|=_BV(COM1A0);
    TCCR1A&=~_BV(COM1A1);
}


Время между прерываниями по сравнению сигнала (3-4) ==24 такта, что очень малоsad.gif
Я не особо силен в ассемблере, и пока не знаю: успеет ли обработаться прерывание по сравнению за 24 такта? Скольким тактам процессора соответствует код в прерывании?!
Посмотрите свежим взглядом, может быть где ошибка допущена?
Заранее благодарен!
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Sprite   Формирование сигнала определенного вида длительностью 1,5 мкс   Jun 6 2008, 19:07
- - Flasher   Алгоритм простой- берем гадалку и пусть она говори...   Jun 6 2008, 19:26
|- - singlskv   Цитата(Flasher @ Jun 6 2008, 23:26) Алгор...   Jun 6 2008, 19:54
- - Flasher   Итак в рамках темы обсуждаем как писать гадалок. О...   Jun 6 2008, 20:00
|- - singlskv   Цитата(Flasher @ Jun 7 2008, 00:00) Итак ...   Jun 6 2008, 20:09
- - DRUID3   По маразму задачи, я так понимаю, что это ВУЗовско...   Jun 6 2008, 22:07
- - rv3dll(lex)   на сколько я понимаю что автор не понял что говоря...   Jun 7 2008, 04:15
- - INT1   Если бы знал, где упаду(отрицательный перепад) , т...   Jun 7 2008, 04:25
- - otrog   Для работы с временами порядка микросекунд просто ...   Jun 7 2008, 04:47
|- - Sprite   Цитата(otrog @ Jun 7 2008, 11:47) Для раб...   Jun 7 2008, 06:35
|- - rv3dll(lex)   Цитата(Sprite @ Jun 7 2008, 10:35) После ...   Jun 7 2008, 07:05
|- - Sprite   Цитата(rv3dll(lex) @ Jun 7 2008, 14...   Jun 7 2008, 07:50
- - Ledmaster   Цитата(Sprite @ Jun 7 2008, 01:07) Доброг...   Jun 7 2008, 07:44
|- - rv3dll(lex)   Цитата(Ledmaster @ Jun 7 2008, 11:44) Пац...   Jun 7 2008, 08:12
|- - Ledmaster   Цитата(rv3dll(lex) @ Jun 7 2008, 14...   Jun 7 2008, 09:40
- - MrYuran   Я знаю как надо поступить. 1. засекаем входной ...   Jun 7 2008, 08:44
- - Sprite   Цитата(MrYuran @ Jun 7 2008, 15:44) Я зна...   Jun 9 2008, 14:35


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

 


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


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