Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
08.04.2010, 14:12
|
|
Временная регистрация
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
|
Re: AVR USART+прерывания=потеря данных
Тогда отладчик в зубы и вперед.
|
|
|
|
08.04.2010, 14:28
|
|
Частый гость
Регистрация: 15.01.2007
Сообщений: 20
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: AVR USART+прерывания=потеря данных
Все вылизано. Реально. всеь код перепахан, главным образом для преобразования разных "PORTB&=(0xBB‹‹((PINB››5)&0x02))" в нормальное читаемое состояние. Главные функции переписаны с нуля, не заглядывая в старый листинг.
Я со 100% уверенностью говорю, что дыры не в коде, аппаратный FIFO реально мал, хотя по расчетам, исходя из задекларированных таймингов со стороны клавиатуры мои 8 MIPS покрываются кодом прерываний на 60%. Парадокс, но не хватает аппаратного буфера UART ((. Почему - загадка, но я мало знаю о специфике работы МК с прерываниями.
void get()
{
unsigned char i=0;
while(rx_buffer[rx_head])
{
tmps[i]=rx_buffer[rx_head];
rx_head++;
i++;
}
tmps[i]=0;
rx_head++;
received--;
}
Последний раз редактировалось umgah; 08.04.2010 в 14:35.
|
|
|
|
08.04.2010, 14:32
|
|
Временная регистрация
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
|
Re: AVR USART+прерывания=потеря данных
А буффер не переполняется? Проверок-то нет.
|
|
|
|
08.04.2010, 14:37
|
|
Частый гость
Регистрация: 15.01.2007
Сообщений: 20
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: AVR USART+прерывания=потеря данных
Первое что я сделал, это ненадолго добавил "if (rx_head==rx_tale) PORTA=0xFF" ), в теле прерывания UART, после инкремента указателя.
И то откровенно говоря для очистки совести. Тереются не первые символы.
Отправка типовой посылки имеет вид "‹AABBCCDDEEFF\n" именно с таким типичным количеством символов. При однократных отправках нет проблем, но по получению такой телеграммы контроллер тут же начинает передачу(дергать ноги) и если три- четыре таких телеграммы идут с небольшим разрывом (если слитно как ни странно проблем нет), то вот тут идет потеря данных.
Последний раз редактировалось umgah; 08.04.2010 в 14:44.
|
|
|
|
08.04.2010, 14:44
|
|
Временная регистрация
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
|
Re: AVR USART+прерывания=потеря данных
Выражение rx_head==rx_tale в твоём случае вернет true если буффер или пуст или полон. Чтобы определить что именно случилось, нужно либо 16 - битный счетчик кол-ва байт в буффере. У тебя это received. Причем обращение к нему должны быть атомарны - иначе глюков не оберёшся. Либо использавать 16-ти битные индексы и более сложную логику. А какая-то проверка на заполнение буффера должна быть.
|
|
|
|
08.04.2010, 14:49
|
|
Частый гость
Регистрация: 15.01.2007
Сообщений: 20
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: AVR USART+прерывания=потеря данных
Нет. Я поправил выше пост, проверка идет строго после инкремента указателя в теле прерывания UART. received это число завершенных сообщений (имещих 0x0D на конце, которое заменяется по получаению на 0x00 чтобы получить zero-term строку).
По мере получаения 0x0D - растет received. По мере считывания в get() и копирования в темп-строку received уменьшается.
|
|
|
|
08.04.2010, 14:56
|
|
Частый гость
Регистрация: 15.01.2007
Сообщений: 20
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: AVR USART+прерывания=потеря данных
Вот примерный тестовый код, он исправен:
// бла-бла-бла
// стандартный флаг занятости UART
#define DATA_REGISTER_EMPTY (1‹‹UDRE)
char tmps[256];
char rx_buffer[256];
volatile unsigned char rx_head=0;
volatile unsigned char rx_tale=0;
char tx_buffer[256];
volatile unsigned char tx_head=0;
volatile unsigned char tx_tale=0;
volatile unsigned char received=0;
// бла-бла-бла
// ***************** UART COMMUNICATION SECTION *****************
//UART0 initialize
// desired baud rate: 38400 //57600 - test
// actual: baud rate:38462 (0,2%)
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x0C; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
/*
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x19; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
*/
}
#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
void uart0_rx_isr(void)
{
char ch=0;
//uart has received a character in UDR
// получили данные
ch=UDR;
if ((ch›=0x61) && (ch‹=0x7A)) ch=ch-0x20;
// ну типа поехали...
if (ch==0x0A) return;
if (ch==0x0D)
{
received++;
ch=0; // сделали zero-terminated строку
}
rx_buffer[rx_tale]=ch;
rx_tale++;
// вот тут это было if (rx_head==rx_tale) PORTA=0xFF; // debug reasons only
}
void send(char* s)
{
unsigned char i=0;
while(s[i])
{
tx_buffer[tx_tale]=s[i];
tx_tale++;
i++;
}
}
void get()
{
unsigned char i=0;
while(rx_buffer[rx_head])
{
tmps[i]=rx_buffer[rx_head];
rx_head++;
i++;
}
tmps[i]=0;
rx_head++;
received--;
}
// ***************** UART COMMUNICATION SECTION *****************
void main()
{
init_devices();
while (1)
{
// UART section
// UART transmission if something is in queue
if (tx_head!=tx_tale)
{
if ((UCSRA & DATA_REGISTER_EMPTY)!=0)
{
UDR=tx_buffer[tx_head];
tx_head++;
}
}
if (received)
{
get();
/*
send(crlf);
tx_buffer[tx_tale]='-';
tx_tale++;
send(tmps);
send(crlf);
*/
if (tmps[0]=='+')
{
send("+ACK");
send(crlf);
}
}
}
}
|
|
|
|
08.04.2010, 14:58
|
|
Частый гость
Регистрация: 15.01.2007
Сообщений: 20
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: AVR USART+прерывания=потеря данных
Пояснять код нет нужды. он проверен. Вся часть UART работает отлично. проблема не там.
|
|
|
|
08.04.2010, 14:58
|
|
Временная регистрация
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
|
Re: AVR USART+прерывания=потеря данных
Ясно. received у тебя счетчик принятых строк.
Сообщение от umgah
|
Тереются не первые символы.
Отправка типовой посылки имеет вид "‹AABBCCDDEEFF\n" именно с таким типичным количеством символов. При однократных отправках нет проблем
|
Ну, точно буффер переполняется при частых посылках.
Попробуй скорость передачи увеличить и добавь проверку на переполнение
|
|
|
|
08.04.2010, 15:00
|
|
Временная регистрация
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
|
Re: AVR USART+прерывания=потеря данных
И tx_buffer тоже может переполняться.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 21:44.
|
|