Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
11.06.2012, 21:58
|
#1
|
Прохожий
Регистрация: 28.08.2008
Сообщений: 4
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
Пакеты через USART
Приветствие! Делал дистанционное управление. Надоело постоянно обрабатывать символы от USART. Решил написать библиотечку для обработки пакетов. Кто желает поучавствовать. Библиотека должна иметь две функции pacet_init(); pacet_send(); и флаг наличия связи с передатчиком. pacet_init(); задаёт адрес устройства в сети, размер пакета, количество аналоговых сигналов. pacet_send(); передает пакет.
К примеру имеем па передаюшем мкроконтроллёре массив unsigned char TXpacet[pacetSIZE]="000000000"; и несколько int ANG1,ANG2,ANG3;
при вызове pacet_send(); точно в таких же массиве и переменных на принемающем мк. появляются данные.
Вот начал делать.
Структура пакета :аа00000000k сначала идёт двоеточие потом адресс устройства (аа) конец пакета (k)
вот как пытаюсь принемать
char ADRES1,ADRES2;//адресс устройства
int flag_paceta=0; //наличее связи с передатчиком
int pacetSIZE=8; //размер пакета
unsigned char RXpacet[pacetSIZE]="000000000";//принятые данные
unsigned char rx_buffer[15];//массив где хранится пакет
//================================================== ====================================
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
if (rx_buffer_overflow==1)
{
rx_buffer[rx_wr_index]=data;
if (++rx_wr_index == RX_BUFFER_SIZE)
{
rx_wr_index=0;
rx_buffer_overflow=0;
if ((rx_buffer[0]==ADRES1)&(rx_buffer[1]==ADRES2)&(rx_buffer[7]=='k'))
{
for (rx_counter=0;rx_counter‹7;rx_counter++)
{
RXpacet[rx_counter]=rx_buffer[rx_counter];
flag_paceta=1;
};
};
};
};
if (data==':')
{ rx_buffer_overflow=1;
rx_wr_index=0;
};
};
}
сначала ждём двоеточия. поймали забиваем массив rx_buffer[15];сравниваем адресс ADRES1,ADRES2; и 'k' в конце если совпали забиваем данные в RXpacet[pacetSIZE]; кто что подскажет?
|
|
|
Сказали "Спасибо" vic12333
|
|
|
11.06.2012, 22:19
|
#2
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: ПАКЕТЫ ЧЕРЕЗ USART
Пишите, пишите. У вас получается.
|
|
|
Сказали "Спасибо" Easyrider83
|
|
|
12.06.2012, 01:25
|
#3
|
Гражданин KAZUS.RU
Регистрация: 25.11.2010
Сообщений: 516
Сказал спасибо: 1
Сказали Спасибо 126 раз(а) в 109 сообщении(ях)
|
Re: Пакеты через USART
десятки лет развития разнообразных стеков коту под хвост
посмотри лучше как работает PPP и перетащи к себе в проект - получишь на выходе готовую пакетную передачу. бонусом пойдет аппаратная независимость алгоритмов.
|
|
|
|
12.06.2012, 05:57
|
#4
|
Почётный гражданин KAZUS.RU
Регистрация: 28.02.2010
Сообщений: 2,297
Сказал спасибо: 53
Сказали Спасибо 461 раз(а) в 392 сообщении(ях)
|
Re: Пакеты через USART
Вот именно, коту под хвост ... даже в CV , нормальная буферизация,только лови оттуда.(зайдите в Tools,Wizard.поставьте галочку на прерываниях USART,накидает листинг)
|
|
|
Сказали "Спасибо" OlegNZH
|
|
|
12.06.2012, 08:32
|
#5
|
Гражданин KAZUS.RU
Регистрация: 31.12.2010
Сообщений: 837
Сказал спасибо: 371
Сказали Спасибо 153 раз(а) в 113 сообщении(ях)
|
Re: Пакеты через USART
Когда то подобное делал, тоже для управления. В один прекрасный момент мне стало недостаточно для управления передавать данные по 1 байту.
Код писался для AT89 на Keil UVision2
PHP код:
|
// ------- Ожидает байт с RS_232 не более заданного времени, если нет больше 50 циклов, то возращает ошибку unsigned char WaitByteComm() { TH0 = 0; TL0 = 0; do { if (RI == 1) { return(OK); } } while (TH0 ‹ 100);
return(BYTE_WAIT_ERROR); }
// --------------- Считывет пакет из RS_232 ---------------------------- unsigned char ReadPackComm() { unsigned char j, res;
sendTo = SBUF; RI = 0; res = WaitByteComm(); if (res != OK) return(res); recFrom = SBUF; RI = 0; res = WaitByteComm(); if (res != OK) return(res); bytesOfRead = SBUF; RI = 0; for (j = 0; j ‹ bytesOfRead; j++) { if (WaitByteComm() == OK) { Buf[j] = SBUF; RI = 0; } else return(DATA_ERROR); }
return(OK); }
// ------------- Посылает пакет через RS_232 unsigned char WritePackComm(unsigned char sendTo, bytesOfWrite) { unsigned char i;
SBUF = sendTo; DelayMS(10); SBUF = HOST_IP; DelayMS(10); SBUF = bytesOfWrite; DelayMS(10); for (i = 0; i ‹ bytesOfWrite; i++) { SBUF = Buf[i]; DelayMS(10); } return(OK); }
void Main(void) { ..... while (1) { if (RI == 1) // в буфер COM порта пришел байт { bt = ReadPackComm(); if (bt == OK) { AnalizePackNet(); } } ............................... //основной цикл программы } }
|
Приход новых данных периодически проверяется в основном цикле программы. Конечно можно было повесить на прерывание но во первых не хотелось из прерывания вызывать громоздкий код, во вторых программа как то реагирует на полученный пакет данных и выполняет определенные действия, мне это тоже было удобнее делать в основном программном потоке.
Последний раз редактировалось Flopix; 12.06.2012 в 08:37.
|
|
|
|
12.06.2012, 09:35
|
#6
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Пакеты через USART
Обычно прерывание по UART принимает байт, кладет его в массив, инкременирует указатель и поднимает флаг. На это десятка команд вполне достаточно.
|
|
|
Эти 2 пользователя(ей) сказали Спасибо Easyrider83 за это сообщение:
|
|
|
12.06.2012, 09:46
|
#7
|
Гражданин KAZUS.RU
Регистрация: 31.12.2010
Сообщений: 837
Сказал спасибо: 371
Сказали Спасибо 153 раз(а) в 113 сообщении(ях)
|
Re: Пакеты через USART
Easyrider83, да в принципе так логичнее. Тогда не нужно будет городить таймауты в функции ожидания байта. Это была одна из моих первых программ под микроконтроллеры и тогда я еще не особо дружил с прываниями
Последний раз редактировалось Flopix; 12.06.2012 в 09:50.
|
|
|
|
12.06.2012, 09:50
|
#8
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Пакеты через USART
Сообщение от Flopix
|
Easyrider83, да впринципе так логичнее. Тогда не нужно будет городить таймауты в функции ожидания байта.
|
Це есть самый примитивный буфер!
Если добавить проверку по максимальному значению указателя, обнуляя по переполнению, буфер будет называться кольцевым. Это еще 3-4 инструкции.
Можно там же ловить начало пакета по контрольному байту.
Можно там же обнулять таймер тайм-аута. Если таймер переполняется - пакет принят полностью.
|
|
|
Сказали "Спасибо" Easyrider83
|
|
|
12.06.2012, 11:55
|
#9
|
Гражданин KAZUS.RU
Регистрация: 25.11.2010
Сообщений: 516
Сказал спасибо: 1
Сказали Спасибо 126 раз(а) в 109 сообщении(ях)
|
Re: Пакеты через USART
...и там же огрести багов, когда контрольный байт потеряется при передаче.
|
|
|
|
12.06.2012, 12:05
|
#10
|
Почётный гражданин KAZUS.RU
Регистрация: 10.12.2007
Адрес: Екатеринбург
Сообщений: 2,731
Сказал спасибо: 2,443
Сказали Спасибо 893 раз(а) в 580 сообщении(ях)
|
Re: Пакеты через USART
Отправить команду: ошибка приема.
|
|
|
Сказали "Спасибо" baiderin
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
Usart (УСАПП)
|
wolfinstein |
Микроконтроллеры, АЦП, память и т.д |
15 |
18.02.2010 19:15 |
Пакеты, использующие сети Петри
|
makfruit |
Proteus, KiCAD и другие ECAD |
2 |
21.12.2009 22:06 |
atmega128 и 1-wire через USART
|
mer1in |
Микроконтроллеры, АЦП, память и т.д |
3 |
16.07.2009 19:30 |
Связать 2 МК по USART
|
MAX1978 |
Микроконтроллеры, АЦП, память и т.д |
17 |
08.08.2007 19:15 |
USART
|
DK |
Микроконтроллеры, АЦП, память и т.д |
1 |
03.09.2003 19:49 |
Часовой пояс GMT +4, время: 04:59.
|
|