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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Прием данных на Атмеге, Как правильно это организовать
rezident
сообщение May 3 2009, 11:27
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Таймер не нужно запускать по перепаду. Таймер должен всегда работать с (авто)переполнением. Перепад на входе фиксируется в регистре захвата (capture). Беззнаковая разность двух соседних значений, полученных из регистра захвата, дает длительность между фронтами в тактах таймера. Поделите эту разность на частоту тактирования таймера и получите длительность импульса в привычных единицах измерения времени. Следует только помнить, что максимальный период измеряемого импульса зависит от периода переполнения таймера. Если его (периода переполнения) не хватает для ваших задач, то разрядность таймера можно расширить программно. Для этого заводите программный счетчик (бОльшей разрядности, чем позволяет аппаратно таймер), который нужно инкрементировать на величину разрядности таймера при его переполнении. А по прерыванию от фронта импульса значение из регистра захвата суммируете со значением программного счетчика и для расчета периода используете уже это полученное число.
Go to the top of the page
 
+Quote Post
Vny4ek
сообщение May 3 2009, 11:43
Сообщение #17


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

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



А можно пример привести, для кодвижена, принцип я понял достаточно хорошо но на практике начать разбираться с ним никак не смогу.
Я думаю людям с опытом не сложно в кодвижене простой исходник написать, жалательно откоментировав, то что я не понял. Все ведь начинали и не сразу все освоили. Спасибо заранее.
Go to the top of the page
 
+Quote Post
rezident
сообщение May 3 2009, 11:54
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Предлагаю сделать наоборот. Вы предоставляете свой исходник с комментариями "непоняток". А мы тут его пытаемся поправить и прокомментировать. Потому, что я, например, программируя на Си, с AVR знаком лишь "шапочно", а с CodeVison вообще практически дел не имел. Как вы считаете, не слишком ли "жирно" с вашей стороны требовать, чтобы для этого был освоен "недокомпилятор Си" CodeVison и изучен AVR? wink.gif
Go to the top of the page
 
+Quote Post
Vny4ek
сообщение May 3 2009, 16:42
Сообщение #19


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

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



ок, я полностью с вами согласен.
у меня есть пример приема этого кода, рабочий вот выложу часть может вы поможете:
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=135;
RFBit=RfIn;
\\\\\\\\\\
TCCR0=0x02;
TCNT0=0x00;
вот не могу понять что означает это, это прерывание по таймеру вроде, и почему вы кодвижен не долюбливаете? я понимаю что он скорее для начинающих, может мне не стоит в его сторону даже изначально смотреть, а начинать изучать другой компилятор?
Go to the top of the page
 
+Quote Post
rezident
сообщение May 3 2009, 21:38
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Не нужно обрывков. Приводите ваш пример программы целиком.
Судя по заголовку функции, да, это прерывание от переполнения TIMER0.
Go to the top of the page
 
+Quote Post
Vny4ek
сообщение May 4 2009, 04:57
Сообщение #21


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

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



Вот привожу пример кода, для приема. Насколько мне известно тут длительность задана а не измеряется.
CODE
#include <mega8.h>
#include <stdio.h>
#include <delay.h>
#include <String.h>

#define TRFreset 0
#define TRFSYNC 1
#define TRFUNO 2
#define TRFZERO 3

#define NBIT 65

#define HIGH_TO -10
#define LOW_TO 10
#define SHORT_HEAD 20
#define LONG_HEAD 45

#define RfIn PIND.4

typedef unsigned char byte;

bit RFFull;
bit RFBit;
int RFcount;
byte Bptr,BitCount,RFstate,Buf[9];
/////////////// receive /////////////////////////////////
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=135;
RFBit=RfIn;

if (RFFull)
return;
/////////////////////////////////////////////////////////
switch(RFstate)
{
case TRFUNO:
if ( RFBit == 0)
{
RFstate= TRFZERO;
}
else
{
RFcount--;
if (RFcount < HIGH_TO) RFstate = TRFreset;
}
break;
//////////////////////////////////////////////////////////
case TRFZERO:
if (RFBit)
{
RFstate= TRFUNO;
Buf[Bptr] >>= 1;
if ( RFcount >= 0)
{
Buf[Bptr]+=0x80;
}
RFcount = 0;
if ((++BitCount & 7) == 0) Bptr++;

if (BitCount == NBIT)
{
printf("Reseive signal:");
printf("%02X%02X%02X%02X%02X%02X%02X%02X", Buf[0],Buf[1],Buf[2],Buf[3],Buf[4],Buf[5],Buf[6],Buf[7]);
printf("\n\r");

RFstate = TRFreset;
RFFull = 1;
}
}
else
{
RFcount++;
if ( RFcount >= LOW_TO)
{
RFstate = TRFSYNC;
Bptr = 0;
BitCount = 0;
}
}
break;
///////////////////////////////////////////////////////////
case TRFSYNC:
if ( RFBit)
{
if ((RFcount < SHORT_HEAD)||(RFcount >= LONG_HEAD))
{
RFstate = TRFreset;break;
}
else
{
RFcount =0;RFstate= TRFUNO;
}
}
else
{
RFcount++;
}
break;
/////////////////////////////////////////////////////////////
case TRFreset:
default:
RFstate = TRFSYNC;
RFcount = 0;
Bptr = 0;
BitCount = 0;
break;
} // switch
//////////////////////////////////////////////////////////////
if(RFFull)
{
RFstate = TRFreset;
RFFull=0;
}
/////////////////////////////////////////////////////////////
} // receive
////////////////// main ////////////////////////////////////
void main(void)
{
PORTD=0x10;
DDRD=0x00;

TCCR0=0x02;
TCNT0=0x00;

TIMSK=0x01;

UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;

////////////////////////////////////////////////////////////
printf(" WAIT SIGNAL!\n\r");
printf("\n\r");
////////////////////////////////////////////////////////////
#asm("sei")
}// main
Причина редактирования: Уменьшение видимого размера цитаты исходника.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение May 4 2009, 09:05
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Vny4ek @ May 4 2009, 07:57) *
Вот привожу пример кода, для приема. Насколько мне известно тут длительность задана а не измеряется.

Осталось вот это:
Цитата(rezident)
Вы предоставляете свой исходник с комментариями "непоняток".


А вообще-то Вам описали алгоритм, и Вы ответили:
"я потихоньку начинаю понимать, давайте я начну делать а если Вам не сложно вы поправите и скажете где ошибся"
Что же Вы действительно САМИ начали делать, кроме выкладывания чужих исходников?


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Vny4ek
сообщение May 4 2009, 10:02
Сообщение #23


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

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



не понятно мне следующее: как отследить изменение уровня, и по этому событию запустить таймер, далее его остановить при переходе уровня из 1 в 0
Ну у самого получилось сделать обработку обычного прерывания из 0в1 на ножке int0 по которому например получается зажечь светодиод, но вот с таймером никак даже начать не могу...
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение May 4 2009, 10:13
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Vny4ek @ May 4 2009, 13:02) *
не понятно мне следующее: как отследить изменение уровня, и по этому событию запустить таймер, далее его остановить при переходе уровня из 1 в 0

Я опять процитирую уважаемого rezidentа:
"Таймер не нужно запускать по перепаду. Таймер должен всегда работать с (авто)переполнением. Перепад на входе фиксируется в регистре захвата (capture). Беззнаковая разность двух соседних значений, полученных из регистра захвата, дает длительность между фронтами в тактах таймера..."

Вот пример запуска постоянно работающего таймера в ATmega32:
Код
void BackgroundInit()
{ TCCR0=0;    //stop TC0
  TCCR0 = 1 << WGM01; // ClearTimertoCompare mode, TC0 top on OCR0
  TCNT0 = 0x01;       // initial value TC0
  OCR0 = 249;         // TOP   250 kHz/(249+1)=1 kHz
  TIMSK = TIMSK & ~(1 << TOIE0) | (1 << OCIE0);
  TIFR |= (1 << OCF0) | (1 << TOV0);
}

Добавьте инициализацию схем захвата.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Vny4ek
сообщение Jun 7 2009, 14:09
Сообщение #25


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

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



Здраствуйте, я разбираюсь с одним кодом, задача такая: Получить код от приемника в формате кейлог, и по событию отправить его же (отправка кода происходит при полностью полученном коде), дальше хочу научиться записывать в ячейки полученные коды, для сравнения, но пока передача не проходит, смотрю осцилографом, а передаются только нули (вижу по однотипным импульсам в теле пакета) подскажите в чем дело?
CODE
#include <mega8.h>
//#include <my_lcd.c>
#include <stdio.h>
#include <delay.h>
#include <String.h>

#define TRFreset 0
#define TRFSYNC 1
#define TRFUNO 2
#define TRFZERO 3

#define NBIT 65
#define TE 400
#define HIGH_TO -10
#define LOW_TO 10
#define SHORT_HEAD 20
#define LONG_HEAD 45
#define RFOut PORTC.7
#define RfIn PINB.0
#define Btn PINB.2
typedef unsigned char byte;
typedef signed int sbyte;
typedef signed long word;
#pragma warn- //директива для инициаизации еепрома
eeprom byte EprBuf0 [65];
eeprom byte EprBuf1 [65];
eeprom byte EprBuf2 [65];

eeprom byte eep_ring;
#pragma warn+ //директива для инициаизации еепрома




byte i;
bit RFFull;
bit RFBit;
int RFcount;
byte Bptr,BitCount,RFstate,Buf[9];



void Transmit(byte*b,byte u)
{
byte g=0,j=0,counts;
{
for(;u>0;u--)
counts = b[9];
for (i = 0; i < 12; i ++) //преамбула
{
RFOut = 1;
delay_us(TE);
RFOut = 0;
delay_us(TE);
}
delay_ms(4); // хедер
for (i=0;i<8;i++) // цыкл вывода байтов
{
g = b[i]; // считаем буфер
for (j=0;j<8;j++) // цикл вывода битов в байте
{
RFOut = 1; // вывод бита
delay_us(TE);
if (g&1)
RFOut = 0;
delay_us(TE);
RFOut = 0;
delay_us(TE);
g >>= 1;
}
}

delay_ms(10); // гуард тайм
} //end for u
} //end Transmi


/////////////// receive /////////////////////////////////
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=135;
RFBit=RfIn;

if (RFFull)
return;
/////////////////////////////////////////////////////////
switch(RFstate)
{
case TRFUNO:
if ( RFBit == 0)
{
RFstate= TRFZERO;
}
else
{
RFcount--;
if (RFcount < HIGH_TO) RFstate = TRFreset;
}
break;
//////////////////////////////////////////////////////////
case TRFZERO:
if (RFBit)
{
RFstate= TRFUNO;
Buf[Bptr] >>= 1;
if ( RFcount >= 0)
{
Buf[Bptr]+=0x80;
}
RFcount = 0;
if ((++BitCount & 7) == 0) Bptr++;

if (BitCount == NBIT)
{


printf("Reseive signal:");
printf("%02X%02X%02X%02X%02X%02X%02X%02X",
Buf[0],Buf[1],Buf[2],Buf[3],Buf[4],Buf[5],Buf[6],Buf[7]);
printf("\n\r");
Transmit(Buf,1);
RFstate = TRFreset;
RFFull = 1;
}
}
else
{
RFcount++;
if ( RFcount >= LOW_TO)
{
RFstate = TRFSYNC;
Bptr = 0;
BitCount = 0;
}
}
break;
///////////////////////////////////////////////////////////
case TRFSYNC:
if ( RFBit)
{
if ((RFcount < SHORT_HEAD)||(RFcount >= LONG_HEAD))
{
RFstate = TRFreset;break;
}
else
{
RFcount =0;RFstate= TRFUNO;
}
}
else
{
RFcount++;
}
break;
/////////////////////////////////////////////////////////////
case TRFreset:
default:
RFstate = TRFSYNC;
RFcount = 0;
Bptr = 0;
BitCount = 0;
break;
} // switch
//////////////////////////////////////////////////////////////
if(RFFull)
{
RFstate = TRFreset;
RFFull=0;
}
/////////////////////////////////////////////////////////////
} // receive
////////////////// main ////////////////////////////////////






void main(void)
{

PORTD=0x10;
DDRD=0x00;
PORTB=0x00;
DDRB=0x00;
PORTC=0x7F;
DDRC=0xFF;
TCCR0=0x02;
TCNT0=0x00;

TIMSK=0x01;

UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;

////////////////////////////////////////////////////////////
printf(" WAIT SIGNAL!\n\r");
printf("\n\r");
////////////////////////////////////////////////////////////
#asm("sei")
}// main
Причина редактирования: [codebox], хотя нужно использовать приложения
Go to the top of the page
 
+Quote Post
XVR
сообщение Jun 8 2009, 09:03
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



1. В main нет зацикливания в конце
2. printf в обработчик прерывания не ставят
3. Передачу с задержками внутри тоже не рекомендуется ставить в обработчик прерывания
4. Непонятно предназначение конструкции for(;u>0;u--) counts = b[9]; в начале функции передачи
5. SM в прерывании не смотрел - на первый взгляд нечто монстрообразное (хоть бы коментарии написал rolleyes.gif )
Go to the top of the page
 
+Quote Post
Vny4ek
сообщение Jun 8 2009, 09:14
Сообщение #27


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

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



да я взял уже работающий пример, прием работает корректно, в УАРТ выводит коды, но вот по сути после того как принят последний бит, должна сразу стартовать передача, это происходит, но передаются нули. Я думаю может нужно, принятое в какойнибудь временный буфер присваивать, а уже от туда отправлять? Или действительно может дело в пункте 3. Я если честно до сих пор не понял доконца некоторых элементов этого кода, содраны с официальных аппноутов вроде.
Go to the top of the page
 
+Quote Post
Vny4ek
сообщение Jun 28 2009, 15:34
Сообщение #28


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

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



Здравствуйте, подскажите плиз. Вообщем я пытаюсь принять сигнал с приемника, ну там есть элементы логическое 1=400мкс а 0=800мкс, ну хочу данные принять и пакет еще приходит с преамбулой (12шт логических 1 затем пауза 4милисекунд) мне важно что бы знать в какой фазе сейчас прием. Я покажу элемент кода, откоментируйти плиз что я не так делаю
Код
while (1)
      {  
      if (PINA.0==0) {
      i=0;
      s=0;
      };
  
for (i=0;PINA.0==1;i++) {
        delay_us(1);
       s=i;
    };      
          
     printf("Dlitelnost  ____|---|____=");
             printf("%u",s);
      printf("\n\r");

      };


Подаю в протеусе сигнал где первый импульс, как и последующие имеет длинну около 400-800мкс, но в уарт выводятся значения произвольные от 1до 100, что я делаю не так? Если запускаю генератор достаточно медленный на 50милисекунд например он показывает длинну, а вот реальный пакет отправляю через audio генератор, не хочет.
знаю что правильно организовать прием по перрыванию, но пока освоить не могу, их хорошо.
Go to the top of the page
 
+Quote Post
Vny4ek
сообщение Jun 29 2009, 17:41
Сообщение #29


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

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



Ребят, ну подскажите плиз, я понимаю что не лучшее решение, мне главное что бы работало, а если не будет то скажите почему. Код ведь минимален не сложно оценить.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jun 29 2009, 18:17
Сообщение #30


Гуру
******

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



Блин. Во что лень делает....

Первый пост ноябрь 2008, на дворе конец июня 2009. 7 месяцев!!!!!! smile3046.gif

1) Возьмите себя в руки (максимум день).
2) Почитайте не примеры, а документацию на выбранный вами камень. (максимум 2 дня).
3) Перечитайте ответы спецов по данной теме. (пол дня)
3) Выкиньте чужое и напишите своё. Но чтобы вы понимали что там написано. (Максимум неделя)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 02:27
Рейтинг@Mail.ru


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