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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Одноразовый UART в AVR, Отправляет данные корректно только 1 раз..
_Pasha
сообщение Aug 6 2012, 12:25
Сообщение #31


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Вы б отложили чашку с кофейной гущей и гадали бы на Протеусе. Найти обращение к байту в интересующей структуре - дело 5 минут при помощи условных брекпоинтов. Тем более, что дефект у Вас стабильный и танцы с бубном не нада.
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Aug 6 2012, 13:10
Сообщение #32


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(_Артём_ @ Aug 6 2012, 15:12) *
...А как указать чтобы поля не менялись местами?


код видоизменить так, что бы не было в нём первого поля, или последнего. структура как чёрный ящик - длина, начало буфера. тогда пофигу будет где в ней какие поля раскиданы.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Aug 6 2012, 13:24
Сообщение #33


Гуру
******

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



Цитата(kolobok0 @ Aug 6 2012, 16:10) *
код видоизменить так, что бы не было в нём первого поля, или последнего. структура как чёрный ящик - длина, начало буфера. тогда пофигу будет где в ней какие поля раскиданы.

А что у вас были случаи когда компилятор менял местами поля в структуре?
Я таких случаев не помню.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 6 2012, 19:09
Сообщение #34


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (_Артём_ @ Aug 6 2012, 16:24) *
Я таких случаев не помню.
Да и стандарт не позволяет. Но у страха-то глаза велики...


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Dikoy
сообщение Aug 6 2012, 20:18
Сообщение #35


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 4-03-09
Из: Богота, Колумбия
Пользователь №: 45 676



Цитата(Petka @ Aug 6 2012, 10:33) *
Полный бред.
1) ADC3_temp = ADC3_RxC_counter;
2) ADC3_temp--;
3) Buf_ADC3[ADC3_temp] = UDR1;
4) ADC3_RxC_counter = ADC3_temp;
5) goto 1
Разумеется после обнуления ADC3_temp команда из п.2 сделает ADC3_temp==0xFF и тогда п.3 сломает память.

Вы, как всегда, пишете быстрее чем думаете.
1 и 4 кпируют волатайл переменную в R16 и далее все операции идут с регистром, что экономит порядка 20 тактов.
5 - ваш глюк.
3 - для одноразовой операции нет разницы, используется указатель или индекс. Всё равно будет с нуля браться адрес и вычисляться смещение.
2 - даже не знаю что и сказать.

А про порчу памяти от прерывания вам уже всё сказали. Не возникает лишнего прерывания. И я это вижу в железке на осциллографе, а не в протеусе, что суть кофейная гуща. Да ещё и пиратская (да да, есть такое понятие).

Компилятор НИКОГДА не переставит поля структуры. На то она и структура. По крайней мере за 5 лет работы в IAR и 8 лет в CV я такого не видел.

Цитата(kolobok0 @ Aug 6 2012, 17:10) *
код видоизменить так, что бы не было в нём первого поля, или последнего. структура как чёрный ящик - длина, начало буфера. тогда пофигу будет где в ней какие поля раскиданы.

Это называется массив wink.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 6 2012, 23:06
Сообщение #36


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Dikoy @ Aug 6 2012, 23:18) *
а не в протеусе, что суть кофейная гуща. Да ещё и пиратская (да да, есть такое понятие).

Как говорят братья-мусульмане, Аллах, когда ночью спит, через стенку не видит sm.gif
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Aug 7 2012, 06:05
Сообщение #37


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(_Артём_ @ Aug 6 2012, 17:24) *
...компилятор менял местами..


для тех кто начал читать топик с конца, даю справку:

речь шла не о компиляторах...


Цитата(Dikoy @ Aug 7 2012, 00:18) *
...Это называется массив..


в данном конкретном случае - не важно как это называется. важно как это воспринимается.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Aug 7 2012, 06:27
Сообщение #38


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Возьмите реализацию очередей из CVAvr-а. Я её и на WinAVR-е "портировал" - работает.

Структуры в CvAVR-е передавал, как байтовые массивы:

CODE

// Отправка структуры measureData
pData = (byte *)&measureData;
for (Uint=0; Uint<sizeof(measureData); Uint ++)
{
uartBufferPutchar ( *pData );
pData ++;
} // for


На компе, в программе на C# принимается как часы ... Даже второй МК (мега8), которая из себя изображает USB, нормально принимает. Там правда свои глюки есть, но то уже издержки эмуляции USB...
Изделие - ваттметр на Мега16, стек - 350 байт.

Сообщение отредактировал hd44780 - Aug 7 2012, 06:31


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
Petka
сообщение Aug 7 2012, 07:05
Сообщение #39


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(Dikoy @ Aug 7 2012, 00:18) *
...
1 и 4 кпируют волатайл переменную в R16 и далее все операции идут с регистром, что экономит порядка 20 тактов.
3 - для одноразовой операции нет разницы, используется указатель или индекс. Всё равно будет с нуля браться адрес и вычисляться смещение.

Не суть.
Цитата
5 - ваш глюк.

А что запретит прерывание по UART_RXC? Если прерывание не запрещены, то при следующем входном байте на UART будет снова вызван обработчик прерывания.
вы так упорото не хотите понять, что индекс массива у вас никак не защищён от переполнения вниз.
Цитата
А про порчу памяти от прерывания вам уже всё сказали.

так это или не так легко проверить: поставьте проверку на индекс массива
Код
if(ADC2_RxC_counter >= ADCBUFSISE){
    ERROR_LED_ON;
}
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Aug 7 2012, 07:12
Сообщение #40


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(hd44780 @ Aug 7 2012, 09:27) *
Возьмите реализацию очередей из CVAvr-а. Я её и на WinAVR-е "портировал" - работает.


Советовал уже использовать fifo гдето в первых постах.
У автора топика проблема с заполнением структуры данных АЦП а не с передачей.
Как по мне проглядывается ещё одна проблема - автор пытается заполнять структуру в прерываниях от ацп и одновремененно отправлять её по uart. Возможно там есть временное разделение - т.е. сначала структура заполняется, потом передаётся и гарантированно она не изменится в процессе передачи, но в целом подход неверный.
Было бы правильней проверять флаг необходимости передачи, при обнаружении с запрещёнными прерываниями закинуть всю структуру данных в fifo uart, сбросить флаг необходимости передачи, разрешить прерывания. Заодно можно обнулять индекс массива данных и инкрементировать его по каждому прерыванию ацп.
Go to the top of the page
 
+Quote Post
Dikoy
сообщение Aug 7 2012, 23:02
Сообщение #41


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 4-03-09
Из: Богота, Колумбия
Пользователь №: 45 676



Цитата(Petka @ Aug 7 2012, 11:05) *
А что запретит прерывание по UART_RXC?
}

UART в режиме SPI. Если байт не будет отправлен, то он не будет принят, и RxC не будет. Посмотрите тушку прерывания - последний байт принимается, но отправки (UDR1 = ADC3_temp;) нет.
Это про порты АЦП речь.
С передачей в комп уже всё определилось - не она виновата.

Цитата(hd44780 @ Aug 7 2012, 10:27) *
Возьмите реализацию очередей из CVAvr-а. Я её и на WinAVR-е "портировал" - работает.

У меня есть свой движок с очередью, пользую уже лет 5. Но в очереди есть смысл когда мы мониторим несколько портов и, главное, информация из этих портов может уйти произвольно.
В данном случае маршруты следования информации строго определены, делать очередь нет смысла.
Go to the top of the page
 
+Quote Post
Dikoy
сообщение Aug 8 2012, 02:35
Сообщение #42


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 4-03-09
Из: Богота, Колумбия
Пользователь №: 45 676



Переписал прерывание через указатель, и всё заработало:
CODE

unsigned char *pADC3_rx_pointer = &(Buf_ADC3[0]);;
volatile unsigned char ADC3_rx_compl = 0;

//*********

#pragma vector=(0x48*0x02)
__interrupt void ADC3_RxC_isr(void) { //

*pADC3_rx_pointer = UDR1;
if(pADC3_rx_pointer < (&(Buf_ADC3[ADCBUFSISE - 1])) ) {
pADC3_rx_pointer++;
UDR1 = 0xff;
} else {
ADC3_rx_compl = 0xff;
}

}

// **********

while(1) {
if( ADC3_rx_compl == 0xff ) {

CopyBufFast( (char *)&TransmisionFrame.ADC3[0], (char *)&Buf_ADC3[0], (ADCBUFSISE) ); // êîïèðóåì âðåìåííûé áóôåð â âûõîäíîé ôðåéì

pADC3_rx_pointer = &(Buf_ADC3[0]);
ADC3_rx_compl = 0;
}
}


Результат:

Код
22BB00000002000000000000000000000000000000000003000000000000
0000000000000000DF1A584696F1A500695F1A5F469971A55889A55A
22BB00000003000000000000000000000000000000000004000000000000
00000000000000001A584696F1A4FC695E1A5F469981A55889EDA55A
22BB00000004000000000000000000000000000000000005000000000000
00000000000000001A580696F1A500695E1A5F469971A55889EEA55A
22BB00000005000000000000000000000000000000000006000000000000
00000000000000001A580696E1A4FC695C1A5EC69961A55489F2A55A


Пока сделал только для АЦП №3.

Теперь думаю, как соптимизировать прерывание. Пробовал избавиться от ADC3_rx_compl и в мейнлупе поставить проверку
if( pADC3_rx_pointer == (&(Buf_ADC3[ADCBUFSISE - 1])) ) {}
Прерывание долбит непрерывно и не останавливается.
Уже поздно и мозг не варит, по тому не могу понять почему blink.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 8 2012, 16:18
Сообщение #43


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Dikoy @ Aug 8 2012, 05:35) *
Прерывание долбит непрерывно и не останавливается.
Уже поздно и мозг не варит, по тому не могу понять почему
Если pADC3_rx_pointer изменяется в прерывании, а анлизируется в основном цикле - она должна быть объявлена как volatile-указатель: unsigned char * volatile pADC3_rx_pointer = &(Buf_ADC3[0]);


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Dikoy
сообщение Aug 9 2012, 02:33
Сообщение #44


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 4-03-09
Из: Богота, Колумбия
Пользователь №: 45 676



В этом случае компилер ругается

Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
*pADC3_rx_pointer++ = UDR1;

Регистры в IAR все volatile и компилер какбЭ намекает, что не может одновременно извлечь две volatile переменные для операции.

Хотя в реале, конечно, работает.
Go to the top of the page
 
+Quote Post
xemul
сообщение Aug 9 2012, 09:39
Сообщение #45



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(Dikoy @ Aug 9 2012, 06:33) *
В этом случае компилер ругается

Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
*pADC3_rx_pointer++ = UDR1;

Вот так
*pADC3_rx_pointer = UDR1;
pADC3_rx_pointer++;
полегчает.
Цитата
Регистры в IAR все volatile и компилер какбЭ намекает, что не может одновременно извлечь две volatile переменные для операции.
Хотя в реале, конечно, работает.

Компилер намекает, что порядок выполнения присваивания и постинкремента не гарантирован.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 24th June 2025 - 23:48
Рейтинг@Mail.ru


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