|
|
  |
Прием данных на Атмеге, Как правильно это организовать |
|
|
|
May 4 2009, 04:57
|
Частый гость
 
Группа: Участник
Сообщений: 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
Причина редактирования: Уменьшение видимого размера цитаты исходника.
|
|
|
|
|
May 4 2009, 09:05
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Vny4ek @ May 4 2009, 07:57)  Вот привожу пример кода, для приема. Насколько мне известно тут длительность задана а не измеряется. Осталось вот это: Цитата(rezident) Вы предоставляете свой исходник с комментариями "непоняток". А вообще-то Вам описали алгоритм, и Вы ответили: "я потихоньку начинаю понимать, давайте я начну делать а если Вам не сложно вы поправите и скажете где ошибся" Что же Вы действительно САМИ начали делать, кроме выкладывания чужих исходников?
--------------------
Уходя, оставьте свет...
|
|
|
|
|
May 4 2009, 10:13
|
Гуру
     
Группа: Свой
Сообщений: 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); } Добавьте инициализацию схем захвата.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jun 7 2009, 14:09
|
Частый гость
 
Группа: Участник
Сообщений: 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], хотя нужно использовать приложения
|
|
|
|
|
Jun 8 2009, 09:03
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
1. В main нет зацикливания в конце 2. printf в обработчик прерывания не ставят 3. Передачу с задержками внутри тоже не рекомендуется ставить в обработчик прерывания 4. Непонятно предназначение конструкции for(;u>0;u--) counts = b[9]; в начале функции передачи 5. SM в прерывании не смотрел - на первый взгляд нечто монстрообразное (хоть бы коментарии написал  )
|
|
|
|
|
Jun 8 2009, 09:14
|
Частый гость
 
Группа: Участник
Сообщений: 145
Регистрация: 11-01-08
Пользователь №: 34 001

|
да я взял уже работающий пример, прием работает корректно, в УАРТ выводит коды, но вот по сути после того как принят последний бит, должна сразу стартовать передача, это происходит, но передаются нули. Я думаю может нужно, принятое в какойнибудь временный буфер присваивать, а уже от туда отправлять? Или действительно может дело в пункте 3. Я если честно до сих пор не понял доконца некоторых элементов этого кода, содраны с официальных аппноутов вроде.
|
|
|
|
|
Jun 28 2009, 15:34
|
Частый гость
 
Группа: Участник
Сообщений: 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 генератор, не хочет. знаю что правильно организовать прием по перрыванию, но пока освоить не могу, их хорошо.
|
|
|
|
|
Jun 29 2009, 18:17
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Блин. Во что лень делает.... Первый пост ноябрь 2008, на дворе конец июня 2009. 7 месяцев!!!!!! 1) Возьмите себя в руки (максимум день). 2) Почитайте не примеры, а документацию на выбранный вами камень. (максимум 2 дня). 3) Перечитайте ответы спецов по данной теме. (пол дня) 3) Выкиньте чужое и напишите своё. Но чтобы вы понимали что там написано. (Максимум неделя)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|