реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Прием данных USART, пропускаю данные из за переполнения
messenger
сообщение Jan 18 2012, 12:56
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



Из заособенностей работы ответной стороны принял решение не использовать перывания USART
контроллер ATMega 64
скорость 4800
COM1
CodeVision AVR
используются перывания только от таймера Т1(16bit) где Т1 останавливается и флаг RxTimOvf=1 (по умолчанию 0)

Проблема передаю с ПК посылку 123456, принимаю 126
передаю с ПК посылку 123456789, принимаю 129
флаг DOR говорит о переполнении буфера приемника, т.е. данные вовремя не считались?Почкму так?

#define FRAMING_ERROR_1 (1<<FE1)
#define PARITY_ERROR_1 (1<<UPE1)
#define DATA_OVERRUN_1 (1<<DOR1)
#define DATA_REGISTER_EMPTY_1 (1<<UDRE1)
#define RX_COMPLETE_1 (1<<RXC1)


void READ_MASS_RS_1()
{
char status, data;
flag_stop_timer=0;
flag_eroor_rs=0;
RxTimOvf=0;

for (temp_1_i=0;temp_1_i<22;temp_1_i++)
{reading_mass_rs_1[temp_1_i]=0;} //Обнуление массива

// Reinitialize Timer1 value
TIMSK=(0<<TOIE1); // запретить прерывание от счетчика № T1
TCNT1H=0x00;TCNT1L=0x00; //Таймаут max для Т1
TIMSK=(1<<TOIE1); // разрешить прерывание от счетчика № T1

for (temp_1_i=0;temp_1_i<20;temp_1_i++)
{

while ((((status=UCSR1A) & RX_COMPLETE_1)==0)&& RxTimOvf==0);
data=UDR1;
if (RxTimOvf ==0) //Есть данные, И если тайм-аут НЕ истек "заходим"
{

if ((status & (FRAMING_ERROR_1| PARITY_ERROR_1 | DATA_OVERRUN_1)==0) && (RxTimOvf ==0))
{reading_mass_rs_1[temp_1_i]=data;}
else
{ flag_eroor_rs=1;//При чтении пакета были ошибки }

}

}




for (temp_1_i=0;temp_1_i<22;temp_1_i++)
{putchar1(reading_mass_rs_1[temp_1_i]);} //Смотрим что пришло

}

Сообщение отредактировал messenger - Jan 18 2012, 13:28
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 18 2012, 13:27
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Возможно:
1. Ошибка в функции putchar1
2. Данные принимаются с ошибкой. Чтобы проверить последнее следует либо проинициализировать массив reading_mass_rs_1 неким значением, отличным от нуля (например, символом 'X'). либо сохранять значение принятого байта, несмотря на ошибку в status (он же - UCSR1A).
Go to the top of the page
 
+Quote Post
messenger
сообщение Jan 18 2012, 13:43
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



Цитата(Палыч @ Jan 18 2012, 16:27) *
Данные принимаются с ошибкой.

Да.. горит переполнение буфера приемника- данные вовремя не забрали, но почему?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 18 2012, 15:30
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(messenger @ Jan 18 2012, 17:43) *
Да.. горит переполнение буфера приемника- данные вовремя не забрали, но почему?
Как Вы определили, что "Data OverRun" ? Такой же эффект может быть и при "Frame Error".
Попробуйте временно комментировать строку
Код
TIMSK=(1<<TOIE1); // разрешить прерывание от счетчика № T1

и передать 22 символа. Что будет возвращено?
Go to the top of the page
 
+Quote Post
messenger
сообщение Jan 18 2012, 16:06
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



если исключить из условия проверку на переполнение, то в принятом буфере лежат 3 символа,остальное пусто. Если не исключать то все пусто. Если не использовать таймер а просто ждать прихода символа то отправив один символ с ПК - принимаем один в буфер... все работает. Причем отправляю ,например, 123456789 а из трех принятых 129

Сообщение отредактировал messenger - Jan 18 2012, 18:55
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 18 2012, 16:19
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(messenger @ Jan 18 2012, 20:06) *
если исключить из условия проверку на переполнение, то в принятом буфере лежат 3 символа,остальное пусто. Если не исключать то все пусто. Если не использовать таймер а просрочки ждать то 1отправил-1принял... все работает. Причем отправляю ,например, 123456789 а из трех принятых 129

Путано объясняете... Ничего не понял...
Если убрать проверку status, сохранять значение data в буфере всегда, то что будет возвращать?
Go to the top of the page
 
+Quote Post
messenger
сообщение Jan 18 2012, 16:45
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



129 принимает
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 18 2012, 17:21
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Приведите код инициализации таймера и процедуру обработки прерывания
Go to the top of the page
 
+Quote Post
messenger
сообщение Jan 18 2012, 18:54
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x01; //без делителя
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;


//Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
TIMSK=(0<<TOIE1); //запретить прерывание от счетчика № 0
RxTimOvf=1;
flag_timer_1_set=1;//Используется в задержках(паузах)
}//void

Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 18 2012, 19:59
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Маленькая ошибочка при определении тайм-аута.
В функции READ_MASS_RS_1 перед разрешением прерывания от таймера необходимо сбросить флаг TOV1
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jan 18 2012, 20:42
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(messenger @ Jan 18 2012, 20:54) *
TIMSK=(0<<TOIE1); //запретить прерывание от счетчика № 0

Сомнительное действие: написано вроде так "//запретить прерывание от счетчика № 0"
но комментарий неверный, т.к. TIMSK=(0<<TOIE1); эквивалентно TIMSK=0, что означает запрет врех прерываний разрешаемых через TIMSK, в том числе и от таймера T0 (для Atmega64/128).
Правильно так:
Код
TIMSK&=~(1<<TOIE1);
// и на выходе
TIMSK|=(1<<TOIE1);


Проблема наверно не в этом, но потенциально - это грабля.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jan 18 2012, 21:00
Сообщение #12


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



1. Как вы синхронизируете начало таймаута и начало передачи символа с ПК?

2. Зачем вы трижды проверяете таймаут (RxTimOvf==0) во время приёма одного байта, достаточно одной проверки в while. Возможно будет достаточно одной проверки в конце цикла передачи всех байт


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
messenger
сообщение Jan 19 2012, 04:00
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



"перед разрешением прерывания от таймера необходимо сбросить флаг TOV1"- обязательно сделаю, только не раньше вечера

с Т0 это конечно ошибочка. Там д.б. Т1

а как нужно синхронизировать?у меня нет ,наверно, синхронизации. Просто жду по таймеру много больше. Это же не критично?

RxTimOvf проверяю дважды. Первый раз что бы не повиснуть, второй что бы понять успела ли посылка набрать 22 символа.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 19 2012, 05:26
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(messenger @ Jan 19 2012, 08:00) *
...успела ли посылка набрать 22 символа.

Хотя это не решит проблему, но: Ваша программа принимает только 20 символов из 22.

for (temp_1_i=0;temp_1_i< 20 ;temp_1_i++)

Цитата(messenger @ Jan 19 2012, 08:00) *
а как нужно синхронизировать?у меня нет ,наверно, синхронизации.

Сброс флага TOV (это - Вы добавите) и регистра TCNT (это - уже есть) в функции READ_MASS_RS_1 перед ожиданием прихода в USART символов и будет синхронизацией.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jan 19 2012, 08:07
Сообщение #15


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(messenger @ Jan 19 2012, 04:00) *
а как нужно синхронизировать?у меня нет ,наверно, синхронизации. Просто жду по таймеру много больше. Это же не критично?

RxTimOvf проверяю дважды. Первый раз что бы не повиснуть, второй что бы понять успела ли посылка набрать 22 символа.

1. Проверяете вы трижды: в операторе while, операторе if, и ещё раз в операторе if. 2-я и 3-я проверки бесполезны и даже вредны, поскольку в 1-ой проверке таймаута не было, принятый байт вы считали, но таймер1 тикает дальше и таймаут может наступить и вы запишете ошибку приёма, хотя никакой ошибки не было.

2. Синхронизировать нужно и вот почему. Вы запускаете программу в МК, запускается таймаут помимо всего прочего, затем вы нажимаете кнопку на ПК и начинаете передачу вашего пакета. Таймaут у вас заканчивается то раньше, то позже, отсюда все ваши беды. Уберите таймаут из цикла вообще, примите весь пакет, затем проверьте, был ли таймаут или нет. Засинхронизировать просто - примите 1-й байт от ПК, после него запустите таймаут.

3. Вообще, какая-то логика программы у вас странная. По программе, передав 123456, вы должны бы получить в буфере 120006, а вы пишете, что приняли 126, так не должно быть. Похоже, после приёма первых 2-х символов у вас пресловутый таймаут и наступает.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 13th August 2025 - 11:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01492 секунд с 7
ELECTRONIX ©2004-2016