| Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
Проблема правильного приема пакета UART AVR
26.04.2011, 21:12
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.11.2008
Адрес: г.Смоленск
Сообщений: 2,010
Сказал спасибо: 348
Сказали Спасибо 1,023 раз(а) в 551 сообщении(ях)
|
Проблема правильного приема пакета UART AVR
Есть кусок кода(ниже) минимально переделан из http://www.levap.ru/2010/10/paketnyj...bmena-dannymi/
Протокол на основе всем известного WAKE. Все варится в CVAVR Проблема в том, что пакет принимается полностью, начало пакета определяется, а вот конец нет.
Сам пакет выглядит так
По протеусу, да и в железе одно и тоже. Получается что в буфере имеем
0x00 0x03 0x00 0x66 0x0D 0x0A. А по идее должно быть 0x00 0x03 0x00 0x66, так как \r и \n являются концовкой пакета, т.е. по ним определяем, что пакет принят и взводим глобальные флаги приема. Далее получаем адрес, команду, кол-во байтов данных, сами байты и CRC8 пакета. Но так как концовка попадает в буфер, получается, что отследить AVR конец пакета не может.
А я не могу понять почему. Есть, уважаемые, у кого какие мысли? Заранее спасибо!
Код упрощен, остальное в приложении
|
PHP код:
|
#include ‹mega128.h›
// Standard Input/Output functions
#include ‹stdio.h›
#include "commands.h"
#include "tbcp.h"
//*********************************************
#define ASCII_CR '\r'
#define ASCII_LF '\n'
#define ASCII_SOF ':'
#define TBCP_BROADCAST 0x00
typedef enum
{
STATE_RX_IDLE, /* Receiver is in idle state. */
STATE_RX_RCV, /* Frame is beeing received. */
STATE_RX_WAIT_EOF /* Wait for End of Frame. */
}eTBCPRcvState ;
typedef enum
{
STATE_TX_IDLE, /* Transmitter is in idle state. */
STATE_TX_START, /* Starting transmission (':' sent). */
STATE_TX_DATA, /* Sending of data (Address, Data, LRC). */
STATE_TX_END /* End of transmission. */
}eTBCPSndState;
typedef enum
{
BYTE_HIGH_NIBBLE, /* Character for high nibble of byte. */
BYTE_LOW_NIBBLE /* Character for low nibble of byte. */
}eTBCPBytePos;
char flag_proba = 0;
/*
* States
*/
volatile eTBCPRcvState eRcvState;
volatile eTBCPSndState eSndState;
volatile eTBCPBytePos eBytePos;
//volatile char primer;
/*
* Data Buffers
*/
unsigned char RcvFrame[TBCP_FRAME_SIZE];
unsigned char SndFrame[TBCP_FRAME_SIZE];
unsigned char ucRcvDataPos;
volatile unsigned char ucSndDataPos;
volatile unsigned char ucSndDataCount;
/*
* Flags
*/
volatile unsigned char ucFrameReceived;
unsigned char ucSlaveAddress;
/*
* Text to Integer
* Integer to Text
*/
static unsigned char CHAR2BIN(unsigned char ucCharacter);
static unsigned char BIN2CHAR(unsigned char ucByte);
void USART0_Init(void){
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 9600
UCSR0A=0x00;
UCSR0B=0xD8;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x67;
// USART1 initialization
// USART1 disabled
UCSR1B=0x00;
};
/*
* Init Protocol Stack
*/
eTBCPErrorCode TBCP_Init(unsigned char ucAddress) {
ucSlaveAddress = ucAddress;
eRcvState = STATE_RX_IDLE;
eSndState = STATE_TX_IDLE;
ucRcvDataPos = 0;
ucSndDataPos = 0;
ucSndDataCount = 0;
ucFrameReceived = 0;
return TBCP_ENOERR;
}
// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
unsigned char status;
unsigned char ucByte;
unsigned char ucResult;
status=UCSR0A;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))!=0) { putsf("1");}
/* Read Data */
ucByte=UDR0;
/* Frame already received? Ignoring any new data */
if(ucFrameReceived) {
return;
}
/* Start Of Frame Received */
if(ucByte == ASCII_SOF) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/* Reset the input buffers to store the frame. */
ucRcvDataPos = 0;
eBytePos = BYTE_HIGH_NIBBLE;
eRcvState = STATE_RX_RCV;
return;
}
switch(eRcvState) {
case STATE_RX_RCV: {
if(ucByte == ASCII_CR) {//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eRcvState = STATE_RX_WAIT_EOF;
} else {
ucResult = CHAR2BIN(ucByte);
switch(eBytePos) {
case BYTE_HIGH_NIBBLE: {
//putsf("1");
if(ucRcvDataPos ‹ TBCP_FRAME_SIZE) {
RcvFrame[ucRcvDataPos] = (unsigned char)(ucResult ‹‹ 4);
eBytePos = BYTE_LOW_NIBBLE;
break;
} else {
eRcvState = STATE_RX_IDLE;
putsf("-");
};
break;
}
case BYTE_LOW_NIBBLE: {
//putsf("2");
RcvFrame[ucRcvDataPos] |= (unsigned char)(ucResult & 0x0F);
ucRcvDataPos++;
eBytePos = BYTE_HIGH_NIBBLE;
break;
}
}
}
break;
}
case STATE_RX_WAIT_EOF: {
if(ucByte == ASCII_LF) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/* Receiver is again in idle state. */
eRcvState = STATE_RX_IDLE;
/* Set global Flag */
ucFrameReceived = 1;
} else {
/* Frame is not OK. Delete frame. */
eRcvState = STATE_RX_IDLE;
}
break;
}
}
}
//*********************************************
/*
* Message Handle
*/
eTBCPErrorCode Process() {
unsigned char ucRxCRC,ucCRC;
unsigned char ucAddress, ucCommand, ucLength;
/* Frame Received */
if(ucFrameReceived) { flag_proba = 1;
putsf("11");
/* Handle Message */
ucAddress = RcvFrame[TBCP_ADDR_INDEX];
ucCommand = RcvFrame[TBCP_CMD_INDEX];
ucLength = RcvFrame[TBCP_LEN_INDEX];
/* Check Array Index */
if(ucLength › TBCP_MAX_DATA_LENGTH) {
/* Error! Reset Message */
ucFrameReceived = 0;
return TBCP_EOVERFLOW;
}
ucRxCRC = RcvFrame[TBCP_DATA_INDEX + ucLength];
ucCRC = TBCP_CRC8(RcvFrame, TBCP_DATA_INDEX + ucLength);
/* Check CRC */
if(ucRxCRC == ucCRC) {
/* Is Message to this device? */
if((ucAddress == ucSlaveAddress) || (ucAddress == TBCP_BROADCAST)) {
Command_Exe(ucCommand);
}
}
/* Reset Message */
ucFrameReceived = 0;
}
return TBCP_ENOERR;
}
/*
* Send Message
*/
eTBCPErrorCode Send(unsigned char ucCommand, unsigned char ucLength) {
/* Buffer Overflow? */
if(ucLength › TBCP_MAX_DATA_LENGTH) {
return TBCP_EINVAL;
}
SndFrame[TBCP_ADDR_INDEX] = ucSlaveAddress;
SndFrame[TBCP_CMD_INDEX] = ucCommand;
SndFrame[TBCP_LEN_INDEX] = ucLength;
SndFrame[TBCP_DATA_INDEX + ucLength] = TBCP_CRC8(SndFrame, TBCP_DATA_INDEX + ucLength);
ucSndDataPos = 0;
ucSndDataCount = ucLength + 4; // Addr + Cmd + Len + CRC
eSndState = STATE_TX_START;
UCSR0B=0x58; //включить прерывание на ножке ТХ USART0
return TBCP_ENOERR;
}
/*
* Reply without data
*/
eTBCPErrorCode Reply(unsigned char ucCommand, unsigned char ucErrorCode) {
SndFrame[TBCP_DATA_INDEX] = ucErrorCode;
return Send(ucCommand, 1);
}
/*
* Convert Character to BIN
*/
static unsigned char CHAR2BIN(unsigned char ucCharacter) {
if((ucCharacter ›= '0') && (ucCharacter ‹= '9'))
return (unsigned char)(ucCharacter - '0');
else if((ucCharacter ›= 'A') && (ucCharacter ‹= 'F'))
return (unsigned char)(ucCharacter - 'A' + 0x0A);
return 0xFF;
}
/*
* Convert BIN to Character
*/
static unsigned char BIN2CHAR(unsigned char ucByte) {
if(ucByte ‹= 0x09)
return (unsigned char)('0' + ucByte);
else if((ucByte ›= 0x0A) && (ucByte ‹= 0x0F))
return (unsigned char)(ucByte - 0x0A + 'A');
return '0';
}
|
Заранее извиняюсь, что код такой длинный получился, думал хоть прокрутка появится.
Последний раз редактировалось Saadov; 26.04.2011 в 21:16.
|
|
|
|
26.04.2011, 21:43
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,815
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Re: Проблема правильного приема пакета UART AVR
Сообщение от Saadov
|
Сам пакет выглядит так PHP код:
:000300660D0A
в буфере имеем 0x00 0x03 0x00 0x66 0x0D 0x0A.
должно быть 0x00 0x03 0x00 0x66, так как \r и \n
|
Дык пакет 000300660D0A,
почему должно быть в буфере 0x00 0x03 0x00 0x66?
В буфер принммается весь пакет, а уж как вы его бработаете.
Убивайте тода концовку пакета после подсчёта КС.
__________________
"picavr(ГАВ)мыло.ру" USB_Analyzer, Digital_Storage_Oscilloscope "picavr.kr1.ru" заказы в Китай компонентов/изготовление: плат/ЖКИ/мембраных клавиатур/имп трансформаторов
|
|
|
|
26.04.2011, 21:50
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.11.2008
Адрес: г.Смоленск
Сообщений: 2,010
Сказал спасибо: 348
Сказали Спасибо 1,023 раз(а) в 551 сообщении(ях)
|
Re: Проблема правильного приема пакета UART AVR
Спасибо. Смысл в том, что к пакету прилагается концовка 0x0D(\r) 0x0A(\n). Принимаем по одному байту, как только принимаем 0x0D, ждем 0x0A и взводим флаг. По этому флагу обрабатываем принятый пакет.
|
|
|
|
26.04.2011, 21:52
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,026
Сказал спасибо: 60
Сказали Спасибо 3,941 раз(а) в 2,302 сообщении(ях)
|
Re: Проблема правильного приема пакета UART AVR
Добавить программное распознавание кода 0D, взводим флаг, и если следующий байт 0A - однозначно определяем конец пакета. В противном случае флаг сбрасываем
|
|
|
|
26.04.2011, 21:55
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.11.2008
Адрес: г.Смоленск
Сообщений: 2,010
Сказал спасибо: 348
Сказали Спасибо 1,023 раз(а) в 551 сообщении(ях)
|
Re: Проблема правильного приема пакета UART AVR
Сообщение от niXto
|
|
Добавить программное распознавание кода 0D
|
|
PHP код:
|
#define ASCII_CR '\r'
#define ASCII_LF '\n'
#define ASCII_SOF ':'
|
|
PHP код:
|
if(ucByte == ASCII_SOF) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/* Reset the input buffers to store the frame. */
ucRcvDataPos = 0;
eBytePos = BYTE_HIGH_NIBBLE;
eRcvState = STATE_RX_RCV;
return;
}
|
|
PHP код:
|
if(ucByte == ASCII_CR) {//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eRcvState = STATE_RX_WAIT_EOF;
} else {
|
|
PHP код:
|
if(ucByte == ASCII_LF) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/* Receiver is again in idle state. */
eRcvState = STATE_RX_IDLE;
/* Set global Flag */
ucFrameReceived = 1;
} else {
|
Все делается, только чего-то я не могу догнать(
|
|
|
|
27.04.2011, 08:05
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.11.2008
Адрес: г.Смоленск
Сообщений: 2,010
Сказал спасибо: 348
Сказали Спасибо 1,023 раз(а) в 551 сообщении(ях)
|
Re: Проблема правильного приема пакета UART AVR
Есть у кого еще какие мысли? Мои уже кончились.
|
|
|
|
27.04.2011, 08:20
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,138
Сказал спасибо: 21
Сказали Спасибо 635 раз(а) в 344 сообщении(ях)
|
Re: Проблема правильного приема пакета UART AVR
Попробуйте
|
Код:
|
#define ASCII_CR 0x0D
#define ASCII_LF 0x0A |
|
|
|
|
27.04.2011, 08:23
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.11.2008
Адрес: г.Смоленск
Сообщений: 2,010
Сказал спасибо: 348
Сказали Спасибо 1,023 раз(а) в 551 сообщении(ях)
|
Re: Проблема правильного приема пакета UART AVR
Испробовано в первую очередь, спасибо. Результат тот же(
|
|
|
|
27.04.2011, 10:22
|
|
|
Прописка
Регистрация: 25.08.2007
Сообщений: 193
Сказал спасибо: 11
Сказали Спасибо 57 раз(а) в 33 сообщении(ях)
|
Re: Проблема правильного приема пакета UART AVR
Поместите проект в Proteus. В пошаговой отладке проще будет найти.
|
|
|
|
27.04.2011, 10:37
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.11.2008
Адрес: г.Смоленск
Сообщений: 2,010
Сказал спасибо: 348
Сказали Спасибо 1,023 раз(а) в 551 сообщении(ях)
|
Re: Проблема правильного приема пакета UART AVR
Протеус еще та штука, не особо он дружит с cof файлами CVAVR, не дает точки остановки ставить, а пошагово не отображает исходник. Перепробовал все, не шибко помогло. Думал, что себе голову задурил и не вижу очевидного, потому и попросил помощи). Все чаще приходит в голову, что чудо кроется где-то в чудесном CVAVR, точнее его свойствах, которые не совсем поддаются логике. А этот код является частью большого проекта написанного в нем же, не охото переносить под др. компилятор. Да и хочется грабельку сломать, чтоб другим по лбу не била.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 17:03.
|
|