Страница 1 из 1

Вопрос по прерыванию.

Добавлено: Чт апр 04, 2013 18:54:24
Pika4u
Вопрос-насколько затормозит контроллер выполнение следующей функции прерывания:

Код: Выделить всё

#pragma vector=USART_RXC_vect 
__interrupt void Uart_RX(void)
{
receive[rec]=UDR;
switch (rec)
{
case 0:
{
switch(receive[rec])
case 248:back_back();
case 252:back_forward();
case 249:back_back_and_turn_left();
case 250:back_back_and_turn_right();
case 253:back_forward_and_turn_left();
case 254:back_forward_and_turn_right();
case 255:brake();
}
case 1:
engine_power=receive[rec];
}
rec++;
if(rec==2)
rec=0;
}
Каждая вызываемая функция что-то типа:

Код: Выделить всё

PORTD_Bit5=0;
PORTD_Bit6=1;
PORTD_Bit7=0;
Контроллер ATMega8,частота 10 МГц,скорость UART 9600. Критична ли будет такая функция прерывания? Или лучше скорость снизить? В принципе,мне гонять в одну сторону 2 байта,в другую 3 раз в секунду. :)

Re: Вопрос по прерыванию.

Добавлено: Чт апр 04, 2013 20:45:35
phanis
может опишите что за устройство планируется? switch

Re: Вопрос по прерыванию.

Добавлено: Чт апр 04, 2013 21:00:20
YS
После case еще break нехудо бы ставить.

Re: Вопрос по прерыванию.

Добавлено: Чт апр 04, 2013 21:31:14
HHIMERA
Там есть "один на всех" адвансед брак-бряк-мутант...

Код: Выделить всё

case 255:brake();

Re: Вопрос по прерыванию.

Добавлено: Чт апр 04, 2013 23:21:22
urry
дело даже не в брейках - и не в том, что не проверяется отсутствие стопового бита и переполнение буфера приема - дело в излишней доверчивости.
С ком порта может придти все, что угодно - передернули разъем, щелкнули питание - а вы всему верите и что-то выполняете...
Верить ком-порту нужно тогда, когда контрольная сумма пакета сойдется.

Re: Вопрос по прерыванию.

Добавлено: Чт апр 04, 2013 23:38:21
Аlex
+ таймаут. Истёк - сброс счётчика байтов и приём заного, игнорируя то, что приняли.

Re: Вопрос по прерыванию.

Добавлено: Чт апр 04, 2013 23:49:30
vitalik_1984
HHIMERA писал(а):Там есть "один на всех" адвансед брак-бряк-мутант...

Код: Выделить всё

case 255:brake();
Если кто не в курсе brake это тормоз, видать моделька должна остановиться при этой команде.

Вообще не сильно затормозит, если всего три команды, но лучше в прерывании принимать в буфер и обрабатывать в основном цикле.
Затем можно помещать в очередь команд либо сразу выполнять.
Выполнять так же можно по таймеру.

Re: Вопрос по прерыванию.

Добавлено: Пт апр 05, 2013 06:39:54
Pika4u
vitalik_1984 писал(а):
HHIMERA писал(а):Там есть "один на всех" адвансед брак-бряк-мутант...

Код: Выделить всё

case 255:brake();
Если кто не в курсе brake это тормоз, видать моделька должна остановиться при этой команде.

Вообще не сильно затормозит, если всего три команды, но лучше в прерывании принимать в буфер и обрабатывать в основном цикле.
Затем можно помещать в очередь команд либо сразу выполнять.
Выполнять так же можно по таймеру.
Да действительно,вы угадали,что это будет моделька)) просто в основном цикле будет еще и опрос датчиков,а 18b20 опрашивается около секунды. Поэтому решил повесить управление двигателями на прерывания. Ах да,про break я забыл( сейчас поставлю)

Re: Вопрос по прерыванию.

Добавлено: Пт апр 05, 2013 20:50:14
phanis
если семи значений скорости достаточно можно оставить один байт
примерно так
Спойлер

Код: Выделить всё

typedef union
{
struct
        {
         unsigned char  reserv1:3;
         unsigned char all:5;

        };      
struct
        {
         unsigned char  reserv2:3; 
         unsigned char forward:1;
         unsigned char    back:1;
         unsigned char    left:1;
         unsigned char   right:1;
         unsigned char    stop:1;
         
        };    
        }struct_upravl;
#define upravl  (*((struct_upravl*)&PORTD)) 


#pragma vector=USART_RXC_vect
__interrupt void Uart_RX(void)
{
unsigned char temp;
temp=UDR;// 
upravl.all = temp;
engine_power=temp&0xE0;

}
или даже так
Спойлер

Код: Выделить всё

#pragma vector=USART_RXC_vect
__interrupt void Uart_RX(void)
{
unsigned char temp;
temp=UDR;
engine_power=temp&0xE0;
temp &= 0x1F;
PORTD &= temp | 0xE0;
PORTD  |= temp ;
}
возвращаясь к вашем коду, если вдруг порядок байтов (мощности и команд )во время приема будет случайно нарушен(помехи контакт ) тогда что?
правильно советуют, задействуйте таймер (прерывание по сравнению например ), а на момент опроса датчика температуры будете запрещать прерывания. при этом заданные интервалы времени можно использовать для определения тайм аута приемника и ожидания конвертации датчика температуры.
насчет необходимости защиты передаваемой информации тоже согласен.простенький избыточный код не повредит.

Re: Вопрос по прерыванию.

Добавлено: Сб апр 06, 2013 19:16:24
Pika4u
А вы ведь правы))) Хорошо,простенькую защиту поставлю. А ведь мне хватит 10 значений скорости. В первом байте направление определяют последние 3 бита. А остальные 5 можно задействовать для скорости. Спасибо огромное!))Даже счетчик байт оказался не нужен :)

Re: Вопрос по прерыванию.

Добавлено: Сб апр 06, 2013 20:36:31
phanis
в место

Код: Выделить всё

switch (rec)
{
case.....
если три бита, то можно написать 8 байт в массив кодов состояний (0,вперед, назад, вперед+влево, вперед+вправо, назад+влево, назад+вправо, стоп)
и отправлять значение по принятому адресу в регистр порта с некоторыми манипуляциями(если остальные ножки порта используется для других целей ).
что то вроде ентого

Код: Выделить всё


__flash unsigned char code[8]={0,x,x,x,x,x,x,x};//состояние пинов порта
#pragma vector=USART_RXC_vect
__interrupt void Uart_RX(void)
{
unsigned char temp;
temp=UDR;
PORTD = code[(temp&0x07)];//если пины порта  не задействованы для других операций
/*
PORTD &= code[(temp&0x07)] | X; //если пины порта задействованы для других операций, Х- маска остальных бит порта
PORTD |= code[(temp&0x07)];
*/
engine_power=temp&0xF8;
}

Re: Вопрос по прерыванию.

Добавлено: Вс апр 07, 2013 07:11:16
Pika4u
Спасибо! В engine_power у меня хранится значение ШИМ для двигателя. Добавлю switch и все окей будет :))

Re: Вопрос по прерыванию.

Добавлено: Вс апр 07, 2013 10:11:04
phanis
Не совсем понимаю зачем нужен switch , если все будет передаваться одним байтом
3 младших бита направление , остальные 5 бит скорость(32 состояния скорости).
принятый байт можно сразу передавать в регистр шим с использованием маски.

Код: Выделить всё

engine_power=temp&0xF8;

Re: Вопрос по прерыванию.

Добавлено: Вс апр 07, 2013 12:07:44
Pika4u
О,даже так можно))) Спасибо большое!)))

Re: Вопрос по прерыванию.

Добавлено: Вс апр 07, 2013 13:01:43
ut1wpr
phanis писал(а):Не совсем понимаю зачем нужен switch , если все будет передаваться одним байтом
Вот непонимаха! Ну как же на один байт контрольную сумму прилепишь? А urry ее требует! Иначе все рухнет. :) :) :) :)
Ну, а если серьезно, то в распоряжении программиста всегда есть контроль над регистром статуса порта коммуникации и можно (скорее нужно) проверять флаги ошибок. А сам обмен организовать с обязательным квитированием. Даже если он однобайтовый. Вообще-то, организация обмена без зависаний и без ошибок по USART-у не так тривиальна, как кажется.

Re: Вопрос по прерыванию.

Добавлено: Вс апр 07, 2013 13:36:05
phanis
Ну еще можно например так
приняли 2 одинаковых байта подряд значит это команда а не мусор.

Код: Выделить всё


#pragma vector=USART_RXC_vect
__interrupt void Uart_RX(void)
{
static unsigned char old_byte;
unsigned char temp;
temp=UDR;
if (old_byte==temp)
{
действия
}
old_byte=temp;
}
urry о регистрах статуса тож упоминал.
По поводу квитирования, как это можно здесь использовать?