Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
29.03.2012, 21:35
|
|
Прохожий
Регистрация: 11.10.2007
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Сигнализатор поклевки
Собираю следующий девайс: Общий приемник с семисегментным индикатором и до 15 передатчиков. Передатчики устанавливаются на рыболовные снасти, и при поклевке сигнализируют бузером, и передают по радиоканалу номер сработавшей снасти.
Иcпользую следующие схемы для сборки:
Сигнализатор, он же передатчик
Пейджер, он же приемник
сигнализатор собрал на tiny13, прошился нормально.
пейджер собрал на tiny2313, тоже прошился нормально.
Я не смог найти пав резонаторы для приемника и передатчика, поэтому приобрел готовые модули HM-R433 и HM-T433. И мне категорически не удается связать сигнализатор с пейджером по радиоканалу.
Что пробовал:
1 в первую очередь проверил модули - на передатчик через UART передал слово, приемник через MAX232 прицепил к кому, и в терминале слово получил.
2.игрался с опциями исходника. Пробовал менять канал приемника с прямого на инверсный, добавлять пилот сигнал перед передачей (об этом ниже чуть подробнее). Глухо - толку нет.
Какая основная мысль - у этого радиомодуля есть ряд специфических особенностей, из за которых мне кажется нифига и не работает.
1. У передатчика нет ENABLED. После передачи он дает несущую еще 70 мс, после чего тупо засыпает.
2. Когда засыпает передатчик, приемник начинает ловить белый шум. Абсолютный мусор.
3. Чтобы возобновить передачу нужно подать пилот сигнал. Я с юарта тупо тыкал 1 байт, после чего слал передачу. После приема первого байта сигнал приемника и передатчика синхронизировался, и передача шла нормально. Но я пробовал в опциях устаравливать передачу пилота (1010). Не помогло
Основной затык, что у меня не хватает скилов разобрать код автора. Он использует самодельный протокол передачи, в котором я сломал ногу. И опыта программирования микроконтроллеров у меня нет - это первая попытка.
В общем буду благодарен за любую помощь в данной задаче, ибо сам уже неделю бьюсь, и бесстолку
Ниже размещаю исходный код
Передатчик
PHP код:
|
#include ‹stdio.h›
#include ‹inavr.h›
#include ‹iotiny13.h›
#include "setting.h"
// IAR C/C++ Compiler for AVR
// 5.20.1 (5.20.1.50092)
/*
Cигнализатор поклевки c пейджером
Версия №2.01
Добавлена возможность передавать дополнительные начальные сигналы синхронизации для приемников, которым это понадобится.
Контроллер теперь работаеи на 9 МГЦ. (Прерывания от повторных поклевок и передачи сигнала на пейджер искажали звук)
Добавлена возможность выбора схемы сигнализации.
Поменяли режим прерываний от датчика (INT0 на PCINT1) для возможности правильно ложиться спать.
Версия №2.02
Снижена скорость передачи по радиоканалу для увеличения дальности уверенного приема.
Добавлена настройка скорости передачи по радиоканалу.
Добавлен режим отладки радиоканала. Постоянная передача радиосигнала. На очень заниженой мощности или на полной.
Добавлен ключик no_radio
grezincmp@mail.ru
*/
//Нужные макросы
#ifdef max_xtall
#undef XTALL
#define XTALL 15.0
#endif //max_xtall
#define delay_us(us) __delay_cycles (XTALL * us);
#define delay_ms(ms) delay_us (1000 * ms)
#define BIT(x) (1 ‹‹ (x))
#define SETBIT(ADDRESS,BIT) ((ADDRESS) |= (1‹‹(BIT)))
#define CLEARBIT(ADDRESS,BIT) ((ADDRESS) &= ~(1‹‹(BIT)))
#define BitIsClear(reg, bit) ((reg & (1‹‹(bit))) == 0)
#define BitIsSet(reg, bit) ((reg & (1‹‹(bit))) != 0)
#ifndef no_radio
#define startADC ADCSRA = 0xCF
#endif //no_radio
#define stopADC ADCSRA = 0x00
#ifndef newdesign
#define light SETBIT(buzerport,buzerpin);delay_us(AFTER_LIGHT_IM PULS);CLEARBIT(buzerport,buzerpin);delay_us(AFTER_ LIGHT_PAUSE)
#else
#define light SETBIT(ledddr,ledpin)
#endif
#ifndef no_radio
#define SetTX SETBIT(txport, txpin)
#define ResetTX CLEARBIT(txport, txpin)
#define SetTXEnable SETBIT(enableport, enablepin)
#define ResetTXEnable CLEARBIT(enableport, enablepin)
#define TX_Busy BitIsSet(enableport,enablepin)
#endif //no_radio
#define SetBuzer SETBIT(buzerport,buzerpin)
#define ResetBuzer CLEARBIT(buzerport,buzerpin)
#define needlight BitIsSet(ACSR, ACBG)//Чтобы не тратить память, будем использовать под одну битовую переменную
#define setneedlight SETBIT(ACSR, ACBG) //бит в неиспользуемом регистре аналогового компататора
#ifndef newdesign
#define resetneedlight CLEARBIT(ACSR, ACBG)
#else
#define resetneedlight CLEARBIT(ACSR, ACBG); CLEARBIT(ledddr,ledpin)
#endif
#ifdef speed_divider
#if speed_divider==0
#undef speed_divider
#endif //speed_divider=0
#endif //speed_divider
//Две служебные функции, написанные на ассемблере в файлике ass.asm
#ifndef no_radio
extern void SL(void);
extern void SR(void);
#endif //no_radio
//Определение переменных. Все в регистрах и одна в еепроме
__regvar __no_init unsigned int time @ 4; //Переменные хранятся в регистрах
#ifndef no_radio
__regvar __no_init unsigned char counter @ 6;
#endif //no_radio
__regvar __no_init unsigned char intcounter @ 7;
#ifndef no_radio
__regvar __no_init unsigned long paket0 @ 8;
__regvar __no_init unsigned long paket1 @ 12;
#endif //no_radio
__eeprom __no_init unsigned char savedsense; //Переменная в ЕЕПРОМ_е
#ifndef no_radio
#ifdef speed_divider
volatile unsigned char divcounter=0;
#endif //speed_divider
#endif //no_radio
#ifndef no_radio
void transmit_RF(unsigned char masc)
{
unsigned char i;
//while TX_Busy;{} //Это уже есть в бипе
#ifndef Rf_test_power
SetTXEnable; //Выставим разрешение передачи радиомодулю в нормальном режиме.
#elif Rf_test_power==1
SetTXEnable; //Выставим разрешение передачи радиомодулю в режиме отладки радиоканала(Rf_test_power=1).
//И не выставим его если Rf_test_power=0
#endif //Rf_test_power
SETBIT(paket0,0); //И сформируем в переменных paket0 и paket1 битовый образ посылки
for (i=0; i‹8; i++)
{
if BitIsSet(masc, i)
{
SL();SL();SL(); SETBIT(paket0,0); SL();SETBIT(paket0,0); SL();SETBIT(paket0,0);
}
else
{
SL();SL();SL();SL();SETBIT(paket0,0); SL();SETBIT(paket0,0);
}
} //Серийный номер закодирован
for (i=0; i‹20; i++)SL(); //Теперь сдвинем
paket0=paket0+0x0785E1; // и на освободившееся место добавим стандартную преамбулу
counter=0; //сбросим счетчик переданных тактов
#ifdef pilot //Если нужно передавать пилот-сигнал
for (unsigned char c=0; c‹pilot; c++)
{
SetTX; delay_us(TAKT); //длительность единицы синхросигнала типа 0
ResetTX; delay_us(TAKT*4); //длительность нуля синхросигнала типа 0
SetTX; delay_us(TAKT*4); //длительность единицы синхросигнала типа 1
ResetTX; delay_us(TAKT); //длительность нуля синхросигнала типа 1
}
#endif //pilot
startADC; //и запустим источник регулярных прерываний, в которых модулируем выход
}
#endif //no_radio
void cpuinit(void)
{
ACSR=0x80; //Запретим аналоговый компаратор
stopADC; //disable adc
TCCR0A=0x00; //Стоп таймеру
TCCR0B=0x05; //Прескалер таймера=1024
TIMSK0=(1‹‹TOIE0); //Разрешим прерывание от переполнения0x02;
GIMSK=(1‹‹PCIE); //0x20;//Разрешим прерывание от pcint
PCMSK=(1‹‹PCINT1); //0x02;//Размаскируем прерывание от pcint1
MCUCR=(1‹‹PUD)|(1‹‹SM1)|(0‹‹SM0)|(1‹‹SE);// Настроим сон в режим POWER DOWN и запретим PULL-UP
GIFR=(1‹‹PCIF)|(1‹‹INTF0); //На всякий случай сбросим флаги возникших прерываний
PORTB=0; // Установим нули на всех выходах
DDRB=0x3F; // Все пины на выход
#ifdef newdesign
CLEARBIT(ledddr,ledpin); //Если новый дизайн, то пин в 3 состояние иначе неконфигурируем.
#endif //newdesign
CLEARBIT(inputddr,inputpin); //Пин датчика на вход
}
#pragma vector=PCINT0_vect
__interrupt void pcint0(void)
{
if (time›DROPTIME)intcounter=0;//Хотя колесо и провернулось, но time более 3.(1 сработка в секунду) Это ложное срабатывание. Отбросим его.
else intcounter++; //Колесо провернулось. Пришел импульс с датчика. Подсчитываем intcounter если time не более 3(между сработками менее секунды)
TCNT0=0; //Засекаем время
time=0; //При time=3 будет около секуунды
}
void beep(void)
{
unsigned int cykl;
cykl=BEEP_TIME;
#ifndef no_radio
while TX_Busy;{} //Ждем. Дабы не бипать во время передачи. Чтобы не портился звук и не прервать незаконченную передачу.
#endif //no_radio
while (cykl--)
{
#ifdef newdesign
SETBIT(ledddr,ledpin); //Если newdesign, засветим светодиод
#endif //newdesign
SetBuzer; //Это понятно. выход в единицу
delay_us(BEEP_IMPULS); //немножко обождем
ResetBuzer; //и сбросим выход в ноль
delay_us(BEEP_PAUSE); //И опять немножко обождем
}
#ifdef newdesign
CLEARBIT(ledddr,ledpin); //Потушим светодиод
#endif //newdesign
#ifndef no_radio
transmit_RF(SERIAL_NOMER*16+SERIAL_NOMER); //Сделаем нибблы одинаковыми и передадим инфу функции подготовки данных на передачу
#endif //no_radio
}
#pragma vector=TIM0_OVF_vect
__interrupt void t0(void)
{
time++;//Таймер переполнен. Сработок нет! Просто считаем время.
}
void signal(void)
{
//Пробипаем и скажем, что нужно подсветить
intcounter=0;
beep();delay_ms(AFTER_LIGHT_INTERVAL);beep();delay _ms(AFTER_LIGHT_INTERVAL);beep();
setneedlight;//Раз уж отреагировали на поклевку, то подсветим, чтобы в темноте и тишине видно было, какая собака нас разбудить осмелилась.
}
void showsenselevel(unsigned char level)
{//Пробипаем уровень чувствительности
while (level--)
{
beep(); delay_ms(500);
}
}
#ifndef no_radio
#pragma vector=ADC_vect
__interrupt void adchandler(void)
{
#ifdef speed_divider //Если включен понижатель, то не на каждое прерывание реагируем.
divcounter++;
if (divcounter==speed_divider) //Нужно ли пропускать это прерывание?
#endif //speed_divider
{ //Тут начинается обработка не холостых прерываний
#ifdef speed_divider
divcounter=255; //Сбросим счетчик понижателя. При входе он станет нулем.
#endif //speed_divider
if (counter==65) SetTX; //передача завершена. сформируем стоп-бит
else{if BitIsClear(paket0,0) ResetTX; else SetTX;} //Собственно, сама передача. В зависимости от состояния битов в переменной, ставим выход
if (counter‹66) {counter++;startADC;SR();} //Считаем обработанные быты, перезапускаем АЦП и сдвигаем переменную
//вручную перезапускаем АЦП потому, что фриран почему-то не фурычит.
else {stopADC;ResetTXEnable;} //Все. Передача окончена. снимаем разрешение передачи и принудительно останавливаем АЦП
}
#ifdef speed_divider
else{if (counter‹67) startADC; else ResetTX;} //Если прерывание холостое (speed_divider) все равно нужно перезапустить АЦП
#endif //speed_divider И в конце передачи сбросить линию ТХ
}
#endif //no radio
void main( void )
{
#ifdef no_radio
#undef Rf_test_power
#endif //no_radio
#ifndef Rf_test_power
unsigned char senscount;
#endif //Rf_test_power
__disable_interrupt(); //Чтобы ничто нас не отрывало от начальной настройки системы.
#ifdef max_xtall
OSCCAL=0x7F; //Это если вдруг понадобится "погнать" контроллер на максимальной частоте
#endif //max_xtall
delay_ms(200); //Чуточку обождем. Чтобы тактовый генератор надежно вышел на режим
cpuinit(); //Все нужно сначала настроить
savedsense=(savedsense+1) & 3; //прочитаем, скорректируем и сохраним уровень чувствительности.
//В зависимости от уровня чувствительности, выберем заданное к-во импульсов для реагирования на поклевку
#ifndef Rf_test_power
switch (savedsense)
{
case 0: senscount=LOW_LEVEL; break;//Самый низкий уровень
case 1: senscount=MIDDLE_LEVEL; break;
case 2: senscount=HIGH_LEVEL; break;
case 3: senscount=BIG_LEVEL; break;//Самый высокий уровень
default:break;
}
#endif //Rf_test_power
__enable_interrupt(); //А теперь уже и отрываться можно на всякие посторонние запросы
showsenselevel(savedsense+1);//При включении пробипаем уровень чувствительности количеством бипов
intcounter=0; //В самом начале ничего не было...
resetneedlight; //Опять В самом начале ничего не было...
#ifndef Rf_test_power
__sleep(); //Если к этому времени никто не клюнет, то ложимся спать до поклевки.
#endif //Rf_test_power
while(1) //Разбудили ГАДЫ !!!!!!!!!
{
#ifndef Rf_test_power
if (intcounter›senscount) signal(); //Поклевка! Нужно сигнализировать!
if (time›AFTER_LIGHT_TIME) {resetneedlight;} //Пора ли выключать послесвечение сигнализатора?
else {
if needlight light; //Еще не пора. Светим чтобы видно было, какой сигнализатор сработал.
}
if (!needlight) __sleep(); //Активности нету. Светить тоже не надо. Можно спать.
#else //Rf_test_power
#ifndef no_radio
transmit_RF(SERIAL_NOMER*16+SERIAL_NOMER);
delay_ms(10);
#endif //no_radio
#endif //Rf_test_power
}
}
|
Приемник
PHP код:
|
#include ‹iotiny2313.h›
#include ‹inavr.h›
#include "setting.h"
/*
IAR C/C++ Compiler for AVR
5.20.1 (5.20.1.50092)
Пейджер для сигнализаторов поклевки
grezincmp@mail.ru
Здесь ничего не менять. Для этого есть setting.h
Версия 01
Поменял инициализацию портов. Был кратковременный перегруз выхода приемника
*/
//Здесь ничего не менять. Для этого есть setting.h
/* Служебные определения */
#define BIT(x) (1 ‹‹ (x))
#define SETBIT(ADDRESS,BIT) ((ADDRESS) |= (1‹‹(BIT)))
#define CLEARBIT(ADDRESS,BIT) ((ADDRESS) &= ~(1‹‹(BIT)))
#define BitIsSet(reg, bit) ((reg & (1‹‹(bit))) != 0)
#define BitIsClear(reg, bit) ((reg & (1‹‹(bit))) == 0)
/* Задержки в микро и милисекундах */
#define delay_us(us) __delay_cycles ((unsigned char)(XTALL) * us);
#define delay_ms(ms) delay_us (1000.0 * ms)
#define timelimitmax timelimit+timelimit/100.0*dopuskpercent
#define timelimitmin timelimit-timelimit/100.0*dopuskpercent
#ifdef COMMON_ANODE // Если индикатор с общим анодом!
#define ON_a CLEARBIT(seg_a_port,seg_a_pin)
#define ON_b CLEARBIT(seg_b_port,seg_b_pin)
#define ON_c CLEARBIT(seg_c_port,seg_c_pin)
#define ON_d CLEARBIT(seg_d_port,seg_d_pin)
#define ON_e CLEARBIT(seg_e_port,seg_e_pin)
#define ON_f CLEARBIT(seg_f_port,seg_f_pin)
#define ON_g CLEARBIT(seg_g_port,seg_g_pin)
#define OFF_a SETBIT(seg_a_port,seg_a_pin)
#define OFF_b SETBIT(seg_b_port,seg_b_pin)
#define OFF_c SETBIT(seg_c_port,seg_c_pin)
#define OFF_d SETBIT(seg_d_port,seg_d_pin)
#define OFF_e SETBIT(seg_e_port,seg_e_pin)
#define OFF_f SETBIT(seg_f_port,seg_f_pin)
#define OFF_g SETBIT(seg_g_port,seg_g_pin)
#else // Если индикатор с общим катодом!
#define ON_a SETBIT(seg_a_port,seg_a_pin)
#define ON_b SETBIT(seg_b_port,seg_b_pin)
#define ON_c SETBIT(seg_c_port,seg_c_pin)
#define ON_d SETBIT(seg_d_port,seg_d_pin)
#define ON_e SETBIT(seg_e_port,seg_e_pin)
#define ON_f SETBIT(seg_f_port,seg_f_pin)
#define ON_g SETBIT(seg_g_port,seg_g_pin)
#define OFF_a CLEARBIT(seg_a_port,seg_a_pin)
#define OFF_b CLEARBIT(seg_b_port,seg_b_pin)
#define OFF_c CLEARBIT(seg_c_port,seg_c_pin)
#define OFF_d CLEARBIT(seg_d_port,seg_d_pin)
#define OFF_e CLEARBIT(seg_e_port,seg_e_pin)
#define OFF_f CLEARBIT(seg_f_port,seg_f_pin)
#define OFF_g CLEARBIT(seg_g_port,seg_g_pin)
#endif
#define starttimer0 TCCR0B=0x04 //start timer
#define SetBuzer SETBIT(buzer_port,buzer_pin)
#define ResetBuzer CLEARBIT(buzer_port,buzer_pin)
#define starttimer1 TCCR1B = 0x05// c прескалером 1024
#define stoptimer1 TCCR1B = 0x00
#define resettimer1 TCNT1=0
__regvar __no_init unsigned char recive @ 5;
__regvar __no_init unsigned char blinkov @ 6;
__regvar __no_init unsigned char needchangeled @ 7;
__regvar __no_init unsigned char RXData @ 8;
__regvar __no_init unsigned char tip @ 9;
__regvar __no_init unsigned char tp @ 10;
__regvar __no_init unsigned char ti @ 11;
__regvar __no_init unsigned char start @ 12;
__regvar __no_init unsigned char stop @ 13;
__regvar __no_init unsigned char numbit @ 14;
__regvar __no_init unsigned char rx_data @ 15;
__flash unsigned char cod[]={64,121,36,48,25,18,2,120,0,16,8,3,70,33,6,14,127 };
unsigned char blinkbuffer[4]={16,16,16,16};
void initbuzer(void)
{
CLEARBIT(buzer_port,buzer_pin);//В порт бузера загоним ноль
SETBIT(buzer_ddr,buzer_pin); //И сделаем его пин выходом
}
void beep(void) //Все то же, что и в сигнализаторе
{
unsigned char cykl=beeplength;;
while (cykl--)
{
SetBuzer;
delay_us(beepimpulstime);
ResetBuzer;
delay_us(beepimpulpausestime);
}
}
void initled(void) //Установим пин в состояние, при котором индикатор не грит и сделаем пины тиньки выходами
{
OFF_a; SETBIT(seg_a_ddr,seg_a_pin);
OFF_b; SETBIT(seg_b_ddr,seg_b_pin);
OFF_c; SETBIT(seg_c_ddr,seg_c_pin);
OFF_d; SETBIT(seg_d_ddr,seg_d_pin);
OFF_e; SETBIT(seg_e_ddr,seg_e_pin);
OFF_f; SETBIT(seg_f_ddr,seg_f_pin);
OFF_g; SETBIT(seg_g_ddr,seg_g_pin);
}
void inittimer1(void)
{
stoptimer1; // TCCR1B = 0x00; //stop timer
OCR1A = 3905; //set compare value 500ms c прескалером 1024 от внутреннего генгератора 8.2 МГЦ
resettimer1; //Начнем с нуля
TCCR1A = 0x00; //Так надо.
SETBIT(TIMSK,OCIE1A); //Разрешим прерывания TIMER1_COMPA
blinkov=0; //При инициализации блинкать не нужно
}
void printznak(unsigned char znak)// 0..15 16-потушить все!
{// Типа посегментной динамики. Это дало возможность свободного выбора пинов для индикатора
if BitIsSet(cod[znak],0) OFF_a; else ON_a;
if BitIsSet(cod[znak],1) OFF_b; else ON_b;
if BitIsSet(cod[znak],2) OFF_c; else ON_c;
if BitIsSet(cod[znak],3) OFF_d; else ON_d;
if BitIsSet(cod[znak],4) OFF_e; else ON_e;
if BitIsSet(cod[znak],5) OFF_f; else ON_f;
if BitIsSet(cod[znak],6) OFF_g; else ON_g;
}
#pragma vector=PCIN1_vect
__interrupt void Pin_Change_interrupt( void )
{
/*
Формат посылки байта - 4 синхро (0101) + байт + 1 синхро (0) при прямом радиоканале единицей передаем единицу
4 синхро (1010) + байт + 1 синхро (1) при инверсном радиоканале нулем передаем единицу
в результате - последний синхро перед байтом ==1 и первый синхро после байта ==0
Проверяем полярность и наличие старта и стопа, длину байта, отсутствие синхросигнала или ошибки внутри приема байта
При соответствующей настройке (timelimit) фильтруем скорость передачи.
При несоответствии критериям - принятую информацию отвергаем
*/
# ifndef invinput
if BitIsSet(PINB, 0)
{
tp=TCNT0; //Это пауза. Замеряем эту паузу и займемся обсчетом ti/tp (импульс замерен раньше!)
TCNT0=0; //И сбросим счетчик
#ifdef timelimit
unsigned int tl;
tl=ti+tp; //Определяем, сколько времени пошло на прием этого бита
if ((tl›timelimitmin) && (tl‹timelimitmax)) //Если время не за пределами установленного, продолжаем анализ
//Иначе, прекращаем анализ и сбрасываем numbit
#endif //timelimit
{
if (ti‹tp) //Если время импульса меньше времени паузы,
{
if ((tp-ti-ti)‹0) tip=0; else { //Если время паузы меньше времени двух импульсов то это синхро, иначе информационный ноль
tip=3; //это синхросигнал=0
if (numbit==0) start=0; //он может быть стартом
if (numbit==8) stop=0; //он может быть стопом
}
}
else
{//Если время импульса больше времени паузы,
if ((ti-tp-tp)‹0) tip=1; else {//Если время импульса меньше времени двух пауз то это синхро, иначе информационная единица
tip=3; //это синхросигнал=1
if (numbit==0) start=1; //он может быть стартом
if (numbit==8) stop=1; //он может быть стопом
}
}
if (tip==3)
{ // Если приняли синхросигнал
if ((numbit==8) & (start==1) & (stop==0)) // Проверим на конец приема байта
{recive=1;RXData=rx_data; } // после принятия 8 бит, последний синхро перед байтом (старт) и
// первый после байта (стоп) правильныой полярности
numbit=0;//приняли пилот, старт, стоп бит или ошибку!
}
else// приняли информационный бит
{
rx_data=rx_data*2; numbit++;// сдвиг увеличение счетчика принятых бит
if (tip==0) CLEARBIT(rx_data,0); else SETBIT(rx_data,0);//вписываем информационный бит
}
}//обсчитали ti/tp
#ifdef timelimit
else numbit=0; //Брак по ограничению скорости приема
#endif //timelimit
// При необходимости закончили проверку timelimit
}
else { ti=TCNT0; TCNT0=0; }//Это импульс. Замеряем импульс и сбросим счетчик
}
#else // Инверсный радиоканал
if BitIsClear(PINB, 0)
{
ti=TCNT0; //Это импульс. Замеряем этот импульс и займемся обсчетом ti/tp (пауза замерена раньше!)
TCNT0=0; //И сбросим счетчик
#ifdef timelimit
unsigned int tl;
tl=ti+tp; //Определяем, сколько времени пошло на прием этого бита
if ((tl›timelimitmin) & (tl‹timelimitmax)) //Если время не за пределами установленного, продолжаем анализ
//Иначе, прекращаем анализ и сбрасываем numbit
#endif //timelimit
{
if (ti‹tp) //Если время импульса меньше времени паузы,
{
if ((tp-ti-ti)‹0) tip=1; else { //Если время паузы меньше времени двух импульсов то это синхро, иначе информационная единица
tip=3; //это синхросигнал=1
if (numbit==0) start=1; //он божет быть стартом
if (numbit==8) stop=1; //он божет быть стопом
}
}
else
{//Если время импульса больше времени паузы,
if ((ti-tp-tp)‹0) tip=0; else {//Если время импульса меньше времени двух пауз то это синхро, иначе информационный ноль
tip=3; //это синхросигнал=0
if (numbit==0) start=0; //он божет быть стартом
if (numbit==8) stop=0; //он божет быть стопом
}
}
if (tip==3)
{ // Если приняли синхросигнал
if ((numbit==8) & (start==1) & (stop==0)) // Проверим на конец приема байта
{recive=1;RXData=rx_data; } // после принятия 8 бит, последний синхро перед байтом (старт) и
// первый после байта (стоп) правильныой полярности
numbit=0;//приняли пилот, старт, стоп бит или ошибку!
}
else// приняли информационный бит
{
rx_data=rx_data*2; numbit++;// сдвиг увеличение счетчика принятых бит
if (tip==0) CLEARBIT(rx_data,0); else SETBIT(rx_data,0);//вписываем информационный бит
}
}//обсчитали ti/tp
#ifdef timelimit
else numbit=0; //Брак по ограничению скорости приема
#endif //timelimit
// При необходимости закончили проверку timelimit
}
else { tp=TCNT0; TCNT0=0; }//Это пауза. Замеряем паузу и сбросим счетчик
}
#endif
void initreciver(void)
{
CLEARBIT(PCINT0_PORT,PCINT0_PIN); //лишняя перестраховка!!!
CLEARBIT(PCINT0_DDR,PCINT0_PIN); //лишняя перестраховка!!!
GIMSK=(1‹‹PCIE); //Разрешим прерывания PCINT
PCMSK=(1‹‹PCINT0); //Размаскируем только прерывания от PCINT0
recive=0; //Сбросим флаг принятости байта
starttimer0;
}
#pragma vector=TIMER1_COMPA_vect
__interrupt void TIMER1_compareA_interrupt( void )
{ //Прошло 500 мс
resettimer1; //Сброс таймера
blinkov--;
if (blinkov==0) stoptimer1; //Все отблинкали.
else needchangeled=1; //Установим признак необходимости смены состояния индикатора (следующая цифра или погасить)
}
void showsignalizator(void)
{static unsigned char index;
printznak(blinkbuffer[index]); //Засветим номер сработавшего сигнализатора
index=(index+1) & 3; //Увеличим индекс но не более 3
if (blinkbuffer[index]==16) index=0; //Кончились записанные номера.
}
void prepareblinkbuffer(unsigned char datarx)
{ unsigned char d;
for(unsigned char i=0; i‹4; i++)
{
d=blinkbuffer[i];
if (d==datarx) break; //Пришел сигнал с номером уже запомненного сигнализатора
if (d==16) {blinkbuffer[i]=datarx;i=4;} //Это первое пустое место в него запишем номер сработавшего сигнализатора
}
resettimer1; //И подготовим систему отображения номеров
starttimer1;
blinkov=BlinkCount; //Настроим счетчик блинков, вписав в него заранее оговоренное число
needchangeled=1; //Это чтобы сразу же (без паузы) после приема моргнуть принятым номером
showsignalizator(); //Принудительно моргнем
beep(); //И продублируем бип сигнализатора
}
void resetblinkbuffer(void)
{
printznak(16); // Потушить индикатор
for(unsigned char i=0; i‹4; i++) blinkbuffer[i]=16; //И заполним буфер "пустыми" номерами
}
void initport_s(void)
{
PORTA=0; //Это паранойя. Все равно используемые пины будут проинициализированы.
PORTB=0; //но вот неиспользуемые останутся нетронутыми.
PORTD=0; //поэтому здесь сделаем все одним махом.
DDRA=0x07;
DDRB=0xFE;
DDRD=0x7F;
}
void main( void )
{
__disable_interrupt();
initport_s(); //Даже неиспользуемые переведем на выход и установим в 0
initbuzer(); // Подготовим пин бузера
initled(); // Подготовим пины, к которым подключен индикатор
ON_a; delay_ms(100);OFF_a; // Маленькая анимация чтобы увидеть все сегменты индикатора
ON_b; delay_ms(100);OFF_b;
ON_c; delay_ms(100);OFF_c;
ON_d; delay_ms(100);OFF_d;
ON_e; delay_ms(100);OFF_e;
ON_f; delay_ms(100);OFF_f;
ON_g; delay_ms(100);OFF_g;
printznak(16); // Потушить индикатор
beep(); // Гордо бибикнем, мол - готовы к труду и обороне
initreciver(); // По смене состояния PCINT0 будем замерять длительности нулевыз и единичных состояний PCINT0 таймером TIMER0
inittimer1(); // Чтобы он отмерял интервалы по 500мс и генерировал прерывания TIMER1_COMPA
__enable_interrupt(); // Вот теперь уж точно все готово к работе.
while(1)
{
delay_ms(10);
if (recive==1) // Если байт принят
{
recive=0; // То сбросим признак принятости
if ((RXData››4)==(RXData & 0x0F)) // Проверим на допустимые номера 0..15 и одинаковость нибблов
prepareblinkbuffer(RXData & 0x0F); // Если номера наши, запишем их в буфер для отображения на индикаторе
}
if (blinkov!=0) // Если количество блинков еще не закончилось
{
if (needchangeled==1) // И таймер сообщил о прошествии 500мс
{
needchangeled=0; // то сбросим этот признак
if ( BitIsSet(blinkov,0) ) showsignalizator(); //И при четном кол-ве блинков засветим номер, при нечетном потушим (моргаем)
else printznak(16); // Потушить индикатор
}
}
else {resetblinkbuffer();} // Блинки закончились. Очистим буфер под новые номера.
}
}
|
|
|
|
|
29.03.2012, 21:37
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Сигнализатор поклевки
На первый взгляд ошибка в 317 строке.
|
|
|
|
29.03.2012, 21:42
|
|
Прохожий
Регистрация: 11.10.2007
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Сигнализатор поклевки
Сообщение от Easyrider83
|
На первый взгляд ошибка в 317 строке.
|
Понимаю юмор ![Улыбка](images/smilies/icon_smile.gif) К сожалению не нашел тега "спойлер", чтобы завернуть полотно
На самом деле весь код не нужен, интересует только два метода
transmit_RF передача
Pin_Change_interrupt прием
|
|
|
|
29.03.2012, 23:01
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Сигнализатор поклевки
Дождемся Величайшего. Он красноречивее изъяснится.
|
|
|
|
31.03.2012, 21:39
|
|
Прохожий
Регистрация: 11.10.2007
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Сигнализатор поклевки
Разобрался. Накосячил с фьюзами.
В результате помирил схему с этими модулями. Уверенный прием - 150 метров, прием вообще -300 метров.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 21:49.
|
|