_Pasha 0 6 августа, 2012 Опубликовано 6 августа, 2012 · Жалоба Вы б отложили чашку с кофейной гущей и гадали бы на Протеусе. Найти обращение к байту в интересующей структуре - дело 5 минут при помощи условных брекпоинтов. Тем более, что дефект у Вас стабильный и танцы с бубном не нада. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 6 августа, 2012 Опубликовано 6 августа, 2012 · Жалоба ...А как указать чтобы поля не менялись местами? код видоизменить так, что бы не было в нём первого поля, или последнего. структура как чёрный ящик - длина, начало буфера. тогда пофигу будет где в ней какие поля раскиданы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 6 августа, 2012 Опубликовано 6 августа, 2012 · Жалоба код видоизменить так, что бы не было в нём первого поля, или последнего. структура как чёрный ящик - длина, начало буфера. тогда пофигу будет где в ней какие поля раскиданы. А что у вас были случаи когда компилятор менял местами поля в структуре? Я таких случаев не помню. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 116 6 августа, 2012 Опубликовано 6 августа, 2012 · Жалоба Я таких случаев не помню.Да и стандарт не позволяет. Но у страха-то глаза велики... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dikoy 0 6 августа, 2012 Опубликовано 6 августа, 2012 · Жалоба Полный бред. 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 я такого не видел. код видоизменить так, что бы не было в нём первого поля, или последнего. структура как чёрный ящик - длина, начало буфера. тогда пофигу будет где в ней какие поля раскиданы. Это называется массив ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 6 августа, 2012 Опубликовано 6 августа, 2012 · Жалоба а не в протеусе, что суть кофейная гуща. Да ещё и пиратская (да да, есть такое понятие). Как говорят братья-мусульмане, Аллах, когда ночью спит, через стенку не видит :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 7 августа, 2012 Опубликовано 7 августа, 2012 · Жалоба ...компилятор менял местами.. для тех кто начал читать топик с конца, даю справку: речь шла не о компиляторах... ...Это называется массив.. в данном конкретном случае - не важно как это называется. важно как это воспринимается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hd44780 0 7 августа, 2012 Опубликовано 7 августа, 2012 (изменено) · Жалоба Возьмите реализацию очередей из CVAvr-а. Я её и на WinAVR-е "портировал" - работает. Структуры в CvAVR-е передавал, как байтовые массивы: // Отправка структуры measureData pData = (byte *)&measureData; for (Uint=0; Uint<sizeof(measureData); Uint ++) { uartBufferPutchar ( *pData ); pData ++; } // for На компе, в программе на C# принимается как часы ... Даже второй МК (мега8), которая из себя изображает USB, нормально принимает. Там правда свои глюки есть, но то уже издержки эмуляции USB... Изделие - ваттметр на Мега16, стек - 350 байт. Изменено 7 августа, 2012 пользователем hd44780 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 7 августа, 2012 Опубликовано 7 августа, 2012 · Жалоба ... 1 и 4 кпируют волатайл переменную в R16 и далее все операции идут с регистром, что экономит порядка 20 тактов. 3 - для одноразовой операции нет разницы, используется указатель или индекс. Всё равно будет с нуля браться адрес и вычисляться смещение. Не суть. 5 - ваш глюк. А что запретит прерывание по UART_RXC? Если прерывание не запрещены, то при следующем входном байте на UART будет снова вызван обработчик прерывания. вы так упорото не хотите понять, что индекс массива у вас никак не защищён от переполнения вниз. А про порчу памяти от прерывания вам уже всё сказали. так это или не так легко проверить: поставьте проверку на индекс массива if(ADC2_RxC_counter >= ADCBUFSISE){ ERROR_LED_ON; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 7 августа, 2012 Опубликовано 7 августа, 2012 · Жалоба Возьмите реализацию очередей из CVAvr-а. Я её и на WinAVR-е "портировал" - работает. Советовал уже использовать fifo гдето в первых постах. У автора топика проблема с заполнением структуры данных АЦП а не с передачей. Как по мне проглядывается ещё одна проблема - автор пытается заполнять структуру в прерываниях от ацп и одновремененно отправлять её по uart. Возможно там есть временное разделение - т.е. сначала структура заполняется, потом передаётся и гарантированно она не изменится в процессе передачи, но в целом подход неверный. Было бы правильней проверять флаг необходимости передачи, при обнаружении с запрещёнными прерываниями закинуть всю структуру данных в fifo uart, сбросить флаг необходимости передачи, разрешить прерывания. Заодно можно обнулять индекс массива данных и инкрементировать его по каждому прерыванию ацп. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dikoy 0 7 августа, 2012 Опубликовано 7 августа, 2012 · Жалоба А что запретит прерывание по UART_RXC? } UART в режиме SPI. Если байт не будет отправлен, то он не будет принят, и RxC не будет. Посмотрите тушку прерывания - последний байт принимается, но отправки (UDR1 = ADC3_temp;) нет. Это про порты АЦП речь. С передачей в комп уже всё определилось - не она виновата. Возьмите реализацию очередей из CVAvr-а. Я её и на WinAVR-е "портировал" - работает. У меня есть свой движок с очередью, пользую уже лет 5. Но в очереди есть смысл когда мы мониторим несколько портов и, главное, информация из этих портов может уйти произвольно. В данном случае маршруты следования информации строго определены, делать очередь нет смысла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dikoy 0 8 августа, 2012 Опубликовано 8 августа, 2012 · Жалоба Переписал прерывание через указатель, и всё заработало: 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: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 116 8 августа, 2012 Опубликовано 8 августа, 2012 · Жалоба Прерывание долбит непрерывно и не останавливается. Уже поздно и мозг не варит, по тому не могу понять почему Если pADC3_rx_pointer изменяется в прерывании, а анлизируется в основном цикле - она должна быть объявлена как volatile-указатель: unsigned char * volatile pADC3_rx_pointer = &(Buf_ADC3[0]); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dikoy 0 9 августа, 2012 Опубликовано 9 августа, 2012 · Жалоба В этом случае компилер ругается Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement *pADC3_rx_pointer++ = UDR1; Регистры в IAR все volatile и компилер какбЭ намекает, что не может одновременно извлечь две volatile переменные для операции. Хотя в реале, конечно, работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xemul 0 9 августа, 2012 Опубликовано 9 августа, 2012 · Жалоба В этом случае компилер ругается 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 переменные для операции. Хотя в реале, конечно, работает. Компилер намекает, что порядок выполнения присваивания и постинкремента не гарантирован. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться