Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прочитать передачу
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
micronano
Добрый день!

Кто-нибудь может подсказать как прочитать передачу некоего интерфейса?
Известна его его скорость и структура.

Пытаюсь по первому биту запускать таймер, и с частотой раз в бит увожу контроллер в прерывание, где считываю значение порта.
Но огромное количество ошибок самого разного плана: сдвиг, чтение 1 вместо 0, чтение 0 вместо 1... Не знаю что делать.

Сигнал прямоугольный, так что дело к коде.

Есть программные алгоритмы приема?
Непомнящий Евгений
По идее надо читать несколько раз за бит, а уровень бита определять по большему числу выборок (или требовать чтобы все выборки были одинаковыми)

А так ничего особо сложного вроде бы нету...
AHTOXA
Цитата(micronano @ Aug 2 2011, 15:50) *
Пытаюсь по первому биту запускать таймер, и с частотой раз в бит увожу контроллер в прерывание, где считываю значение порта.


По первому фронту(или спаду) надо запускать на пол-бита, чтоб попасть в середину. А уже все последующие - через целый бит.
kovigor
Цитата(micronano @ Aug 2 2011, 12:50) *
Кто-нибудь может подсказать как прочитать передачу некоего интерфейса?


Формат посылки известен ? Если совершенно точно известно, как устроены посылки, известна скорость, на которой работает интерфейс, и проч., то выберите подходящий аппаратный интерфейс, входящий в состав вашего МК, и на нем все сделайте. Если такого итерфейса у вашего МК нет, то поищите МК с необходимым вам интерфейсом. Если такого МК нет, то придется имитировать этот интерфейс программно (если интерфейс медленный) или используя ПЛИС (если он быстрый). А если формат посылки точно не известен, то придется захватывать посылки, например, хорошим осциллографом или лог. анализатором, а затем изучать их вручную.

P.S. Из вашего сообщения ничего нельзя понять. Неужели так трудно изложить свои мысли яснее ?
micronano
Непомнящий Евгений
Да, спасибо, как вариант.

AHTOXA, это не влияет. и фо фронту пробовал, и в середине бита.

kovigor, если бы такой интерфейс бы был, я бы не пытался прочитать его столь извращенно.
И если бы был такой МК с таким интерфейсом, то я бы взял его.
Формат известен!

Цитата
Есть программные алгоритмы приема?
- я пришел к тому же выводу, что и вы, и сразу задал такой вопрос! =) Минуя очевидные вещи.
kovigor
Цитата(micronano @ Aug 2 2011, 13:07) *
Формат известен!

- я пришел к тому же выводу, что и вы, и сразу задал такой вопрос! =) Минуя очевидные вещи.


Тогда и говорить не о чем - делайте программно, если скорость позволяет. А алгоритм зависи от того, что это за интерфейс. Одно дело - UART, и совсем другое - I2C или SPI ...
Непомнящий Евгений
Цитата
Но огромное количество ошибок самого разного плана: сдвиг, чтение 1 вместо 0, чтение 0 вместо 1... Не знаю что делать.


Выдайте на ножку момент выборки, а на другую - ее результат, сравните это с реальным входом.
Возможно у вас какая-то ошибка в программе, и вы не в то время проверяете порт...
micronano
Вот я и прошу подсказать существующие алгоритмы!! Т.к. мне нужно сделать это программно! И это не UART, не I2С, не SPI!!!
kovigor, вы не чувствуете, что ничем не помогли, а просто проконстатировали то, что я и так уже написал? Не можете помочь алгоритмом - не отвечайте, можете - я буду вам очень благодарен!

Непомнящий Евгений
Цитата
Выдайте на ножку момент выборки, а на другую - ее результат, сравните это с реальным входом.
Возможно у вас какая-то ошибка в программе, и вы не в то время проверяете порт...

выдайте на ножку момент выборки - не понял)
на другую - её результат - тоже не понял =)
И что такое реальных вход?

что есть что?=)

Ммм сложно представить, как прерывание по сравнению может считывать не в тот момент...=)
Или я что- то не понимаю..
Непомнящий Евгений
В момент, когда читаете вход, инвертируйте некоторый выход МК.
Потом берете осциллограф и сравниваете реальный входной сигнал и моменты его считывания вашей программой.
micronano
Теперь понял.
Цитата
Потом берете осциллограф и сравниваете реальный входной сигнал и моменты его считывания вашей программой.

А что мне это даст? ошибки от этого никуда не денутся и их причину я не пойму... Я увижу тоже самое, что и видел до этого! =)
Просто например бывает что вместо сообщения (порядка 60 бит выборки), мне приходят 60 "1"... (состояние на линии без передачи - "1")

Логика окончания приема сообщения - пауза в 50 бит перед следующим сообщением, состоящая из "1"
Непомнящий Евгений
Ну как что даст - отсечете какие-то виды ошибок...

Потом еще что-нить попробуете, еще какие-то ошибки отсечете. И так до победного

Возможно у вас не в те моменты срабатывает прерывание - например другие прерывания слишком тяжелые. Или просто в программе ошибка. Да мало-ли что может быть...
SSerge
Даже если битовая скорость известна, то никто не обещал что тактовая частота приёмника точно совпадает с тактовой частотой передатчика.
Со временем неизбежно накапливается ошибка.
Нужно подстраивать свою скорость приёма под скорость следования битов в принимаемом сигнале.
В зависимости от способа кодирования это можно делать по-разному, обычно это некая разновидность цифровой ФАПЧ, которая синхронизируется по фронтам сигнала.
micronano
Других прерываний нет =)
В программе кроме считывания передачи и отправки пакетов на компорт, ничего нет...

Ошибки конечно есть, но какого плана...

Цитата
Даже если битовая скорость известна, то никто не обещал что что тактовая частота приёмника точно совпадает с тактовой частотой передатчика.
Со временем неизбежно накапливается ошибка.
Нужно подстраивать свою скорость прима под скорость следования битов в принимаемом сигнале.
В зависимости от способа кодирования это можно делать по-разному, обычно это некая разновидность цифровой ФАПЧ которая синхронизируется по фронтам сигнала.


каждое сообщение (порядка 60 бит), таймер запускаю заново по фронту первого бита, т.ч. врятли за 60 бит накапливается ошибка... Тем более что иногда (очень редко) приходит то, что надо!
Непомнящий Евгений
Сделайте без прерываний ради интереса.

На самом деле все должно быть очень просто. Вероятно какая-то тупая ошибка sm.gif

Приведите здесь код, если его немного. Может кто-нить сразу увидит в чем дело
micronano
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include "uart_i2c.h"

volatile int i = 0, pause = 0, uart = 0; // i - length of telegramm, pause - length of pause after telegramm
char s[64];

#define F_CPU 1843200L

// I/O ports init
void init_io_ports()
{ DDRA =(1<< DDA0)|(1<< DDA1)|(1<< DDA2)|(1<< DDA3)|(1<< DDA4)|(1<< DDA5)|(1<< DDA6)|(1<< DDA7);
DDRB =(1<< DDB0)|(1<< DDB1)|(1<< DDB2)|(1<< DDB3)|(1<< DDB4)|(1<< DDB5)|(1<< DDB6)|(1<< DDB7);
DDRC =(0<< DDC0)|(0<< DDC1)|(1<< DDC2)|(1<< DDC3)|(1<< DDC4)|(1<< DDC5)|(1<< DDC6)|(1<< DDC7);
DDRD =(1<< DDD0)|(1<< DDD1)|(1<< DDD2)|(1<< DDD3)|(1<< DDD4)|(1<< DDD5)|(1<< DDD6)|(1<< DDD7);

PORTA =(0<< PA0)|(0<< PA1)|(0<< PA2)|(0<< PA3)|(0<< PA4)|(0<< PA5)|(0<< PA6)|(0<< PA7);
PORTB =(0<< PB0)|(0<< PB1)|(0<< PB2)|(0<< PB3)|(0<< PB4)|(0<< PB5)|(0<< PB6)|(0<< PB7);
PORTC =(1<< PC0)|(1<< PC1)|(0<< PC2)|(0<< PC3)|(0<< PC4)|(0<< PC5)|(0<< PC6)|(0<< PC7);
PORTD =(0<< PD0)|(0<< PD1)|(0<< PD2)|(0<< PD3)|(0<< PD4)|(0<< PD5)|(0<< PD6)|(0<< PD7);
}


//************************************* Timer ****************************************************
// Timer0 8bit init, no prescaler, CTC mode
void init_timer()
{ TCCR0 = (0<< FOC0)|(0<< WGM00)|(0<< COM01)|(0<< COM00)|(1<< WGM01)|(0<< CS02)|(0<< CS01)|(1<< CS00);
TIMSK = (1<< OCIE0); // enable interrupts
sei(); // enable interrupts
SREG = (1<< 7); // enable interrupts
OCR0 = 192; // 1.8432Mhz of Xtal / 9600Hz = 192
}

//******************************** Interrupt Vector ************************************************
ISR(TIMER0_COMP_vect) // interrupt vector
{
if (i <= 64) // while telegramm is ON 64
{

if((PINC & (1 << PC0)) == 1)
{s[i] = '0';} // write "0" in s[i]
else
{s[i] = '1';} // write "1" in s[i]
i++;
}

else
{
if ((PINC & (1 << PC0)) == 0) //waiting the end of pause
{pause++;}
else
{pause = 0;}
}

}

//**************************************** MAIN ****************************************************
int main(void)
{
init_io_ports();
init_uart();

while (1)
{
i = 0;
pause = 0;
uart = 0;
if((PINC & (1 << PC0)) == 1) // waiting first "0" in Transmition on PC0

{
_delay_ms(0.010);
init_timer();
TCCR2 = 254;
while (pause <= 50) // pause after telegramm = 50 bit
{}
TCCR2 = 0; // stop timer TCNT2
putstr(s);
}

}


return 0;
}

Цитата
Сделайте без прерываний ради интереса.

На самом деле все должно быть очень просто. Вероятно какая-то тупая ошибка sm.gif

Приведите здесь код, если его немного. Может кто-нить сразу увидит в чем дело

без прерываний как?

Глупы ошибки это да... =)
kovigor
Цитата(micronano @ Aug 2 2011, 13:21) *
kovigor, вы не чувствуете, что ничем не помогли, а просто проконстатировали то, что я и так уже написал? Не можете помочь алгоритмом - не отвечайте, можете - я буду вам очень благодарен!


Я чувствую, что вы не желаете описать вашу проблему человеческим языком. Что вам нужно ? Принимать биты ? Принимайте по прерыванию (если они следуют один за другим не очень быстро. Только учтите, что компилятор при вхождении в обработчик складывает регистры в стек, а это съедает львиную долю быстродействия. Или вам надо сложить биты в слова ? Тогда поможет обычный цифровой автомат. конкретный ответ дается на конкретный вопрос. Или вы думаете, что я могу читать мысли ?
ILYAUL
Не понятго

Цитата
Сигнал прямоугольный,
меандр , что ли?

Цитата
Просто например бывает ,что вместо сообщения (порядка 60 бит выборки), мне приходят 60 . "1"... (состояние на линии без передачи - "1")


Точки и запятые в фразе расставил я. Но , что такое вместо 60 приходят 60 , я не расшифровал

Зато понятно, что можно спокойно использовать прерывание INTX для принятия посылки
_Pasha
Пишут Вам пишут, что надо дождаться фронта, сдвинуть моменты чтения на полпериода и смело принимать, а Вы так и не хотите... Ну-ну laughing.gif
micronano
kovigor, да, мне нужно принимать биты..

ILYAUL, а не надо было расставлять точки, там все нормально было!=) Вместо сообщения, в котором "0" и "1" должно быть примерно пополам, мне приходит сообщение из одних только "1".
Меандр - прямоугольный сигнал со скважностью 2. Прямоугольный =НЕ пилообразный, НЕ синусоида и т.д.

Цитата
Зато понятно, что можно спокойно использовать прерывание INTX для принятия посылки

Это что за прерывание? Можно поподробнее, пожалуйста?

_Pasha, я на это уже ответил, что я так уже пробовал! ничего не меняется, абсолютно! К сожалению. Я экспериментировал с задержками как только можно! =(
ILYAUL
Цитата(micronano @ Aug 2 2011, 15:54) *
ILYAUL, а не надо было расставлять точки, там все нормально было!=) Вместо сообщения, в котором "0" и "1" должно быть примерно пополам, мне приходит сообщение из одних только "1".
Меандр - прямоугольный сигнал со скважностью 2. Прямоугольный =НЕ пилообразный, НЕ синусоида и т.д

Т.е слово импульсный Вам не знакомо, будем знать
micronano
ILYAUL, считайте что хотите.
Чем вам не понравилось слово прямоугольный, не понимаю.
Marian
Нарисуйте, как у вас выглядит лог. "1" и лог. "0", это для того чтобы представлять как они кодируются.
Если сигнал медленный, настройте внешнее прерывание на изменение уровня.
В прерывании запускаете таймер и сохраняете (в массив) длительность импульсов.
Если скорости хватает, походу и декодируете, если нет, декодированием занимаетесь уже приняв всю посылку.
ILYAUL
Цитата(Marian @ Aug 2 2011, 21:20) *
В прерывании запускаете таймер и сохраняете (в массив) длительность импульсов.

Это лишнее

Цитата
Чем вам не понравилось слово прямоугольный, не понимаю.

В электронике есть чёткое определение таких сигналов - импульсный сигнал
Marian
Цитата(ILYAUL @ Aug 2 2011, 20:31) *
Это лишнее


Я предложил рабочий алгоритм, а выкинув его часть он работать не будет.

"Слово из песни не выкинешь"
ILYAUL
Цитата(Marian @ Aug 2 2011, 21:35) *
А вы что, знаете какая скорость и какая форма сигнала ?

На скорость - вобщем-то наплевать , лишь бы несовпадала с частотой процессора , а форма - прямоугольная. См. начало топика.
Но Вы на верном пути- осталось написать обработчик прерывания, но надо ещё чуть-чуть и поймёте почему это лишнее
Цитата
В прерывании запускаете таймер и сохраняете (в массив) длительность импульсов.
Marian
Цитата(ILYAUL @ Aug 2 2011, 20:44) *
На скорость - вобщем-то наплевать , лишь бы несовпадала с частотой процессора , а форма - прямоугольная. См. начало топика.
Но Вы на верном пути- осталось написать обработчик прерывания, но надо ещё чуть-чуть и поймёте почему это лишнее

Как раз вся загвоздка в скорости.
Скажем так, чтобы принять сигнал с частотой 100 KHz, проц должен работать на частоте от четырех до десяти раз выше.(если писать на ассемблере, чуть пониже)

Если в прерывании не заниматься декодированием, то есть возможность принимать посылку с долее высокой частотой следования импульсов.




Цитата(ILYAUL @ Aug 2 2011, 20:44) *
а форма - прямоугольная.


Такое название мне тоже не нравиться.
Любой цифровой сигнал будет иметь импульсы прямоугольной формы.

Сигнал прямоугольной формы мне представляется(похоже и другим участникам форума) меандр определенной частоты с заполнением столько та процентов.
Все остальное импульсный сигнал.

Цитата(micronano @ Aug 2 2011, 13:36) *
каждое сообщение (порядка 60 бит), таймер запускаю заново по фронту первого бита, т.ч. врятли за 60 бит накапливается ошибка... Тем более что иногда (очень редко) приходит то, что надо!

Вам, в 12 посте подсказали, что необходима синхронизация.

Посмотрите http://ru.wikipedia.org/wiki/%D0%9C%D0%B5%...%BB%D0%BE%D0%B2

Обратите внимание на Манчестерское кодирование.
ILYAUL
Цитата(Marian @ Aug 2 2011, 22:31) *
Как раз вся загвоздка в скорости.
Скажем так, чтобы принять сигнал с частотой 100 KHz, проц должен работать на частоте от четырех до десяти раз выше.(если писать на ассемблере, чуть пониже)

Всё значительно проще ,чем запускать счётчик и что то считать - в прерывании по INITX - достаточно отслеживать фронты- (т.к. из полезного , что нам сообщил топикстартер , это то что начальный уровень лог. 1) - поэтому ждём прерывание по спаду, в прерывании записываем в память zero , и переключаем на прерывание по фронту , получили пишем лог 1 , переключаем на спад фронта и т.д. - Скорость == количеству команд используемых в обработке прерывания , естественно на asm будет выше , т.к. в стек загонять ничего не требуется, если идёт только прием данных.

Но всё это при условии практически идеальной линии - или откуда там этот сигнал поступает
Marian
Цитата(ILYAUL @ Aug 2 2011, 21:57) *
Всё значительно проще ,чем запускать счётчик и что то считать - в прерывании по INITX - достаточно отслеживать фронты- (т.к. из полезного , что нам сообщил топикстартер , это то что начальный уровень лог. 1) - поэтому ждём прерывание по спаду, в прерывании записываем в память zero , и переключаем на прерывание по фронту , получили пишем лог 1 , переключаем на спад фронта и т.д. - Скорость == количеству команд используемых в обработке прерывания , естественно на asm будет выше , т.к. в стек загонять ничего не требуется, если идёт только прием данных.

Этот вариант без кодирования исходного сигнала, даже сигнал пультов радио аппаратуры кодированный.
ILYAUL
Цитата(Marian @ Aug 2 2011, 23:02) *
Этот вариант без кодирования исходного сигнала, даже сигнал пультов радио аппаратуры кодированный.

Кодированный не кодированный - об этом история умалчивает, главное, что прямоугольный , прерывания будут работать biggrin.gif

И ещё настораживает вот эта фраза из кода
Цитата
pause after telegramm
Marian
Цитата(ILYAUL @ Aug 2 2011, 21:57) *
Скорость == количеству команд используемых в обработке прерывания

Это не соответствует действительности.
Скорее так :
"Скорость ==" частота проца делить на "количеству команд используемых в обработке прерывания "
Чем меньше команд в прерывании тем выше скорость.
ILYAUL
Цитата(Marian @ Aug 2 2011, 23:14) *
Это не соответствует действительности.
Скорее так :
"Скорость ==" частота проца делить на "количеству команд используемых в обработке прерывания "

Конечно, конечно
Marian
Цитата(ILYAUL @ Aug 2 2011, 22:05) *
И ещё настораживает вот эта фраза из кода

Что тут не понятного, пауза после посылки.
ILYAUL
Цитата(Marian @ Aug 2 2011, 23:19) *
Что тут не понятного, пауза после посылки.

Там слово телеграмма - а это накладывает определённые параметры на протокол передачи и и обычно это USART
Marian
Посмотрите Отрисовка сигнала.
Создавалась для отрисовки сигнала пультов, отрисует и цифровой сигнал, если подойдет по скорости,
Есть проект для протеуса, если интересует могу выложить.
нечитатель
Цитата(micronano @ Aug 2 2011, 13:50) *
по первому биту запускать таймер, и с частотой раз в бит увожу контроллер в прерывание, где считываю значение порта.
Но огромное количество ошибок самого разного плана: сдвиг, чтение 1 вместо 0, чтение 0 вместо 1
На всякий случай вспомнил бы о картинках из описания к микросхеме типа AVR *. Которые в разделе про уарт. В смысле асинхронный. Которые переопубликовывать вручную уже от своего имени представляется нецелесообразным.
Или много букв про не понял что здесь пишут.

* особенно когда даже название раздела выбрано...
ILYAUL
Цитата(Marian @ Aug 2 2011, 23:33) *
Посмотрите Отрисовка сигнала.
Создавалась для отрисовки сигнала пультов, отрисует и цифровой сигнал, если подойдет по скорости,
Есть проект для протеуса, если интересует могу выложить.

А почему бы и нет , положите вот сюда:
http://electronix.ru/forum/index.php?showtopic=10934
Вдруг и в правду кому-то понадобится , а по поводу этого топика , при таком "количестве "полезной" информации от топикстартера, мы можем только гадать
Dog Pawlowa
Цитата(micronano @ Aug 2 2011, 13:36) *
каждое сообщение (порядка 60 бит)

Похоже, Вы мучаете интерфейс какой-нить микросхемы радио управления.

Есть простой способ - используете прерывание capture и складываете отсчеты таймера в буфер. Индекс буфера обнуляется при отсутствии фронтов в течение определенного времени.
Потом, пройдясь по буферу с начала до конца, можно спокойно проанализировать, что же там передавалось.
micronano
Marian, ILYAUL, спасибо.
Попробую сделать на прерываниях по фронту/спаду и записью длительности...

Dog Pawlowa, нет, это не интерфейс какой-нить микросхемы радио управления. =)
ArtemKAD
Цитата(micronano @ Aug 2 2011, 15:14) *
ILYAUL, считайте что хотите.
Чем вам не понравилось слово прямоугольный, не понимаю.

Наверное тем, что когда речь о "0" и "1" или о протоколе, они все прямоугольные... Это не информативно.
Надо знать как передается эти "0" и "1". Это может быть просто уровень, это может быть скважность, это может быть период(частота), это может быть что-то еще. Вариантов там воз и маленькая тележка.
И вообще, что Вы знаете о сигнале кроме того, что он прямоугольный?
ЗЫ. А вообще, самый разумный был совет - используйте запоминающий осциллограф или логический анализатор и внимательно рассмотрите сам сигнал. Пока половина советов тут сводилась к попытке сделать простейший лог. анализатор подручными средствами...
Marian
Цитата(Dog Pawlowa @ Aug 2 2011, 23:37) *
Есть простой способ - используете прерывание capture и складываете отсчеты таймера в буфер.


Вроде capture работает по фронту импульса.
Измерить длительность лог."0" так не получится.
ArtemKAD
Цитата
Вроде capture работает по фронту импульса.

Работает по обоим фронтам (какой укажешь и можно менять по ходу дела) и по результату компаратора. Измерить длительность нуля - очень просто. Ловишь падающий, меняешь в прерывании каптура на нарастающий и запоминаешь текущее. В следующем прерывании вычитаешь текущее от запомненного = измерили.
Плюс можно компарами ставить ограничения на допустимые пределы длительности нуля/импульса.
ILYAUL
Цитата(ArtemKAD @ Aug 4 2011, 21:06) *
....и запоминаешь текущее. В следующем прерывании вычитаешь текущее от запомненного = измерили.

А надо ли ? По условию задания ему нужно только
Цитата
Кто-нибудь может подсказать как прочитать передачу некоего интерфейса

К тому же
Цитата
Известна его его скорость и структура

Насчёт длительности импульсов ничего не сказано. И даже если , что-то считать , то только не в прерывании. К тому же по каждому прерыванию , можно просто перезапускать счётчик, предворительно считав предыдущие данные, которые можно потом сохранить выйдя из прерывания. И считать полученные данные до следующего прерывания.
Но неизвестны ни скорость передачи ни структура сигнала- не озвучены. А так можно было прикинуть программу обработки. Но и проц не известен.
zombi
Цитата(micronano @ Aug 2 2011, 12:50) *
как прочитать передачу некоего интерфейса?

Цитата(micronano @ Aug 2 2011, 13:43) *
#include <avr/io.h>
.
.
.
Глупы ошибки это да... =)

Такие вещи и на СИ! прям садомазо какоето biggrin.gif
сорри за офтоп
ASZ
В документации на любой микроконтроллер AVR (раз уж эта ветка в МК AVR), содержащий UART, очень детально расписан принцип детектирования последовательного сигнала.
ИМХО, к этому добавить нечего.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.